sourcecode 1.30.17__tar.gz → 1.30.18__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.18/.continue-here.md +150 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/PKG-INFO +3 -3
- {sourcecode-1.30.17 → sourcecode-1.30.18}/README.md +2 -2
- {sourcecode-1.30.17 → sourcecode-1.30.18}/pyproject.toml +1 -1
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/contract_pipeline.py +2 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/prepare_context.py +98 -29
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/repository_ir.py +2 -0
- sourcecode-1.30.17/.continue-here.md +0 -231
- {sourcecode-1.30.17 → sourcecode-1.30.18}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/.gitignore +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/.ruff.toml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/CONTRIBUTING.md +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/LICENSE +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/SECURITY.md +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/docs/privacy.md +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/docs/schema.md +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/raw +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/run_cli.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/cli.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/flow_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/__init__.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/conftest.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_block5_quality.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_classifier.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_cli.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detector_python.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_encoding_regression.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_packaging.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_pipeline_integrity.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_real_projects.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_redactor.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_repository_ir.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_scanner.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_schema.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_summarizer.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_telemetry.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_v1_10_regressions.py +0 -0
- {sourcecode-1.30.17 → sourcecode-1.30.18}/tests/test_workspace_analyzer.py +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Continue Here — atlas-cli sesión 15
|
|
2
|
+
|
|
3
|
+
**Paused:** 2026-05-18 (sesión 15)
|
|
4
|
+
**Repo:** `/Users/user/Downloads/atlas-cli`
|
|
5
|
+
**Branch:** master
|
|
6
|
+
**Working tree:** 3 ficheros modificados, SIN commit
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Trabajo de esta sesión
|
|
11
|
+
|
|
12
|
+
### Ya commiteado (66db10b)
|
|
13
|
+
|
|
14
|
+
`fix(cli): three flag-routing bugs in compact/repo-ir paths`
|
|
15
|
+
|
|
16
|
+
| Bug | Fichero | Fix |
|
|
17
|
+
|---|---|---|
|
|
18
|
+
| `--changed-only` = `--compact` (byte idéntico) | `cli.py` | Filtrar `sm.file_paths`, `entry_points`, `code_notes` antes de `compact_view`; `_allowed_changed_files` se computaba pero nunca se aplicaba porque `compact` forzaba `mode=raw` |
|
|
19
|
+
| `--compact --format yaml` ignorado | `cli.py` | Rama compact hardcodeaba `json.dumps`; añadir bloque `if format == "yaml"` igual al de contract_view |
|
|
20
|
+
| `sourcecode repo-ir .` → "No such command '.'" | `cli.py` | `"repo-ir"` ausente de `_SUBCOMMANDS`; preprocessor consumía token como PATH antes de que Click pudiera dispatchar |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### Pendiente de commit (3 ficheros modificados)
|
|
25
|
+
|
|
26
|
+
**Para commitear (primera acción al retomar):**
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd /Users/user/Downloads/atlas-cli
|
|
30
|
+
git add src/sourcecode/contract_pipeline.py \
|
|
31
|
+
src/sourcecode/repository_ir.py \
|
|
32
|
+
src/sourcecode/prepare_context.py
|
|
33
|
+
|
|
34
|
+
git commit -m "fix(encoding): utf-8 en subprocess + symptom boost por commit messages
|
|
35
|
+
|
|
36
|
+
- repository_ir.py _get_git_old_content: añadir encoding='utf-8', errors='replace'
|
|
37
|
+
al subprocess.run de git show — causa raíz del UnicodeDecodeError cp1252 en Windows
|
|
38
|
+
- contract_pipeline.py grep -rl: mismo fix (fallback Python en Windows, defensivo)
|
|
39
|
+
- prepare_context.py: symptom boost refactor en 6 passes
|
|
40
|
+
- Nuevo: _recent_commits_for_symptom extraído en bloque 5b (sin coste extra)
|
|
41
|
+
- Nuevo: commit message index (file → n commits con keyword en mensaje)
|
|
42
|
+
- Nuevo: inyección desde commit index para ficheros no en candidate pool
|
|
43
|
+
- Fix: content scan +0.05/hit, cap +0.50 (era +0.02, cap +0.30)
|
|
44
|
+
- Fix: code notes matching → back-propagate score al fichero (+0.20/note)
|
|
45
|
+
- Fix: path-kw boost aplicado a candidatos pre-existentes (no solo inyectados)
|
|
46
|
+
- Multi-signal boost en un solo file-read pass; reason string explica cada boost"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Qué hace cada cambio pendiente
|
|
52
|
+
|
|
53
|
+
### `repository_ir.py` + `contract_pipeline.py` — encoding fix
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
# Antes (crash en Windows cp1252):
|
|
57
|
+
result = subprocess.run([...], text=True, timeout=5)
|
|
58
|
+
|
|
59
|
+
# Después:
|
|
60
|
+
result = subprocess.run([...], text=True, encoding="utf-8", errors="replace", timeout=5)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Causa raíz del bug reportado: `sourcecode repo-ir . --since HEAD~3` en Windows 11 Python 3.10
|
|
64
|
+
crasheaba con `UnicodeDecodeError: 'charmap' codec can't decode byte 0x81` porque
|
|
65
|
+
`subprocess` hereda `cp1252` como encoding por defecto en Windows.
|
|
66
|
+
|
|
67
|
+
### `prepare_context.py` — symptom boost overhaul
|
|
68
|
+
|
|
69
|
+
**Problema original:** `--symptom "sesiones"` = output idéntico al baseline porque:
|
|
70
|
+
- Ningún path Java contiene "sesiones" (clases no se nombran en español)
|
|
71
|
+
- Content scan era demasiado débil (+0.02/hit → max +0.20 para 10 hits)
|
|
72
|
+
- Git commit messages no se escaneaban
|
|
73
|
+
|
|
74
|
+
**Nuevo pipeline (6 passes):**
|
|
75
|
+
|
|
76
|
+
| Pass | Señal | Boost | Cap |
|
|
77
|
+
|---|---|---|---|
|
|
78
|
+
| 1 | Code notes text match → `related_notes` + `_note_matched_paths` | — | — |
|
|
79
|
+
| 2 | **Commit index**: `file → n_commits` con keyword en mensaje | — | — |
|
|
80
|
+
| 3 | **Inyección desde commit index** (ficheros no en pool) | +0.15/commit desde 0.5 | 0.85 |
|
|
81
|
+
| 4 | Path injection (sin cambios lógicos) | +0.20/kw desde 0.5 | 1.0 |
|
|
82
|
+
| 5 | **Multi-signal boost** en 1 file-read: commit (+0.25/commit, cap+0.40), note (+0.20/note, cap+0.30), path-kw (+0.20/kw), content (+0.05/hit, cap+0.50) | acumulativo | 1.0 |
|
|
83
|
+
| 6 | Cross-layer synonym frontend→backend (sin cambios) | sin cambios | — |
|
|
84
|
+
|
|
85
|
+
**Before/after verificado** en BroadleafCommerce:
|
|
86
|
+
- `--symptom "pagination"`: top 10 pasa de servicios genéricos (0.67) a `PageDao.java` (0.90, role=`symptom_match`, reason="commit-msg symptom ×1 (+0.25)")
|
|
87
|
+
- `--symptom "zookeeper"`: `pom.xml` (1.00, 2 commit hits), `ZookeeperUtil.java` (1.00, path+content)
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Estado de tests
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
920 passed, 3 skipped
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Pre-existing failures (no tocar):
|
|
98
|
+
- `tests/test_block2_coverage.py` — bug `DocRecord` en `doc_analyzer.py`
|
|
99
|
+
- `tests/test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions`
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Pendientes (próxima sesión)
|
|
104
|
+
|
|
105
|
+
### Heredados de sesión 14 (aún vigentes)
|
|
106
|
+
|
|
107
|
+
1. **Spring bean wiring graph** — `_build_relations` emite `injects` edges para `@Autowired`. Falta: trazar `@Configuration → @Bean → @Autowired` completo, exponer como `wiring_graph`.
|
|
108
|
+
|
|
109
|
+
2. **Smoke test en repo spring-boot real:**
|
|
110
|
+
```bash
|
|
111
|
+
cd ~/Documents/workspace/spring-boot-realworld-example-app
|
|
112
|
+
sourcecode repo-ir . --since HEAD~1 2>/dev/null | python3 -c "
|
|
113
|
+
import json, sys; d=json.load(sys.stdin)
|
|
114
|
+
print('nodes:', len(d['graph']['nodes']))
|
|
115
|
+
print('route_surface:', d.get('route_surface', []))
|
|
116
|
+
print('reverse_graph keys:', len(d.get('reverse_graph', {})))
|
|
117
|
+
"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
3. **Transaction boundary tracking** — `@Transactional` detectado. Falta: emitir `transactional_boundary` edges.
|
|
121
|
+
|
|
122
|
+
4. **`_diff_routes` para `@RequestMapping` en clase** — class-level mapping change debería propagarse a todos los endpoints del controller.
|
|
123
|
+
|
|
124
|
+
### Nuevos de sesión 15
|
|
125
|
+
|
|
126
|
+
5. **Tests para el symptom fix** — validar que `--symptom "sesiones"` con commits mock que contengan "sesiones" en mensaje produce ranking diferente al baseline. Cobertura en `tests/test_prepare_context_symptom.py` o similar.
|
|
127
|
+
|
|
128
|
+
6. **`_FRONTEND_SYMPTOM_MAP`** — añadir "sesiones"/"session" como frontend keyword con backend terms `["httpsession", "sessionmanager", "sessionservice", "sessionrepository"]`.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Para retomar
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
cd /Users/user/Downloads/atlas-cli
|
|
136
|
+
git log --oneline -3 # debe mostrar 66db10b como más reciente
|
|
137
|
+
git status # 3 ficheros M: contract_pipeline, prepare_context, repository_ir
|
|
138
|
+
|
|
139
|
+
# Primera acción: commitear (comando arriba)
|
|
140
|
+
|
|
141
|
+
python3 -m pytest tests/ \
|
|
142
|
+
--ignore=tests/test_block2_coverage.py \
|
|
143
|
+
--ignore=tests/test_dependency_analyzer_node_python.py \
|
|
144
|
+
-q
|
|
145
|
+
# Expected: 920 passed, 3 skipped
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
*Pausado 2026-05-18 sesión 15 — 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.18
|
|
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.18
|
|
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.18
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
---
|
|
@@ -561,17 +561,23 @@ _ARTIFACT_CHANGE_EFFECT: dict[str, str] = {
|
|
|
561
561
|
# Maps frontend symptom keywords → backend terms likely to contain the root cause.
|
|
562
562
|
# Used to boost service/interceptor files when the symptom is UI-only.
|
|
563
563
|
_FRONTEND_SYMPTOM_MAP: dict[str, list[str]] = {
|
|
564
|
-
"spinner":
|
|
565
|
-
"loading":
|
|
566
|
-
"login":
|
|
567
|
-
"logout":
|
|
568
|
-
"dropdown":
|
|
569
|
-
"modal":
|
|
570
|
-
"popup":
|
|
571
|
-
"table":
|
|
572
|
-
"grid":
|
|
573
|
-
"button":
|
|
574
|
-
"form":
|
|
564
|
+
"spinner": ["loading", "setloading", "finalize", "httpinterceptor", "interceptor", "service"],
|
|
565
|
+
"loading": ["loading", "setloading", "finalize", "httpinterceptor", "interceptor", "service"],
|
|
566
|
+
"login": ["authcontroller", "securityconfig", "filterconfig", "jwtfilter", "auth", "authentication"],
|
|
567
|
+
"logout": ["authcontroller", "securityconfig", "jwtfilter", "auth", "session"],
|
|
568
|
+
"dropdown": ["getmapping", "findall", "obtenertodos", "listall", "findby"],
|
|
569
|
+
"modal": ["controller", "getmapping", "findby", "search"],
|
|
570
|
+
"popup": ["controller", "getmapping", "findby", "search"],
|
|
571
|
+
"table": ["paginated", "findby", "search", "getmapping", "listall"],
|
|
572
|
+
"grid": ["paginated", "findby", "search", "getmapping"],
|
|
573
|
+
"button": ["postmapping", "putmapping", "deletemapping", "controller", "service"],
|
|
574
|
+
"form": ["postmapping", "putmapping", "controller", "service", "dto"],
|
|
575
|
+
# session-related symptoms (Spanish + English)
|
|
576
|
+
"sesion": ["httpsession", "sessionmanager", "sessionservice", "sessionrepository", "sessionfactory", "authentication"],
|
|
577
|
+
"sesiones": ["httpsession", "sessionmanager", "sessionservice", "sessionrepository", "sessionfactory", "authentication"],
|
|
578
|
+
"session": ["httpsession", "sessionmanager", "sessionservice", "sessionrepository", "sessionfactory", "authentication"],
|
|
579
|
+
# worker/assignment domain terms (common in RRHH/HR systems)
|
|
580
|
+
"trabajador": ["trabajador", "empleado", "worker", "asignacion", "trabajadordao", "trabajadorservice"],
|
|
575
581
|
}
|
|
576
582
|
|
|
577
583
|
|
|
@@ -826,12 +832,14 @@ class TaskContextBuilder:
|
|
|
826
832
|
# ── 5b. Git signals for ranking ────────────────────────────────────
|
|
827
833
|
git_hotspots: dict[str, int] = {}
|
|
828
834
|
uncommitted_files: set[str] = set()
|
|
835
|
+
_recent_commits_for_symptom: list = []
|
|
829
836
|
try:
|
|
830
837
|
from sourcecode.git_analyzer import GitAnalyzer
|
|
831
838
|
_gc = GitAnalyzer().analyze(self.root, depth=30, days=90)
|
|
832
839
|
_bad = {"no_git_repo", "git_not_found", "git_timeout"}
|
|
833
840
|
if _gc and not (_bad & set(_gc.limitations)):
|
|
834
841
|
git_hotspots = {h.file: h.commit_count for h in _gc.change_hotspots}
|
|
842
|
+
_recent_commits_for_symptom = list(_gc.recent_commits)
|
|
835
843
|
if _gc.uncommitted_changes:
|
|
836
844
|
_uc = _gc.uncommitted_changes
|
|
837
845
|
uncommitted_files = set(_uc.staged) | set(_uc.unstaged)
|
|
@@ -1208,19 +1216,52 @@ class TaskContextBuilder:
|
|
|
1208
1216
|
if len(w) > 2
|
|
1209
1217
|
]
|
|
1210
1218
|
if symptom_keywords:
|
|
1211
|
-
#
|
|
1219
|
+
# Pass 1: surface code notes whose text contains any keyword
|
|
1220
|
+
# Also track which file paths have matching notes (for score boost below).
|
|
1221
|
+
_note_matched_paths: dict[str, int] = {} # path → count of matching notes
|
|
1212
1222
|
for _n in cn_notes_for_ranking:
|
|
1213
1223
|
_text = (getattr(_n, "text", "") or "").lower()
|
|
1214
1224
|
if any(kw in _text for kw in symptom_keywords):
|
|
1225
|
+
_np = getattr(_n, "path", "")
|
|
1215
1226
|
related_notes.append({
|
|
1216
1227
|
"kind": getattr(_n, "kind", ""),
|
|
1217
|
-
"path":
|
|
1228
|
+
"path": _np,
|
|
1218
1229
|
"line": getattr(_n, "line", None),
|
|
1219
1230
|
"text": getattr(_n, "text", ""),
|
|
1220
1231
|
})
|
|
1221
|
-
|
|
1222
|
-
|
|
1232
|
+
_note_matched_paths[_np] = _note_matched_paths.get(_np, 0) + 1
|
|
1233
|
+
|
|
1234
|
+
# Pass 2: build commit message index — files touched in commits whose
|
|
1235
|
+
# message matches a symptom keyword get a strong recency signal.
|
|
1236
|
+
# This is the primary signal for functional keywords like "sesiones"
|
|
1237
|
+
# that don't appear in file paths but do appear in commit messages.
|
|
1238
|
+
_commit_file_hits: dict[str, int] = {} # path → n matching commits
|
|
1239
|
+
for _cr in _recent_commits_for_symptom:
|
|
1240
|
+
_msg_lower = (_cr.message or "").lower()
|
|
1241
|
+
if any(kw in _msg_lower for kw in symptom_keywords):
|
|
1242
|
+
for _cf in (_cr.files_changed or []):
|
|
1243
|
+
_cf_norm = _cf.replace("\\", "/")
|
|
1244
|
+
_commit_file_hits[_cf_norm] = _commit_file_hits.get(_cf_norm, 0) + 1
|
|
1245
|
+
|
|
1246
|
+
# Pass 3: inject files from commit index not yet in candidate pool
|
|
1223
1247
|
_existing_paths = {rf.path for rf in relevant_files}
|
|
1248
|
+
for _cp, _nhits in _commit_file_hits.items():
|
|
1249
|
+
if _cp in _existing_paths:
|
|
1250
|
+
continue
|
|
1251
|
+
if Path(_cp).suffix.lower() not in _ALL_EXTENSIONS:
|
|
1252
|
+
continue
|
|
1253
|
+
_ci_score = round(min(0.5 + 0.15 * _nhits, 0.85), 2)
|
|
1254
|
+
relevant_files.append(RelevantFile(
|
|
1255
|
+
path=_cp,
|
|
1256
|
+
role="symptom_match",
|
|
1257
|
+
score=_ci_score,
|
|
1258
|
+
reason=f"commit message matches symptom ({_nhits} commit{'s' if _nhits > 1 else ''})",
|
|
1259
|
+
why=f"symptom commit-index: {', '.join(symptom_keywords)}",
|
|
1260
|
+
))
|
|
1261
|
+
_existing_paths.add(_cp)
|
|
1262
|
+
|
|
1263
|
+
# Pass 4: inject files whose path matches symptom keywords
|
|
1264
|
+
# but weren't in the candidate pool (no structural/git signals).
|
|
1224
1265
|
for _p in all_paths:
|
|
1225
1266
|
if _p in _existing_paths:
|
|
1226
1267
|
continue
|
|
@@ -1242,17 +1283,38 @@ class TaskContextBuilder:
|
|
|
1242
1283
|
))
|
|
1243
1284
|
_existing_paths.add(_p)
|
|
1244
1285
|
|
|
1245
|
-
#
|
|
1246
|
-
|
|
1247
|
-
path_lower = rf.path.lower()
|
|
1248
|
-
return rf.score + 0.2 * sum(1.0 for kw in symptom_keywords if kw in path_lower)
|
|
1249
|
-
relevant_files = sorted(relevant_files, key=lambda rf: -_symptom_score(rf))
|
|
1250
|
-
|
|
1251
|
-
# Content scan boost: read file body for symptom keywords
|
|
1286
|
+
# Pass 5: multi-signal boost — apply commit, note, content, and path
|
|
1287
|
+
# signals in one pass to avoid redundant file reads.
|
|
1252
1288
|
_src_exts = frozenset({".java", ".py", ".ts", ".js", ".kt", ".go"})
|
|
1253
|
-
|
|
1289
|
+
_boosted: list[RelevantFile] = []
|
|
1254
1290
|
for _rf in relevant_files:
|
|
1255
1291
|
_extra = 0.0
|
|
1292
|
+
_reasons: list[str] = []
|
|
1293
|
+
_p_lower = _rf.path.lower()
|
|
1294
|
+
|
|
1295
|
+
# Commit message boost: +0.25/commit, cap +0.40
|
|
1296
|
+
_c_hits = _commit_file_hits.get(_rf.path, 0)
|
|
1297
|
+
if _c_hits:
|
|
1298
|
+
_cb = min(0.40, _c_hits * 0.25)
|
|
1299
|
+
_extra += _cb
|
|
1300
|
+
_reasons.append(f"commit-msg symptom ×{_c_hits} (+{_cb:.2f})")
|
|
1301
|
+
|
|
1302
|
+
# Code note boost: +0.20/note, cap +0.30
|
|
1303
|
+
_n_hits = _note_matched_paths.get(_rf.path, 0)
|
|
1304
|
+
if _n_hits:
|
|
1305
|
+
_nb = min(0.30, _n_hits * 0.20)
|
|
1306
|
+
_extra += _nb
|
|
1307
|
+
_reasons.append(f"note-match symptom ×{_n_hits} (+{_nb:.2f})")
|
|
1308
|
+
|
|
1309
|
+
# Path keyword boost: +0.20/keyword already in score for injected
|
|
1310
|
+
# files; re-apply for pre-existing candidates whose path matches.
|
|
1311
|
+
_path_kws = [kw for kw in symptom_keywords if kw in _p_lower]
|
|
1312
|
+
if _path_kws and _rf.role != "symptom_match":
|
|
1313
|
+
_pb = 0.20 * len(_path_kws)
|
|
1314
|
+
_extra += _pb
|
|
1315
|
+
_reasons.append(f"path-kw symptom ({', '.join(_path_kws)}) (+{_pb:.2f})")
|
|
1316
|
+
|
|
1317
|
+
# Content scan boost: +0.05/hit, cap +0.50 (was +0.02, cap +0.30)
|
|
1256
1318
|
if Path(_rf.path).suffix.lower() in _src_exts:
|
|
1257
1319
|
try:
|
|
1258
1320
|
_lines = (self.root / _rf.path).read_text(
|
|
@@ -1260,26 +1322,33 @@ class TaskContextBuilder:
|
|
|
1260
1322
|
).splitlines()[:300]
|
|
1261
1323
|
_body = "\n".join(_lines).lower()
|
|
1262
1324
|
_hits = sum(_body.count(kw) for kw in symptom_keywords)
|
|
1263
|
-
|
|
1325
|
+
_content_b = min(0.50, _hits * 0.05)
|
|
1326
|
+
if _content_b > 0:
|
|
1327
|
+
_extra += _content_b
|
|
1328
|
+
_reasons.append(f"content-match symptom ×{_hits} (+{_content_b:.2f})")
|
|
1264
1329
|
except OSError:
|
|
1265
1330
|
pass
|
|
1266
|
-
|
|
1331
|
+
|
|
1332
|
+
_new_reason = _rf.reason
|
|
1333
|
+
if _reasons:
|
|
1334
|
+
_new_reason = _rf.reason + ", " + ", ".join(_reasons)
|
|
1335
|
+
_boosted.append(RelevantFile(
|
|
1267
1336
|
path=_rf.path,
|
|
1268
1337
|
role=_rf.role,
|
|
1269
1338
|
score=round(min(_rf.score + _extra, 1.0), 2),
|
|
1270
|
-
reason=
|
|
1339
|
+
reason=_new_reason,
|
|
1271
1340
|
why=_rf.why,
|
|
1272
1341
|
))
|
|
1273
|
-
relevant_files = sorted(
|
|
1342
|
+
relevant_files = sorted(_boosted, key=lambda rf: -rf.score)
|
|
1274
1343
|
|
|
1275
|
-
#
|
|
1344
|
+
# Pass 6: cross-layer synonym boost — frontend keywords → backend equivalents
|
|
1276
1345
|
_synonym_note: Optional[str] = None
|
|
1277
1346
|
_frontend_kws = [kw for kw in symptom_keywords if kw in _FRONTEND_SYMPTOM_MAP]
|
|
1278
1347
|
if _frontend_kws:
|
|
1279
1348
|
_backend_terms: list[str] = []
|
|
1280
1349
|
for _fkw in _frontend_kws:
|
|
1281
1350
|
_backend_terms.extend(_FRONTEND_SYMPTOM_MAP[_fkw])
|
|
1282
|
-
_backend_terms_set = list(dict.fromkeys(_backend_terms))
|
|
1351
|
+
_backend_terms_set = list(dict.fromkeys(_backend_terms))
|
|
1283
1352
|
_synonym_boosted: list[RelevantFile] = []
|
|
1284
1353
|
for _rf in relevant_files:
|
|
1285
1354
|
_extra_syn = 0.0
|
|
@@ -1,231 +0,0 @@
|
|
|
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*
|
{sourcecode-1.30.17 → sourcecode-1.30.18}/.agents/skills/source-command-gsd-join-discord/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.30.17 → sourcecode-1.30.18}/.agents/skills/source-command-gsd-review-backlog/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.30.17 → sourcecode-1.30.18}/.agents/skills/source-command-gsd-workstreams/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|