sourcecode 1.29.0__tar.gz → 1.30.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sourcecode-1.30.1/.continue-here.md +129 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/PKG-INFO +3 -3
- {sourcecode-1.29.0 → sourcecode-1.30.1}/README.md +2 -2
- {sourcecode-1.29.0 → sourcecode-1.30.1}/pyproject.toml +1 -1
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/prepare_context.py +168 -11
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_v1_10_regressions.py +5 -5
- sourcecode-1.29.0/.continue-here.md +0 -108
- {sourcecode-1.29.0 → sourcecode-1.30.1}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/.gitignore +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/.ruff.toml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/CONTRIBUTING.md +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/LICENSE +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/SECURITY.md +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/docs/privacy.md +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/docs/schema.md +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/raw +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/run_cli.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/cli.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/__init__.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/conftest.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_block5_quality.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_classifier.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_cli.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detector_python.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_encoding_regression.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_packaging.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_pipeline_integrity.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_real_projects.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_redactor.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_scanner.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_schema.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_summarizer.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_telemetry.py +0 -0
- {sourcecode-1.29.0 → sourcecode-1.30.1}/tests/test_workspace_analyzer.py +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Continue Here — atlas-cli session 6
|
|
2
|
+
|
|
3
|
+
**Paused:** 2026-05-16 (sesión 6)
|
|
4
|
+
**Repo:** `/Users/user/Downloads/atlas-cli`
|
|
5
|
+
**Branch:** master
|
|
6
|
+
**Último commit:** `772a01e` (fix false positives review-pr)
|
|
7
|
+
**Working tree:** DIRTY — `src/sourcecode/prepare_context.py` modificado (28 ins / 8 del), sin commit
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Lo que se hizo esta sesión
|
|
12
|
+
|
|
13
|
+
### Fix 1 — `review-pr` false positive cuando `since=None`
|
|
14
|
+
|
|
15
|
+
Commit `772a01e` (ya en repo). Root cause: `_get_git_changed_files(since=None)` usaba `HEAD~1` como default → devolvía archivos del último commit committeado → `review-pr` los trataba como "PR diff". Fix: nuevo método `_get_uncommitted_changed_files()` llamado desde gate review-pr cuando `since=None`. Tests actualizados en `test_v1_10_regressions.py` para mockear el nuevo método.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
### Fix 2 — BFS over-expansion en `_build_delta_impact` (SIN COMMIT — PENDIENTE)
|
|
20
|
+
|
|
21
|
+
**Problema confirmado en `~/Documents/workspace/spring-boot-realworld-example-app`:**
|
|
22
|
+
Con 2 archivos cambiados (`User.java`, `ArticleFavorite.java`), `review-pr` devolvía 24 `relevant_files` incluyendo todos los controllers REST, todos los GraphQL resolvers, y 2 test files.
|
|
23
|
+
|
|
24
|
+
**3 bugs identificados y corregidos:**
|
|
25
|
+
|
|
26
|
+
| Bug | Línea orig | Descripción | Fix |
|
|
27
|
+
|-----|-----------|-------------|-----|
|
|
28
|
+
| Tests en `_bfs_collected` | ~2081 | `_bfs_collected.append()` fuera de `if not _is_test:` → TestHelper.java, ArticleApiTest.java incluidos | Movido dentro del bloque |
|
|
29
|
+
| Sin per-hop cap | ~2091 | `_max_results` (8) limitaba solo el frontier, no `_bfs_collected`. Hop-1 llenaba los 20 slots, expulsando hop-2/3 | Nuevo `_hop_bfs_staged`: acumula por hop, ordena por score desc, extiende con `[:_max_results]` |
|
|
30
|
+
| Sin truncation guard | — | Sin señal cuando expansión excesiva | Flag `_expansion_truncated` + mensaje `truncated_dependency_graph` en `analysis_gaps` cuando `len(relevant) > 40` |
|
|
31
|
+
|
|
32
|
+
**Resultado smoke test:**
|
|
33
|
+
|
|
34
|
+
| Métrica | Antes | Después |
|
|
35
|
+
|---------|-------|---------|
|
|
36
|
+
| `relevant_files` total | 24 | 14 |
|
|
37
|
+
| Tests incluidos | 2 | **0** |
|
|
38
|
+
| GraphQL resolvers | 8 | **0** |
|
|
39
|
+
| REST controllers | 7 | 5 (top-5 score) |
|
|
40
|
+
| Security hop-1 legítimos | 3 | 3 |
|
|
41
|
+
| JwtTokenFilter (hop-2) | 1 | 1 |
|
|
42
|
+
| WebSecurityConfig (hop-3) | 0 | 1 |
|
|
43
|
+
|
|
44
|
+
**Tests:** 771 passed, 3 skipped
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Estado de tests al pausar
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
771 passed, 3 skipped
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Pre-existing failures (excluidos del run):
|
|
55
|
+
- `test_block2_coverage.py::test_java_marked_unsupported` — DocRecord bug en doc_analyzer.py
|
|
56
|
+
- `test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions` — typer version mismatch
|
|
57
|
+
- `test_packaging.py::test_console_script_reports_version` — installed v1.29 vs source v1.30 (se resolverá al reinstalar post-commit)
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Decisiones técnicas de esta sesión
|
|
62
|
+
|
|
63
|
+
- **`_get_uncommitted_changed_files()`**: Método extraído para que sea mockeado en tests. Delta sigue usando HEAD~1 — correcto, no afectado.
|
|
64
|
+
- **`_hop_bfs_staged` per-hop cap**: Elegido sobre threshold de score porque 0.30 seguía incluyendo GraphQL (score 0.32). Cap determinístico.
|
|
65
|
+
- **`_bfs_cap = sum(budget[0])`**: 8+6+4=18, derivado de `_BFS_HOP_BUDGET`, no hardcodeado.
|
|
66
|
+
- **WebSecurityConfig sigue apareciendo (hop-3)**: Legítimo. Cadena real: JwtService→JwtTokenFilter→WebSecurityConfig. Para eliminar: reducir `_BFS_HOP_BUDGET` a 2 hops.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Pendiente / próximos pasos
|
|
71
|
+
|
|
72
|
+
1. **COMMIT fix BFS** — diff listo, tests verdes:
|
|
73
|
+
```bash
|
|
74
|
+
cd /Users/user/Downloads/atlas-cli
|
|
75
|
+
git add src/sourcecode/prepare_context.py
|
|
76
|
+
git commit -m "fix: BFS over-expansion en review-pr — per-hop cap, tests excluidos, truncation guard"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
2. **Opcional — reducir a 2 hops** si se quiere eliminar WebSecurityConfig (hop-3):
|
|
80
|
+
Cambiar `_BFS_HOP_BUDGET` en `prepare_context.py` de 3 a 2 elementos.
|
|
81
|
+
|
|
82
|
+
3. **Opcional — cross-module guard en BFS**: No incluir archivos cuyo módulo (`_extract_ddd_domain`) difiere del módulo de los changed files. Eliminaría AuthorizationService/JwtService (módulo "service" ≠ "user"/"favorite") de hop-1.
|
|
83
|
+
|
|
84
|
+
4. **Smoke test `delta`** con BFS fix (verificar no afectado):
|
|
85
|
+
```bash
|
|
86
|
+
cd ~/Documents/workspace/spring-boot-realworld-example-app
|
|
87
|
+
sourcecode prepare-context delta . --since HEAD~1 2>&1 | python3 -c "import json,sys; d=json.load(sys.stdin); print('relevant_files:', len(d.get('relevant_files', [])))"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
5. **Smoke tests sesiones anteriores** (saint-server) — ver handoff sesión 4/5.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Para retomar
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
cd /Users/user/Downloads/atlas-cli
|
|
98
|
+
git log --oneline -3
|
|
99
|
+
# debe mostrar:
|
|
100
|
+
# 772a01e (fix) corrigiendo bug que identificaba falsos positivos en review-pr
|
|
101
|
+
# 5c06ef3 (feature) implementando mejoras significativas en prepare-context review-pr
|
|
102
|
+
# e5a1a05 corrigiendo bug en delta --since en windows
|
|
103
|
+
|
|
104
|
+
git diff --stat HEAD
|
|
105
|
+
# debe mostrar: prepare_context.py | 36 +++--- (BFS fix pendiente de commit)
|
|
106
|
+
|
|
107
|
+
# Tests
|
|
108
|
+
python3 -m pytest tests/ \
|
|
109
|
+
--ignore=tests/test_block2_coverage.py \
|
|
110
|
+
--ignore=tests/test_packaging.py \
|
|
111
|
+
--deselect=tests/test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions \
|
|
112
|
+
-q
|
|
113
|
+
# Expected: 771 passed, 3 skipped
|
|
114
|
+
|
|
115
|
+
# Smoke test review-pr
|
|
116
|
+
cd ~/Documents/workspace/spring-boot-realworld-example-app
|
|
117
|
+
sourcecode prepare-context review-pr . 2>&1 | python3 -c "
|
|
118
|
+
import json, sys
|
|
119
|
+
d = json.load(sys.stdin)
|
|
120
|
+
print('relevant_files:', len(d.get('relevant_files', [])))
|
|
121
|
+
for f in d.get('relevant_files', []):
|
|
122
|
+
print(' ', f.get('score'), f.get('path').split('/')[-1])
|
|
123
|
+
"
|
|
124
|
+
# Expected: 14 files, no tests, no GraphQL
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
*Pausado 2026-05-16 sesión 6 — gsd:pause-work*
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.30.1
|
|
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
|
**Compressed AI-ready context for Java/Spring enterprise codebases.**
|
|
223
223
|
|
|
224
|
-

|
|
225
225
|

|
|
226
226
|
|
|
227
227
|
---
|
|
@@ -255,7 +255,7 @@ pipx install sourcecode
|
|
|
255
255
|
|
|
256
256
|
```bash
|
|
257
257
|
sourcecode version
|
|
258
|
-
# sourcecode 1.
|
|
258
|
+
# sourcecode 1.30.1
|
|
259
259
|
```
|
|
260
260
|
|
|
261
261
|
---
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Compressed AI-ready context for Java/Spring enterprise codebases.**
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|
|
|
8
8
|
---
|
|
@@ -36,7 +36,7 @@ pipx install sourcecode
|
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
38
|
sourcecode version
|
|
39
|
-
# sourcecode 1.
|
|
39
|
+
# sourcecode 1.30.1
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
---
|
|
@@ -681,7 +681,13 @@ class TaskContextBuilder:
|
|
|
681
681
|
error_message="review-pr requires a git repository.",
|
|
682
682
|
ci_decision="no_git_repo",
|
|
683
683
|
)
|
|
684
|
-
|
|
684
|
+
if since is None:
|
|
685
|
+
# review-pr with no --since: check only uncommitted changes.
|
|
686
|
+
# _get_git_changed_files(since=None) defaults to HEAD~1 which
|
|
687
|
+
# returns the last *committed* diff — a false positive here.
|
|
688
|
+
_pr_raw: Optional[list[str]] = self._get_uncommitted_changed_files()
|
|
689
|
+
else:
|
|
690
|
+
_pr_raw = self._get_git_changed_files(since=since)
|
|
685
691
|
if _pr_raw is None:
|
|
686
692
|
_avail_pr, _sug_pr = self._get_available_refs(since or "")
|
|
687
693
|
_pr_hints: list[str] = []
|
|
@@ -1599,6 +1605,78 @@ class TaskContextBuilder:
|
|
|
1599
1605
|
# Binaries, images, lock files — treat as noise (closed taxonomy: no unknown_*)
|
|
1600
1606
|
return {"artifact_type": "ide_noise", "risk_areas": [], "impact_level": "noise", "is_noise": True, "module": module, "confidence": "low"}
|
|
1601
1607
|
|
|
1608
|
+
def _classify_diff_severity(self, path: str, since: Optional[str]) -> str:
|
|
1609
|
+
"""Classify the semantic severity of a file's diff to gate BFS expansion.
|
|
1610
|
+
|
|
1611
|
+
Returns: 'trivial' | 'field_change' | 'api_change' | 'security_change' | 'unknown'
|
|
1612
|
+
|
|
1613
|
+
- trivial: only comments/whitespace changed — no BFS expansion seeded
|
|
1614
|
+
- field_change: field/attribute declarations changed — hop-1 only, no hop-2+ frontier
|
|
1615
|
+
- api_change: method signatures or class structure changed — full BFS
|
|
1616
|
+
- security_change: auth/security keywords in changed lines — full BFS + security chain
|
|
1617
|
+
- unknown: diff unreadable — treated as api_change (safe default)
|
|
1618
|
+
"""
|
|
1619
|
+
import subprocess as _subprocess
|
|
1620
|
+
import re as _re
|
|
1621
|
+
|
|
1622
|
+
try:
|
|
1623
|
+
if since:
|
|
1624
|
+
cmd = ["git", "diff", since, "HEAD", "--", path]
|
|
1625
|
+
else:
|
|
1626
|
+
cmd = ["git", "diff", "HEAD", "--", path]
|
|
1627
|
+
result = _subprocess.run(
|
|
1628
|
+
cmd, capture_output=True, text=True, timeout=5,
|
|
1629
|
+
cwd=str(self.root), encoding="utf-8", errors="ignore",
|
|
1630
|
+
)
|
|
1631
|
+
diff_text = result.stdout
|
|
1632
|
+
except Exception:
|
|
1633
|
+
return "unknown"
|
|
1634
|
+
|
|
1635
|
+
if not diff_text.strip():
|
|
1636
|
+
return "unknown"
|
|
1637
|
+
|
|
1638
|
+
changed_lines = [
|
|
1639
|
+
line[1:] for line in diff_text.splitlines()
|
|
1640
|
+
if line.startswith(("+", "-")) and not line.startswith(("+++", "---"))
|
|
1641
|
+
]
|
|
1642
|
+
if not changed_lines:
|
|
1643
|
+
return "trivial"
|
|
1644
|
+
|
|
1645
|
+
suffix = Path(path).suffix.lower()
|
|
1646
|
+
if suffix in (".java", ".kt"):
|
|
1647
|
+
_TRIVIAL = _re.compile(r'^\s*(?://|/\*|\*)')
|
|
1648
|
+
_FIELD = _re.compile(r'^\s*(?:private|protected|public|final|static)\s+\w[\w<>, ]*\s+\w+\s*[;=]')
|
|
1649
|
+
_API = _re.compile(r'^\s*(?:public|protected)\s+\S.*\(')
|
|
1650
|
+
# Exclude 'password', 'role', 'permission' — these are common field names
|
|
1651
|
+
# in domain models and don't indicate auth logic changes. Keep mechanism
|
|
1652
|
+
# keywords: jwt, auth (as class prefix), token, credential, encrypt, decrypt, oauth.
|
|
1653
|
+
_SECURITY = _re.compile(r'\b(?:jwt|auth|token|credential|encrypt|decrypt|oauth|saml|ldap|principal|Security)\b')
|
|
1654
|
+
_STRUCT = _re.compile(r'^\s*(?:class|interface|enum|record|import|package)\s')
|
|
1655
|
+
elif suffix == ".py":
|
|
1656
|
+
_TRIVIAL = _re.compile(r'^\s*#')
|
|
1657
|
+
_FIELD = _re.compile(r'^\s*(?:self\.\w+\s*=|\w+:\s*\w)')
|
|
1658
|
+
_API = _re.compile(r'^\s*def\s+\w')
|
|
1659
|
+
_SECURITY = _re.compile(r'\b(?:jwt|auth|token|credential|encrypt|decrypt|oauth|saml|ldap|principal|security)\b', _re.IGNORECASE)
|
|
1660
|
+
_STRUCT = _re.compile(r'^\s*(?:class|import|from)\s')
|
|
1661
|
+
elif suffix in (".ts", ".tsx", ".js", ".jsx", ".mjs"):
|
|
1662
|
+
_TRIVIAL = _re.compile(r'^\s*(?://|/\*|\*)')
|
|
1663
|
+
_FIELD = _re.compile(r'^\s*(?:private|readonly|public)?\s*\w+[?!]?\s*[=:]')
|
|
1664
|
+
_API = _re.compile(r'^\s*(?:(?:public|private|protected|async|export)\s+)*(?:function\s+\w|\w+\s*\()')
|
|
1665
|
+
_SECURITY = _re.compile(r'\b(?:jwt|auth|token|credential|encrypt|decrypt|oauth|saml|ldap|principal|security)\b', _re.IGNORECASE)
|
|
1666
|
+
_STRUCT = _re.compile(r'^\s*(?:class|interface|import|export\s+(?:class|interface|type))\s')
|
|
1667
|
+
else:
|
|
1668
|
+
return "unknown"
|
|
1669
|
+
|
|
1670
|
+
if any(_SECURITY.search(line) for line in changed_lines):
|
|
1671
|
+
return "security_change"
|
|
1672
|
+
if any(_API.match(line) or _STRUCT.match(line) for line in changed_lines):
|
|
1673
|
+
return "api_change"
|
|
1674
|
+
if any(_FIELD.match(line) for line in changed_lines):
|
|
1675
|
+
return "field_change"
|
|
1676
|
+
if all(_TRIVIAL.match(line) or not line.strip() for line in changed_lines):
|
|
1677
|
+
return "trivial"
|
|
1678
|
+
return "field_change" # safe default: treat unknown non-trivial as field-level
|
|
1679
|
+
|
|
1602
1680
|
def _scan_import_dependents(
|
|
1603
1681
|
self,
|
|
1604
1682
|
changed_paths: list[str],
|
|
@@ -1882,6 +1960,16 @@ class TaskContextBuilder:
|
|
|
1882
1960
|
f: self._classify_changed_file(f) for f in changed_files
|
|
1883
1961
|
}
|
|
1884
1962
|
|
|
1963
|
+
# ── Step 1b: classify diff severity to gate BFS expansion ─────────────
|
|
1964
|
+
# trivial → no BFS seeding (comments/whitespace only)
|
|
1965
|
+
# field_change → hop-1 BFS only, deps excluded from hop-2+ frontier
|
|
1966
|
+
# api_change → full BFS (method signature or class structure changed)
|
|
1967
|
+
# security_change → full BFS + security chain allowed cross-module
|
|
1968
|
+
# unknown → treated as api_change (safe default)
|
|
1969
|
+
diff_severities: dict[str, str] = {
|
|
1970
|
+
f: self._classify_diff_severity(f, since) for f in changed_files
|
|
1971
|
+
}
|
|
1972
|
+
|
|
1885
1973
|
# ── Step 2: build relevant_files from the changed set ─────────────────
|
|
1886
1974
|
relevant: list[RelevantFile] = []
|
|
1887
1975
|
why: dict[str, str] = {}
|
|
@@ -1998,9 +2086,12 @@ class TaskContextBuilder:
|
|
|
1998
2086
|
]
|
|
1999
2087
|
|
|
2000
2088
|
_bfs_seen: set[str] = {rf.path for rf in relevant}
|
|
2089
|
+
# trivial changes (comments/whitespace only) don't seed BFS — nothing structural
|
|
2090
|
+
# to propagate, so excluding them prevents false expansion on cosmetic commits
|
|
2001
2091
|
_bfs_frontier: list[str] = [
|
|
2002
2092
|
f for f in changed_files
|
|
2003
2093
|
if Path(f).suffix.lower() in _BFS_SCANNABLE
|
|
2094
|
+
and diff_severities.get(f, "unknown") != "trivial"
|
|
2004
2095
|
]
|
|
2005
2096
|
|
|
2006
2097
|
# (max results added from this hop, max_candidates scanned per seed)
|
|
@@ -2029,6 +2120,8 @@ class TaskContextBuilder:
|
|
|
2029
2120
|
|
|
2030
2121
|
# collect (score, path) pairs for this hop to build the next frontier
|
|
2031
2122
|
_hop_scored: list[tuple[float, str]] = []
|
|
2123
|
+
# per-hop staging list — capped at _max_results before merging into _bfs_collected
|
|
2124
|
+
_hop_bfs_staged: list[tuple[int, float, str, RelevantFile]] = []
|
|
2032
2125
|
|
|
2033
2126
|
for _seed_path, _dep_paths in _hop_dep_map.items():
|
|
2034
2127
|
_seed_atype = (
|
|
@@ -2036,6 +2129,9 @@ class TaskContextBuilder:
|
|
|
2036
2129
|
if _seed_path in classifications
|
|
2037
2130
|
else self._classify_changed_file(_seed_path)["artifact_type"]
|
|
2038
2131
|
)
|
|
2132
|
+
# diff severity for original changed files only (hop-1 seeds);
|
|
2133
|
+
# hop-2+ seeds are dep files not in diff_severities → "unknown"
|
|
2134
|
+
_seed_severity = diff_severities.get(_seed_path, "unknown")
|
|
2039
2135
|
for _dep_path in _dep_paths:
|
|
2040
2136
|
if _dep_path in _bfs_seen:
|
|
2041
2137
|
continue
|
|
@@ -2046,9 +2142,29 @@ class TaskContextBuilder:
|
|
|
2046
2142
|
continue
|
|
2047
2143
|
|
|
2048
2144
|
_dep_atype = _dep_cls["artifact_type"]
|
|
2145
|
+
_dep_module = _dep_cls["module"]
|
|
2146
|
+
|
|
2147
|
+
# Cross-module gating: if dep lives in a different domain module,
|
|
2148
|
+
# only allow it if:
|
|
2149
|
+
# hop-1 AND dep_atype is explicitly in seed's _EXPANSION_TARGETS
|
|
2150
|
+
# For hop-2+, cross-module deps are always excluded — transitives
|
|
2151
|
+
# must stay within the changed modules to avoid system-wide explosion.
|
|
2152
|
+
_is_cross_module = bool(_dep_module) and _dep_module not in affected_modules_set
|
|
2153
|
+
if _is_cross_module:
|
|
2154
|
+
_seed_expansion = _EXPANSION_TARGETS.get(_seed_atype, frozenset())
|
|
2155
|
+
# security_change seeds are allowed to cross into the security chain
|
|
2156
|
+
# even when their base expansion targets don't include those types
|
|
2157
|
+
if _seed_severity == "security_change":
|
|
2158
|
+
_seed_expansion = _seed_expansion | frozenset({"security", "spring_config", "config"})
|
|
2159
|
+
if _hop_num >= 2 or _dep_atype not in _seed_expansion:
|
|
2160
|
+
continue
|
|
2161
|
+
|
|
2049
2162
|
_dep_score_base = _ARTIFACT_SCORE.get(_dep_atype, 0.45)
|
|
2050
2163
|
# score decays 30% per hop so transitives rank below direct dependents
|
|
2051
|
-
|
|
2164
|
+
# cross-module deps get additional 40% penalty so same-module files
|
|
2165
|
+
# always rank higher in the per-hop cap
|
|
2166
|
+
_cross_module_factor = 0.60 if _is_cross_module else 1.0
|
|
2167
|
+
_dep_score = round(_dep_score_base * (0.70 ** _hop_num) * _cross_module_factor, 2)
|
|
2052
2168
|
_dep_role = _role_in_system(_dep_path, _dep_atype, _dep_path in ep_paths)
|
|
2053
2169
|
|
|
2054
2170
|
_why_str = (
|
|
@@ -2063,27 +2179,44 @@ class TaskContextBuilder:
|
|
|
2063
2179
|
f" ({_seed_atype}) | score: {_dep_score:.2f}"
|
|
2064
2180
|
)
|
|
2065
2181
|
why[_dep_path] = _why_str
|
|
2066
|
-
# Tests are
|
|
2067
|
-
#
|
|
2182
|
+
# Tests import production code but are not structural dependencies —
|
|
2183
|
+
# exclude from graph, frontier, and bfs_collected entirely.
|
|
2068
2184
|
_is_test = _dep_atype == "test"
|
|
2069
2185
|
if not _is_test:
|
|
2070
2186
|
graph_edges.append({
|
|
2071
2187
|
"from": _seed_path, "to": _dep_path,
|
|
2072
2188
|
"edge_type": "import_dependency", "hop": _hop_num,
|
|
2073
2189
|
})
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2190
|
+
# field_change seeds don't propagate to hop-2+ frontier:
|
|
2191
|
+
# a field-level change (getter, attribute) is collected at hop-1
|
|
2192
|
+
# but its callers are not recursively expanded further
|
|
2193
|
+
if _seed_severity != "field_change":
|
|
2194
|
+
_hop_scored.append((_dep_score, _dep_path))
|
|
2195
|
+
_hop_bfs_staged.append((_hop_num, _dep_score, _dep_path, RelevantFile(
|
|
2196
|
+
path=_dep_path, role=_dep_role, score=_dep_score,
|
|
2197
|
+
reason=_reason, why=_why_str,
|
|
2198
|
+
)))
|
|
2199
|
+
|
|
2200
|
+
# Per-hop cap: keep only the top-_max_results by score before merging.
|
|
2201
|
+
# Prevents a single high-fanout seed (e.g. User.java imported by every
|
|
2202
|
+
# controller) from flooding _bfs_collected and pushing out hop-2/3 results.
|
|
2203
|
+
_hop_bfs_staged.sort(key=lambda x: (-x[1], x[2]))
|
|
2204
|
+
_bfs_collected.extend(_hop_bfs_staged[:_max_results])
|
|
2079
2205
|
|
|
2080
2206
|
# next frontier = top-N files by score from this hop
|
|
2081
2207
|
_hop_scored.sort(key=lambda x: -x[0])
|
|
2082
2208
|
_bfs_frontier = [p for _, p in _hop_scored[:_max_results]]
|
|
2083
2209
|
|
|
2084
|
-
# merge into relevant: closer hops first, then higher score; cap total at
|
|
2210
|
+
# merge into relevant: closer hops first, then higher score; cap total at 18
|
|
2085
2211
|
_bfs_collected.sort(key=lambda x: (x[0], -x[1], x[2]))
|
|
2086
|
-
|
|
2212
|
+
_bfs_cap = sum(budget[0] for budget in _BFS_HOP_BUDGET) # 8+6+4 = 18
|
|
2213
|
+
relevant.extend(rf for _, _, _, rf in _bfs_collected[:_bfs_cap])
|
|
2214
|
+
|
|
2215
|
+
# Truncation guard: flag excess expansion — gap message added in Step 6.
|
|
2216
|
+
_EXPANSION_HARD_LIMIT = 40
|
|
2217
|
+
_expansion_truncated = len(relevant) > _EXPANSION_HARD_LIMIT
|
|
2218
|
+
if _expansion_truncated:
|
|
2219
|
+
relevant = relevant[:_EXPANSION_HARD_LIMIT]
|
|
2087
2220
|
|
|
2088
2221
|
# ── Step 3d: per-file impact scores, change_type, system_impact ─────────
|
|
2089
2222
|
# Downstream fanout: count graph edges originating from each changed file
|
|
@@ -2257,6 +2390,11 @@ class TaskContextBuilder:
|
|
|
2257
2390
|
analysis_gaps: list[str] = [
|
|
2258
2391
|
f"Related file expansion: type-aware chain expansion + {_bfs_note} + module/directory heuristics",
|
|
2259
2392
|
]
|
|
2393
|
+
if _expansion_truncated:
|
|
2394
|
+
analysis_gaps.insert(0,
|
|
2395
|
+
f"truncated_dependency_graph: expansion exceeded {_EXPANSION_HARD_LIMIT} nodes"
|
|
2396
|
+
" — lower-priority files omitted. Narrow scope with --since <ref> for precision."
|
|
2397
|
+
)
|
|
2260
2398
|
if noise_count > 0 and meaningful > 0:
|
|
2261
2399
|
analysis_gaps.append(
|
|
2262
2400
|
f"{noise_count} IDE/tooling file(s) in diff excluded from impact analysis"
|
|
@@ -2410,6 +2548,25 @@ class TaskContextBuilder:
|
|
|
2410
2548
|
"error": True,
|
|
2411
2549
|
}
|
|
2412
2550
|
|
|
2551
|
+
def _get_uncommitted_changed_files(self) -> list[str]:
|
|
2552
|
+
"""Return files with uncommitted working-tree changes (unstaged only).
|
|
2553
|
+
|
|
2554
|
+
Used by review-pr when no --since ref is given, so we don't confuse
|
|
2555
|
+
the last *committed* diff (HEAD~1 vs HEAD) with an actual PR diff.
|
|
2556
|
+
"""
|
|
2557
|
+
import subprocess
|
|
2558
|
+
try:
|
|
2559
|
+
result = subprocess.run(
|
|
2560
|
+
["git", "diff", "--name-only", "--relative"],
|
|
2561
|
+
cwd=str(self.root), capture_output=True, text=True,
|
|
2562
|
+
encoding="utf-8", errors="replace", timeout=10,
|
|
2563
|
+
)
|
|
2564
|
+
if result.returncode == 0:
|
|
2565
|
+
return [l.strip() for l in (result.stdout or "").splitlines() if l.strip()]
|
|
2566
|
+
except (subprocess.TimeoutExpired, FileNotFoundError):
|
|
2567
|
+
pass
|
|
2568
|
+
return []
|
|
2569
|
+
|
|
2413
2570
|
def _get_git_changed_files(self, since: Optional[str] = None) -> Optional[list[str]]:
|
|
2414
2571
|
"""Get files changed since a git ref (default: HEAD~1) relative to self.root.
|
|
2415
2572
|
|
|
@@ -552,10 +552,10 @@ class TestReviewPrSuspectedAreas:
|
|
|
552
552
|
assert "ci_decision" in data
|
|
553
553
|
|
|
554
554
|
def test_review_pr_no_diff_error_when_git_but_no_changes(self, monkeypatch):
|
|
555
|
-
# Simulate: is_git_repo=True but no
|
|
555
|
+
# Simulate: is_git_repo=True but no uncommitted changes
|
|
556
556
|
from sourcecode import prepare_context as _pc
|
|
557
557
|
monkeypatch.setattr(_pc.TaskContextBuilder, "_is_git_repo", lambda self: True)
|
|
558
|
-
monkeypatch.setattr(_pc.TaskContextBuilder, "
|
|
558
|
+
monkeypatch.setattr(_pc.TaskContextBuilder, "_get_uncommitted_changed_files", lambda self: [])
|
|
559
559
|
result = _invoke("prepare-context", "review-pr", str(FIXTURE))
|
|
560
560
|
assert result.exit_code == 1
|
|
561
561
|
data = _json(result)
|
|
@@ -563,12 +563,12 @@ class TestReviewPrSuspectedAreas:
|
|
|
563
563
|
assert data.get("ci_decision") == "no_changes"
|
|
564
564
|
|
|
565
565
|
def test_review_pr_with_mocked_diff_returns_pr_fields(self, monkeypatch):
|
|
566
|
-
# Simulate: valid git repo with one changed controller file
|
|
566
|
+
# Simulate: valid git repo with one changed controller file (no --since → uncommitted path)
|
|
567
567
|
from sourcecode import prepare_context as _pc
|
|
568
568
|
monkeypatch.setattr(_pc.TaskContextBuilder, "_is_git_repo", lambda self: True)
|
|
569
569
|
monkeypatch.setattr(
|
|
570
|
-
_pc.TaskContextBuilder, "
|
|
571
|
-
lambda self
|
|
570
|
+
_pc.TaskContextBuilder, "_get_uncommitted_changed_files",
|
|
571
|
+
lambda self: ["src/main/java/com/example/UserController.java"],
|
|
572
572
|
)
|
|
573
573
|
result = _invoke("prepare-context", "review-pr", str(FIXTURE))
|
|
574
574
|
assert result.exit_code == 0, result.output
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
# Continue Here — atlas-cli --agent token reduction
|
|
2
|
-
|
|
3
|
-
**Paused:** 2026-05-16 (sesión 4)
|
|
4
|
-
**Repo:** `/Users/user/Downloads/atlas-cli`
|
|
5
|
-
**Branch:** master
|
|
6
|
-
**Commit:** `f1cb001 corrigiendo bug --agent que duplicaba tokens sin justificación` (committed)
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Estado actual
|
|
11
|
-
|
|
12
|
-
Sesión 4: refactorización de `agent_view()` en `serializer.py` completada. **Todo committed.** Working tree limpio.
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
## Qué se hizo esta sesión
|
|
17
|
-
|
|
18
|
-
### Problema resuelto
|
|
19
|
-
|
|
20
|
-
`--agent` producía ~11.337 tokens en SAS vs ~5.885 de `--compact`, con contenido casi idéntico. Objetivo: reducir tokens significativamente manteniendo solo lo que diferencia `--agent`.
|
|
21
|
-
|
|
22
|
-
### Cambios en `agent_view()` (`src/sourcecode/serializer.py`)
|
|
23
|
-
|
|
24
|
-
| Cambio | Impacto |
|
|
25
|
-
|--------|---------|
|
|
26
|
-
| Elimina `production_dependencies` / `dev_tools` / `test_utilities` / `build_tooling` (dep_groups asdict completo) | Mayor fuente de bloat: -3.000-5.000 tokens en repos grandes |
|
|
27
|
-
| `key_dependencies`: de asdict+50 items → `name+version+role+risk_flags` solo, cap 20 | -500-1.500 tokens |
|
|
28
|
-
| Elimina `confidence_summary.hard_signals` / `soft_signals` / `ignored_signals` | -500-1.000 tokens |
|
|
29
|
-
| Elimina bloque `agent_mode` (contenido estático sin señal) | -80 tokens siempre |
|
|
30
|
-
| Elimina `signals.env_vars.keys[]` (duplica compact `env_map`) | -300-500 tokens |
|
|
31
|
-
| `signals.code_notes.top` cap 10→5, strip a `kind+path+line+text` | -200 tokens |
|
|
32
|
-
| Entry points (no-bootstrap): strip a `path+kind+confidence` (como compact) | reducción moderada |
|
|
33
|
-
| Elimina `development_entry_points` (noise para agentes de producción) | pequeña |
|
|
34
|
-
| `architecture.layers` capado a 5 | pequeña |
|
|
35
|
-
|
|
36
|
-
**Reducción estimada para SAS:** −40–60% tokens vs `--agent` anterior.
|
|
37
|
-
|
|
38
|
-
### Campos que permanecen únicos de `--agent`
|
|
39
|
-
|
|
40
|
-
| Campo | Por qué justifica tokens extra vs `--compact` |
|
|
41
|
-
|-------|----------------------------------------------|
|
|
42
|
-
| `file_relevance` (top-20 scored) | Compact no tiene equivalente. Agente sabe qué leer sin explorar. |
|
|
43
|
-
| `architecture.layers` | Compact solo tiene `architecture_summary` string. |
|
|
44
|
-
| `suspicious_dependencies` | Deps declarados sin import observado. Compact no lo tiene. |
|
|
45
|
-
| `confidence_reasons` | Explicación accionable de secciones low-confidence. Compact no lo tiene. |
|
|
46
|
-
|
|
47
|
-
### Tests actualizados
|
|
48
|
-
|
|
49
|
-
- `tests/test_block5_quality.py` — 5 tests de `agent_mode` reemplazados por tests de las nuevas garantías (no `agent_mode`, no `hard_signals`, no `env_vars.keys`, no dep_groups)
|
|
50
|
-
- `tests/test_pipeline_integrity.py` — `test_agent_splits_development_and_auxiliary_eps` → verifica que dev/aux EPs NO aparecen
|
|
51
|
-
|
|
52
|
-
---
|
|
53
|
-
|
|
54
|
-
## Tests al pausar
|
|
55
|
-
|
|
56
|
-
Suite completa (sin fallos pre-existentes): **todo verde**
|
|
57
|
-
|
|
58
|
-
Fallos pre-existentes (no relacionados, ya presentes antes):
|
|
59
|
-
- `test_block2_coverage.py::test_java_marked_unsupported` — DocRecord bug en doc_analyzer.py
|
|
60
|
-
- `test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile` — versión typer mismatch
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
## Pendiente / próximos pasos opcionales
|
|
65
|
-
|
|
66
|
-
1. **Smoke test en saint-server** para medir tokens reales antes/después:
|
|
67
|
-
```bash
|
|
68
|
-
sourcecode saint-server --agent --output /tmp/agent_new.json
|
|
69
|
-
python3 -c "import json,sys; d=json.load(open('/tmp/agent_new.json')); print('agent tokens (est):', len(json.dumps(d))//4)"
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
2. **Verificar que `suspicious_dependencies` es útil en repos reales** — en repos Python/JS (no JVM, donde el index de imports no funciona). En JVM siempre vacío por diseño.
|
|
73
|
-
|
|
74
|
-
3. **Ajustar caps según medición real**: si `file_relevance` (20 files) sigue siendo el mayor contribuyente de tokens, considerar reducir a 15. Medir con `--full` vs default.
|
|
75
|
-
|
|
76
|
-
4. **Smoke tests delta pendientes** de sesión anterior — ver sección "Smoke tests sesión 3" en historial de commits.
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
## Para retomar
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
cd /Users/user/Downloads/atlas-cli
|
|
84
|
-
git log --oneline -3
|
|
85
|
-
# debe mostrar: f1cb001 corrigiendo bug --agent que duplicaba tokens sin justificación
|
|
86
|
-
|
|
87
|
-
python3 -m pytest tests/ \
|
|
88
|
-
--ignore=tests/test_block2_coverage.py \
|
|
89
|
-
--deselect=tests/test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions \
|
|
90
|
-
-q
|
|
91
|
-
# Expected: todo verde
|
|
92
|
-
|
|
93
|
-
# Verificación rápida agent_view
|
|
94
|
-
python3 -c "
|
|
95
|
-
from sourcecode.serializer import agent_view
|
|
96
|
-
from sourcecode.schema import SourceMap, StackInfo, SourceMapMetadata
|
|
97
|
-
sm = SourceMap(stacks=[StackInfo(stack='python', primary=True)], project_type='python', project_summary='test')
|
|
98
|
-
r = agent_view(sm)
|
|
99
|
-
assert 'agent_mode' not in r
|
|
100
|
-
assert 'production_dependencies' not in r
|
|
101
|
-
assert 'hard_signals' not in r.get('confidence_summary', {})
|
|
102
|
-
print('OK — agent_mode/dep_groups/hard_signals all absent')
|
|
103
|
-
"
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
*Pausado 2026-05-16 sesión 4 — gsd:pause-work*
|
{sourcecode-1.29.0 → sourcecode-1.30.1}/.agents/skills/source-command-gsd-join-discord/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.29.0 → sourcecode-1.30.1}/.agents/skills/source-command-gsd-review-backlog/SKILL.md
RENAMED
|
File without changes
|
{sourcecode-1.29.0 → sourcecode-1.30.1}/.agents/skills/source-command-gsd-workstreams/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|