attocode-code-intel 0.1.1__tar.gz → 0.1.3__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.
Files changed (415) hide show
  1. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/PKG-INFO +1 -1
  2. attocode_code_intel-0.1.3/evals/results/2026-10-11-agent-r4-stage0.md +186 -0
  3. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/pyproject.toml +1 -1
  4. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/__init__.py +1 -1
  5. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/ast_service.py +3 -3
  6. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/codebase_context.py +40 -16
  7. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cross_references.py +27 -13
  8. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/index_store.py +1 -1
  9. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/db_provider.py +6 -1
  10. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/full_indexer.py +17 -6
  11. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/incremental.py +7 -1
  12. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/test_ranking.py +71 -1
  13. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/composite_tools.py +38 -2
  14. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_focused_inspection.py +50 -0
  15. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_navigation_evidence.py +36 -0
  16. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/.gitignore +0 -0
  17. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/LICENSE +0 -0
  18. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/README.md +0 -0
  19. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/README.md +0 -0
  20. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_candidate_audit.yaml +0 -0
  21. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_query_cases.yaml +0 -0
  22. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_query_external_cases.yaml +0 -0
  23. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_query_final_holdout.yaml +0 -0
  24. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/client_comparison.py +0 -0
  25. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/client_responses.py +0 -0
  26. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/daily.py +0 -0
  27. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/external_benchmarks.py +0 -0
  28. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/external_study.py +0 -0
  29. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/graded_blind_pack.yaml +0 -0
  30. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/localize_study.py +0 -0
  31. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/locbench_title_pack.yaml +0 -0
  32. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/onboarding_study.py +0 -0
  33. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/pilot.py +0 -0
  34. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/quality_scoring.py +0 -0
  35. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/quality_tasks.py +0 -0
  36. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/release_gate.py +0 -0
  37. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/responses.py +0 -0
  38. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-09-05-macos.json +0 -0
  39. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-04-broad-query-ranking.md +0 -0
  40. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-04-decision-reranker-trial.md +0 -0
  41. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-04-systemone-http-local-trial.md +0 -0
  42. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-05-broad-candidate-audit.md +0 -0
  43. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-05-source-view-transfer.md +0 -0
  44. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-08-blind-graded-rerank.md +0 -0
  45. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-08-locbench-560.md +0 -0
  46. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-09-locbench-560-first-stage.md +0 -0
  47. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-10-agent-pilot.md +0 -0
  48. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-10-agent-r3.md +0 -0
  49. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-10-matrix-r1.md +0 -0
  50. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/README.md +0 -0
  51. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/source_view_transfer.yaml +0 -0
  52. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study.py +0 -0
  53. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study_clients.py +0 -0
  54. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study_events.py +0 -0
  55. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study_tasks.py +0 -0
  56. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/token_overhead.py +0 -0
  57. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/understanding_scoring.py +0 -0
  58. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/understanding_study.py +0 -0
  59. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/warm_cache.py +0 -0
  60. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/workflows.py +0 -0
  61. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/GUIDELINES.md +0 -0
  62. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/__init__.py +0 -0
  63. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/errors/__init__.py +0 -0
  64. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/__init__.py +0 -0
  65. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/__init__.py +0 -0
  66. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/architecture_drift.py +0 -0
  67. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/ast_chunker.py +0 -0
  68. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/blob_oid.py +0 -0
  69. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cache_manifest.py +0 -0
  70. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cas.py +0 -0
  71. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/code_analyzer.py +0 -0
  72. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/codebase_ast.py +0 -0
  73. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cross_mode.py +0 -0
  74. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/embedding_rotation.py +0 -0
  75. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/embeddings.py +0 -0
  76. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/frecency.py +0 -0
  77. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/fuzzy.py +0 -0
  78. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/hierarchical_explorer.py +0 -0
  79. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/hydration.py +0 -0
  80. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/index_repair.py +0 -0
  81. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/memory_store.py +0 -0
  82. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/module_resolution.py +0 -0
  83. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/query_constraints.py +0 -0
  84. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/query_history.py +0 -0
  85. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/reranker.py +0 -0
  86. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/semantic_search.py +0 -0
  87. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/syntax_evidence.py +0 -0
  88. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/systemone_ranker.py +0 -0
  89. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/temporal_coupling.py +0 -0
  90. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/trigram_index.py +0 -0
  91. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/trigram_regex.py +0 -0
  92. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/ts_parser.py +0 -0
  93. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/vector_store.py +0 -0
  94. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/feature_flags/__init__.py +0 -0
  95. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/lsp/__init__.py +0 -0
  96. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/lsp/client.py +0 -0
  97. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/mcp/__init__.py +0 -0
  98. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/mcp/client.py +0 -0
  99. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/__init__.py +0 -0
  100. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/custom_rules.py +0 -0
  101. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/dataflow.py +0 -0
  102. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/dependency_audit.py +0 -0
  103. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/matcher.py +0 -0
  104. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/patterns.py +0 -0
  105. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/scanner.py +0 -0
  106. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/utilities/__init__.py +0 -0
  107. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/utilities/ignore.py +0 -0
  108. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/utilities/token_estimate.py +0 -0
  109. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/tricks/__init__.py +0 -0
  110. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/tricks/recursive_context.py +0 -0
  111. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/types/__init__.py +0 -0
  112. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/types/events.py +0 -0
  113. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/types/severity.py +0 -0
  114. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_shared.py +0 -0
  115. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/analysis_coverage.py +0 -0
  116. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/__init__.py +0 -0
  117. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/access.py +0 -0
  118. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/app.py +0 -0
  119. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/__init__.py +0 -0
  120. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/api_keys.py +0 -0
  121. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/context.py +0 -0
  122. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/jwt.py +0 -0
  123. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/oauth.py +0 -0
  124. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/passwords.py +0 -0
  125. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/deps.py +0 -0
  126. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/knowledge_bridge.py +0 -0
  127. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/mcp_transport.py +0 -0
  128. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/middleware.py +0 -0
  129. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/models.py +0 -0
  130. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/__init__.py +0 -0
  131. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/local_provider.py +0 -0
  132. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/remote_provider.py +0 -0
  133. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/repository_source.py +0 -0
  134. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/__init__.py +0 -0
  135. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/_pin_helper.py +0 -0
  136. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/activity.py +0 -0
  137. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/adr.py +0 -0
  138. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/analysis.py +0 -0
  139. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/api_keys.py +0 -0
  140. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/auth.py +0 -0
  141. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/branches.py +0 -0
  142. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/cross_repo_search.py +0 -0
  143. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/embeddings.py +0 -0
  144. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/files.py +0 -0
  145. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/files_v2.py +0 -0
  146. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/gc.py +0 -0
  147. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/git_v2.py +0 -0
  148. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/graph.py +0 -0
  149. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/graph_viz.py +0 -0
  150. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/health.py +0 -0
  151. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/history.py +0 -0
  152. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/jobs.py +0 -0
  153. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/learning.py +0 -0
  154. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/lsp.py +0 -0
  155. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/notify.py +0 -0
  156. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/operations.py +0 -0
  157. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/orgs.py +0 -0
  158. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/preferences.py +0 -0
  159. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/presence.py +0 -0
  160. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/projects.py +0 -0
  161. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/repos.py +0 -0
  162. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/search.py +0 -0
  163. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/snapshots.py +0 -0
  164. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/webhooks.py +0 -0
  165. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/websocket.py +0 -0
  166. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/static/graph.html +0 -0
  167. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/utils.py +0 -0
  168. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/__init__.py +0 -0
  169. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/hashing.py +0 -0
  170. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/provenance.py +0 -0
  171. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/retrieval_pin.py +0 -0
  172. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/audit.py +0 -0
  173. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/bug_finder.py +0 -0
  174. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/bundle.py +0 -0
  175. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/catalog.py +0 -0
  176. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/change_review.py +0 -0
  177. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/cli.py +0 -0
  178. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/community.py +0 -0
  179. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/__init__.py +0 -0
  180. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/jev.py +0 -0
  181. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/llm.py +0 -0
  182. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/redact.py +0 -0
  183. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/settings.py +0 -0
  184. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/config.py +0 -0
  185. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/crypto.py +0 -0
  186. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/__init__.py +0 -0
  187. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/base.py +0 -0
  188. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/engine.py +0 -0
  189. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/models.py +0 -0
  190. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/entrypoint.py +0 -0
  191. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/focused_evidence.py +0 -0
  192. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/freshness.py +0 -0
  193. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/gateway.py +0 -0
  194. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/__init__.py +0 -0
  195. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/credentials.py +0 -0
  196. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/manager.py +0 -0
  197. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/models.py +0 -0
  198. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/storage.py +0 -0
  199. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/graph_query_parser.py +0 -0
  200. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/helpers.py +0 -0
  201. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/__init__.py +0 -0
  202. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/debouncer.py +0 -0
  203. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/delta_indexer.py +0 -0
  204. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/parser.py +0 -0
  205. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/summarizer.py +0 -0
  206. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/installer.py +0 -0
  207. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/knowledge.py +0 -0
  208. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/local_knowledge.py +0 -0
  209. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/alembic.ini +0 -0
  210. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/env.py +0 -0
  211. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/script.py.mako +0 -0
  212. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/001_initial_schema.py +0 -0
  213. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/002_branch_version_and_embeddings.py +0 -0
  214. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/003_embedding_uniqueness_and_cascade.py +0 -0
  215. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/004_audit_events.py +0 -0
  216. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/005_user_preferences.py +0 -0
  217. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/006_google_oauth.py +0 -0
  218. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/007_pgvector_embeddings.py +0 -0
  219. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/008_symbol_references.py +0 -0
  220. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/009_webhook_secret_encryption.py +0 -0
  221. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/010_add_commits_table.py +0 -0
  222. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/011_commit_changed_files.py +0 -0
  223. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/012_branch_merged_at.py +0 -0
  224. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/013_revoked_tokens.py +0 -0
  225. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/014_blame_hunks.py +0 -0
  226. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/015_commit_file_stats.py +0 -0
  227. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/016_embedding_provenance_columns.py +0 -0
  228. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/017_provenance_table.py +0 -0
  229. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/018_repo_snapshots.py +0 -0
  230. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/019_symref_caller.py +0 -0
  231. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/020_shared_knowledge.py +0 -0
  232. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/onboarding.py +0 -0
  233. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/output.py +0 -0
  234. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/precision.py +0 -0
  235. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/presence.py +0 -0
  236. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/probe.py +0 -0
  237. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/project_dir.py +0 -0
  238. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/pubsub.py +0 -0
  239. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/query_ranking.py +0 -0
  240. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/readiness.py +0 -0
  241. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/redis.py +0 -0
  242. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/reference_pages.py +0 -0
  243. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/remote.py +0 -0
  244. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/repo_ranker.py +0 -0
  245. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/request_context.py +0 -0
  246. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/__init__.py +0 -0
  247. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/ci.py +0 -0
  248. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/combinators.py +0 -0
  249. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/enricher.py +0 -0
  250. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/evolution.py +0 -0
  251. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/executor.py +0 -0
  252. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/filters/__init__.py +0 -0
  253. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/filters/pipeline.py +0 -0
  254. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/formatter.py +0 -0
  255. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/hygiene.py +0 -0
  256. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/importers/__init__.py +0 -0
  257. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/importers/semgrep.py +0 -0
  258. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/loader.py +0 -0
  259. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/marketplace.py +0 -0
  260. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/metavar.py +0 -0
  261. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/model.py +0 -0
  262. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/__init__.py +0 -0
  263. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/_license_templates/Apache-2.0.txt +0 -0
  264. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/_license_templates/MIT.txt +0 -0
  265. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/LICENSE +0 -0
  266. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/NOTICE +0 -0
  267. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/PORTING.md +0 -0
  268. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/manifest.yaml +0 -0
  269. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B105-hardcoded-password.yaml +0 -0
  270. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B303-weak-md5.yaml +0 -0
  271. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B304-weak-des.yaml +0 -0
  272. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B307-use-of-eval.yaml +0 -0
  273. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B324-weak-sha1.yaml +0 -0
  274. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B501-no-cert-validation.yaml +0 -0
  275. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B602-shell-true.yaml +0 -0
  276. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B608-sqli.yaml +0 -0
  277. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/LICENSE +0 -0
  278. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/NOTICE +0 -0
  279. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/PORTING.md +0 -0
  280. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/manifest.yaml +0 -0
  281. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/eqeqeq.yaml +0 -0
  282. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-eval.yaml +0 -0
  283. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-implied-eval.yaml +0 -0
  284. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-new-func.yaml +0 -0
  285. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-throw-literal.yaml +0 -0
  286. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-var.yaml +0 -0
  287. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-with.yaml +0 -0
  288. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/LICENSE +0 -0
  289. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/NOTICE +0 -0
  290. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/PORTING.md +0 -0
  291. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/manifest.yaml +0 -0
  292. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G101-hardcoded-credentials.yaml +0 -0
  293. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G102-bind-all-interfaces.yaml +0 -0
  294. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G103-unsafe-block.yaml +0 -0
  295. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G201-sql-format.yaml +0 -0
  296. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G304-file-inclusion.yaml +0 -0
  297. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G401-weak-cipher.yaml +0 -0
  298. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G402-tls-min-version.yaml +0 -0
  299. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G501-md5-import.yaml +0 -0
  300. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/cpp/manifest.yaml +0 -0
  301. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/cpp/rules/security.yaml +0 -0
  302. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/cpp/rules/structural.yaml +0 -0
  303. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/csharp/manifest.yaml +0 -0
  304. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/csharp/rules/security.yaml +0 -0
  305. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/csharp/rules/structural.yaml +0 -0
  306. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/manifest.yaml +0 -0
  307. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/rules/performance.yaml +0 -0
  308. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/rules/security.yaml +0 -0
  309. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/rules/structural.yaml +0 -0
  310. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/taint/sanitizers.yaml +0 -0
  311. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/taint/sinks.yaml +0 -0
  312. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/taint/sources.yaml +0 -0
  313. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/manifest.yaml +0 -0
  314. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/rules/correctness.yaml +0 -0
  315. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/rules/structural.yaml +0 -0
  316. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/taint/sinks.yaml +0 -0
  317. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/taint/sources.yaml +0 -0
  318. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/kotlin/manifest.yaml +0 -0
  319. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/kotlin/rules/correctness.yaml +0 -0
  320. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/kotlin/rules/structural.yaml +0 -0
  321. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/php/manifest.yaml +0 -0
  322. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/php/rules/security.yaml +0 -0
  323. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/php/rules/structural.yaml +0 -0
  324. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/python/manifest.yaml +0 -0
  325. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/python/rules/performance.yaml +0 -0
  326. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/python/rules/structural.yaml +0 -0
  327. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/ruby/manifest.yaml +0 -0
  328. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/ruby/rules/security.yaml +0 -0
  329. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/ruby/rules/structural.yaml +0 -0
  330. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/rust/manifest.yaml +0 -0
  331. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/rust/rules/correctness.yaml +0 -0
  332. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/rust/rules/structural.yaml +0 -0
  333. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/typescript/manifest.yaml +0 -0
  334. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/typescript/rules/performance.yaml +0 -0
  335. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/typescript/rules/structural.yaml +0 -0
  336. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/pack_loader.py +0 -0
  337. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/plugins/__init__.py +0 -0
  338. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/plugins/plugin_loader.py +0 -0
  339. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/profiling.py +0 -0
  340. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/registry.py +0 -0
  341. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/sarif.py +0 -0
  342. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/synthesis.py +0 -0
  343. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/testing.py +0 -0
  344. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/server.py +0 -0
  345. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/service.py +0 -0
  346. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/sharing.py +0 -0
  347. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/__init__.py +0 -0
  348. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/branch_overlay.py +0 -0
  349. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/content_store.py +0 -0
  350. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/dependency_store.py +0 -0
  351. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/diff_engine.py +0 -0
  352. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/embedding_store.py +0 -0
  353. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/provenance_store.py +0 -0
  354. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/security_scanner_db.py +0 -0
  355. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/symbol_store.py +0 -0
  356. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/structural_evidence.py +0 -0
  357. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/symbol_inspection.py +0 -0
  358. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/symbol_links.py +0 -0
  359. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/telemetry.py +0 -0
  360. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/__init__.py +0 -0
  361. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/fixtures.py +0 -0
  362. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/helpers.py +0 -0
  363. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/mocks.py +0 -0
  364. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/__init__.py +0 -0
  365. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/adr_tools.py +0 -0
  366. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/analysis_tools.py +0 -0
  367. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/cross_mode_tools.py +0 -0
  368. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/dead_code_tools.py +0 -0
  369. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/distill_tools.py +0 -0
  370. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/frecency_tools.py +0 -0
  371. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/fuzzy_tools.py +0 -0
  372. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/history_tools.py +0 -0
  373. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/learning_tools.py +0 -0
  374. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/lsp_tools.py +0 -0
  375. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/maintenance_tools.py +0 -0
  376. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/navigation_tools.py +0 -0
  377. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/overlay_tools.py +0 -0
  378. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/pin_store.py +0 -0
  379. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/pin_tools.py +0 -0
  380. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/query_constraints_tools.py +0 -0
  381. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/query_history_tools.py +0 -0
  382. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/readiness_tools.py +0 -0
  383. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/rule_tools.py +0 -0
  384. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/search_tools.py +0 -0
  385. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/snapshot_tools.py +0 -0
  386. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/__init__.py +0 -0
  387. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/job_utils.py +0 -0
  388. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/jobs.py +0 -0
  389. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/run.py +0 -0
  390. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/settings.py +0 -0
  391. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_cold_discovery.py +0 -0
  392. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_compact_inspection.py +0 -0
  393. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_daily_workflows.py +0 -0
  394. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_doctor.py +0 -0
  395. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_edit_restart.py +0 -0
  396. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_external_study.py +0 -0
  397. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_index_reuse.py +0 -0
  398. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_language_capabilities.py +0 -0
  399. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_local_reranker.py +0 -0
  400. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_localize_study.py +0 -0
  401. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_onboarding_study.py +0 -0
  402. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_pilot.py +0 -0
  403. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_precision_protocol.py +0 -0
  404. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_product.py +0 -0
  405. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_quality_evaluation.py +0 -0
  406. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_query_ranking.py +0 -0
  407. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_ranking_intent.py +0 -0
  408. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_remote.py +0 -0
  409. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_structural_evidence.py +0 -0
  410. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_study.py +0 -0
  411. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_systemone_ranker.py +0 -0
  412. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_token_overhead.py +0 -0
  413. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_understanding_evaluation.py +0 -0
  414. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_walk_order.py +0 -0
  415. {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_warm_cache.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: attocode-code-intel
3
- Version: 0.1.1
3
+ Version: 0.1.3
4
4
  Summary: Local code search and navigation for coding agents and people
5
5
  Project-URL: Homepage, https://github.com/eren23/attocode
6
6
  Project-URL: Repository, https://github.com/eren23/attocode
@@ -0,0 +1,186 @@
1
+ # Agent study R4, Stage 0: tests for a change
2
+
3
+ **Status: The rule for Stage 1 is not met, so no agent runs. On 123 dev
4
+ tasks, `suggest_tests` of code intel 0.1.1 had a test Recall@5 of 0.469.
5
+ A file-name grep had 0.477 (Δ -0.008, range -0.117 to +0.101).** In 19
6
+ tasks, `suggest_tests` failed with `RuntimeError: dictionary changed size
7
+ during iteration`. #161 fixes this race. With the fix, the 19 tasks ran,
8
+ and Recall@5 was 0.545 against 0.477 (Δ +0.068, range -0.020 to +0.158).
9
+ That is also below the rule. By the rule, the next work is better test
10
+ ranking, not agent runs.
11
+
12
+ **Update after the ranking change (#164): the holdout check also does not
13
+ meet the rule.** On the 56 holdout tasks, `suggest_tests` had Recall@5
14
+ 0.640 and the name grep 0.586 (Δ +0.054, range -0.047 to +0.167). On the
15
+ dev tasks, which we used to make the change, Δ was +0.213. Thus no agent
16
+ runs. The section [After the ranking change](#after-the-ranking-change)
17
+ gives the details.
18
+
19
+ R4 follows the R3 rule: after the localization studies, test a review
20
+ task. The [R3 results](2026-10-10-agent-r3.md) give the background.
21
+
22
+ ## Rules
23
+
24
+ We wrote these rules before Stage 0 ran, and the user approved them on
25
+ 2026-10-11. The design file is `studies/r4-design.md` in the evals store
26
+ (sha256 `17b80ae0…`). We did not change it after results existed.
27
+
28
+ - **Question.** When an agent reviews a change, does code intel help it
29
+ name the existing tests that check the change?
30
+ - **Tasks.** R1 core-mix tasks whose `test_patch` changes 1 to 5 test
31
+ files that exist at the base commit. These files are the gold set. The
32
+ change is the `patch`, applied to the base commit and not committed.
33
+ - **Stage 0 arms.** Each arm gets the changed files of the patch.
34
+ - `product`: the first 10 paths of `suggest_tests(files=changed)`, code
35
+ intel 0.1.1 from PyPI.
36
+ - `name`: the test files whose file name contains the stem of a changed
37
+ file, in path order.
38
+ - **Metric.** Test Recall@5: the share of gold files in the first 5 paths.
39
+ Also Hit@5: at least one gold file in the first 5.
40
+ - **Rule.** Go to Stage 1 (agent runs) only if `product` Recall@5 on dev
41
+ is 0.10 or more above `name`. Also, the 95% range from a repository
42
+ bootstrap must be above 0. If not, improve test ranking first.
43
+ - **Failures.** A task where `suggest_tests` fails keeps an empty
44
+ `product` list. Thus a failure counts against the product.
45
+
46
+ The design file gives 121 repositories for the 179 core-mix tasks. The
47
+ correct count is 100. The dev split has 123 tasks from 78 repositories.
48
+
49
+ ## Setup
50
+
51
+ - A RunPod CPU pod, 12 workers, one repository group for each worker.
52
+ - For each task: a blobless clone at the base commit, `git clean`, then
53
+ `git apply` of the patch. The `product` arm polls `suggest_tests` every
54
+ 5 seconds until the index phase is `ready`, for at most 900 seconds.
55
+ - Two tasks failed in the first pass because `git clone` failed. We
56
+ removed their rows and ran them again. One task (dubbo-3317) failed
57
+ because its patch does not apply at the base commit. It stays in the
58
+ results as a failure.
59
+ - The fix view ran the 19 failed tasks again with the #161 branch. All
60
+ other rows are the same as in the primary view.
61
+
62
+ The pod ran for about 1.3 hours and cost about USD 1.15.
63
+
64
+ ## Results
65
+
66
+ | View | Tasks | Failed | `product` R@5 | `name` R@5 | Δ | Range of Δ (95%) | `product` Hit@5 | `name` Hit@5 | Rule met |
67
+ |---|---:|---:|---:|---:|---:|---|---:|---:|---|
68
+ | Primary (0.1.1) | 123 | 20 | 0.469 | 0.477 | -0.008 | -0.117 to +0.101 | 0.496 | 0.512 | No |
69
+ | Fix view (#161) | 123 | 1 | 0.545 | 0.477 | +0.068 | -0.020 to +0.158 | 0.577 | 0.512 | No |
70
+
71
+ The range comes from 10,000 repository bootstrap draws. In the primary
72
+ view, `product` was higher on 18 tasks and `name` on 17. In the fix view,
73
+ the counts are 22 and 10.
74
+
75
+ **Reading.** The primary view is the result of the study. Its Δ is near 0
76
+ and its range includes 0. The fix view shows the product as it will ship
77
+ in the next release. Its Δ is positive, but it is below 0.10, and its
78
+ range includes 0. The race fix does not change the decision.
79
+
80
+ ## Where each arm finds the tests
81
+
82
+ These counts use the fix view and the 122 tasks that ran. They are leads
83
+ for the ranking work, not results of the rule.
84
+
85
+ | Language of the change | Tasks | `product` R@5 | `name` R@5 | Empty `product` list |
86
+ |---|---:|---:|---:|---:|
87
+ | Python | 67 | 0.59 | 0.50 | 11 |
88
+ | JavaScript/TypeScript | 23 | 0.78 | 0.61 | 3 |
89
+ | Java | 12 | 0.31 | 0.51 | 6 |
90
+ | Go | 6 | 0.83 | 0.67 | 0 |
91
+ | Rust | 6 | 0.17 | 0.00 | 1 |
92
+ | C# | 5 | 0.00 | 0.20 | 5 |
93
+ | C/C++ | 3 | 0.00 | 0.00 | 3 |
94
+ | No code file | 1 | 0.00 | 0.00 | 1 |
95
+
96
+ - Both arms had a Hit@5 on 53 tasks. Only `product` had one on 18 tasks,
97
+ and only `name` on 10. Neither arm had one on 41 tasks.
98
+ - `suggest_tests` gave an empty list on 30 tasks. On 3 more tasks, a gold
99
+ file was at rank 6 to 10 and not in the first 5.
100
+ - **Python test folders.** All 7 matplotlib tasks got an empty list. For
101
+ example, the change is `lib/matplotlib/figure.py`, and the gold test is
102
+ `lib/matplotlib/tests/test_figure.py`. The name rules do not look in a
103
+ `tests/` folder next to the source file. The imports do not link either,
104
+ because the resolver does not know the `lib/` source root. Prefect
105
+ (`<package>/tests/test_worker.py`) and pylint (`unittest_misc.py`) are
106
+ similar.
107
+ - **Java.** The name rule maps only `src/main/` to `src/test/` with the
108
+ same package. Gold tests in another package (dubbo `version/VersionTest`)
109
+ or in another module (javaparser `javaparser-core-testing`) are not
110
+ found.
111
+ - **C# and C/C++.** `suggest_tests` has no name rule for these languages,
112
+ so it found no test in 8 tasks.
113
+ - **Neither arm.** Many of the 41 tasks have gold tests whose name does
114
+ not contain a changed stem. For example, a change to `figure.py` has the
115
+ gold test `test_constrainedlayout.py`. Only import or reference evidence
116
+ can find these.
117
+ - **The `name` arm.** Its list also holds files that are not tests, such
118
+ as baseline images below `tests/`. These files fill some of its first 5
119
+ places.
120
+
121
+ ## What this does not show
122
+
123
+ - The gold set holds the tests that the developers changed. Other
124
+ existing tests can also check the change. Recall is thus a lower bound,
125
+ and the study does not measure precision.
126
+ - The `name` arm is a strong baseline for this gold set. Developers often
127
+ change the test file that has the name of the source file.
128
+ - Stage 0 measures the tool output only. It does not show how an agent
129
+ uses that output.
130
+ - We now know the dev tasks. A ranking change that we tune on them needs
131
+ a check on tasks that we did not look at.
132
+
133
+ ## After the ranking change
134
+
135
+ The user approved these steps on 2026-10-11 (`studies/r4-addendum.md` in
136
+ the evals store). Because we used the dev results to make the change, the
137
+ holdout tasks decide. Each holdout task ran once, with the final version.
138
+
139
+ - **Change.** PR #164 at commit `381ece4`. `suggest_tests` finds tests by
140
+ name in the whole repository, and any folder that holds a top-level
141
+ Python package is an import root.
142
+ - **Setup.** The same script, arms and metric, on a new RunPod CPU pod
143
+ (128 CPUs). Dev and holdout ran at the same time, with 12 workers each.
144
+ The pod ran for about 0.5 hours and cost about USD 0.45.
145
+ - **Two record-only fields.** `product_detail` holds the priority of each
146
+ candidate. `name_v011` is the name grep with the test detector of 0.1.1.
147
+ The `name` arm uses the detector of the installed version, and #164 adds
148
+ .NET, C# and C/C++ test names to it.
149
+
150
+ | Set | Tasks | Failed | `product` R@5 | `name` R@5 | Δ | Range of Δ (95%) | `product` Hit@5 | `name` Hit@5 | Higher / lower | Rule met |
151
+ |---|---:|---:|---:|---:|---:|---|---:|---:|---:|---|
152
+ | Dev (tuning) | 123 | 1 | 0.694 | 0.481 | +0.213 | +0.139 to +0.286 | 0.740 | 0.520 | 33 / 1 | Yes |
153
+ | Holdout (decides) | 56 | 1 | 0.640 | 0.586 | +0.054 | -0.047 to +0.167 | 0.696 | 0.625 | 6 / 3 | No |
154
+
155
+ With the 0.1.1 detector, the name grep had 0.477 on dev and 0.580 on the
156
+ holdout. The Δ changes by less than 0.01. Each set has one task whose
157
+ patch does not apply at the base commit (dubbo-3317 and dubbo-4678).
158
+
159
+ **Reading.** On dev, `suggest_tests` improved on 21 tasks against the fix
160
+ view, and no task got worse. All 7 matplotlib tasks had no test before.
161
+ After the change, their Recall@5 is 0.50. On the holdout, the gain is
162
+ small, and the range includes 0. By the rule, this is no evidence that
163
+ the product names the tests for a change better than a file-name grep.
164
+ The name grep is strong on the holdout. Both arms had a Hit@5 on 33 of
165
+ 55 tasks, because the developers changed the test that has the name of
166
+ the source file.
167
+
168
+ **Holdout misses.** These are leads only. The holdout tasks cannot check
169
+ a fix for them.
170
+
171
+ - `suggest_tests` found no test on 8 tasks.
172
+ - In coreutils, the changed file is `src/uu/cp/src/cp.rs`. The name
173
+ finder skips names with fewer than 3 letters, so it did not find
174
+ `tests/by-util/test_cp.rs`.
175
+ - In grommet and decap-cms, the gold set holds a Jest snapshot file
176
+ (`.snap`). `suggest_tests` gives only test source files, and the name
177
+ grep also gives data files.
178
+
179
+ ## Next
180
+
181
+ 1. Merge #164 as a product change. Its claims are the numbers above, not
182
+ a measured gain on new tasks.
183
+ 2. No R4 agent runs. This also gives no new evidence for the cut of the
184
+ daily tool list.
185
+ 3. Any new test-ranking study needs new tasks, because we know the results
186
+ of all 179 tasks now.
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "attocode-code-intel"
9
- version = "0.1.1"
9
+ version = "0.1.3"
10
10
  description = "Local code search and navigation for coding agents and people"
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.12"
@@ -49,4 +49,4 @@ def __getattr__(name: str) -> Any:
49
49
  raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
50
50
 
51
51
  # The other copy is packages/code-intel/pyproject.toml. A test checks that both match.
52
- __version__ = "0.1.1"
52
+ __version__ = "0.1.3"
@@ -892,10 +892,10 @@ class ASTService:
892
892
  """Return all symbols defined in *path*."""
893
893
  self._ensure_initialized()
894
894
  rel = self._to_rel(path)
895
- qnames = self._index.file_symbols.get(rel, set())
896
895
  result: list[SymbolLocation] = []
897
- for qn in qnames:
898
- result.extend(self._index.definitions.get(qn, []))
896
+ with self._index._lock: # Background hydration adds to these sets.
897
+ for qn in self._index.file_symbols.get(rel, set()):
898
+ result.extend(self._index.definitions.get(qn, []))
899
899
  return result
900
900
 
901
901
  def find_symbol(self, name: str, *, include_shadowed: bool = False) -> list[SymbolLocation]:
@@ -366,28 +366,52 @@ def _build_file_index(
366
366
  normalized = f.relative_path.replace(os.sep, "/")
367
367
  file_index[normalized] = f.relative_path
368
368
 
369
- # Detect source prefixes and add stripped alternate keys. A package below
370
- # any src/ folder adds that folder too, as in packages/<name>/src/ of a monorepo.
371
- source_prefixes = set(_detect_source_prefixes(root_dir))
372
- for normalized in file_index:
373
- path = "/" + normalized
374
- if normalized.endswith("/__init__.py") and "/src/" in path:
375
- source_prefixes.add(path[1:path.index("/src/") + 5])
369
+ # Detect source prefixes and add stripped alternate keys.
370
+ source_prefixes = set(_detect_source_prefixes(root_dir)) | _python_import_roots(file_index)
376
371
  if source_prefixes:
377
- extra: dict[str, str] = {}
378
- for normalized, rel_path in file_index.items():
379
- for prefix in sorted(source_prefixes):
380
- if normalized.startswith(prefix):
381
- stripped = normalized[len(prefix):]
382
- # Don't override direct matches
383
- if stripped not in file_index:
384
- extra[stripped] = rel_path
385
- file_index.update(extra)
372
+ _add_root_keys(file_index, source_prefixes)
386
373
 
387
374
  file_index.configure_javascript(root_dir)
388
375
  return file_index
389
376
 
390
377
 
378
+ def _python_import_roots(paths) -> set[str]:
379
+ """Folders that hold a top-level Python package, as ``lib/`` for ``lib/pkg/__init__.py``.
380
+
381
+ Such a folder is an import root: src/, packages/<name>/src/ of a monorepo,
382
+ lib/ of matplotlib or python/ of ray.
383
+ """
384
+ roots: set[str] = set()
385
+ for path in paths:
386
+ package, _, name = path.rpartition("/")
387
+ parent = package.rpartition("/")[0]
388
+ if name == "__init__.py" and parent and parent + "/__init__.py" not in paths:
389
+ roots.add(parent + "/")
390
+ return roots
391
+
392
+
393
+ def _add_root_keys(file_index: dict[str, str], roots: set[str]) -> None:
394
+ """Add a key without the root prefix for each file below an import root."""
395
+ extra: dict[str, str] = {}
396
+ for normalized, rel_path in file_index.items():
397
+ parts = normalized.split("/")
398
+ # Shallow roots first, so a deeper root wins, as in sorted prefix order.
399
+ for depth in range(1, len(parts)):
400
+ prefix = "/".join(parts[:depth]) + "/"
401
+ stripped = normalized[len(prefix):]
402
+ # Don't override direct matches
403
+ if prefix in roots and stripped not in file_index:
404
+ extra[stripped] = rel_path
405
+ file_index.update(extra)
406
+
407
+
408
+ def python_module_index(paths) -> dict[str, str]:
409
+ """Module-path keys for ``_resolve_python_import`` from repository paths alone."""
410
+ file_index = {path: path for path in paths}
411
+ _add_root_keys(file_index, _python_import_roots(file_index))
412
+ return file_index
413
+
414
+
391
415
  def _resolve_python_import(module: str, source_file: str, file_index: dict[str, str]) -> str | None:
392
416
  """Resolve a Python import module name to a relative file path.
393
417
 
@@ -438,15 +438,17 @@ class CrossRefIndex:
438
438
 
439
439
  def get_definitions(self, symbol_name: str, *, include_shadowed: bool = False) -> list[SymbolLocation]:
440
440
  """Look up definitions for a symbol (exact or suffix match)."""
441
- # Try exact qualified name first
442
- if symbol_name in self.definitions and not include_shadowed:
443
- return self.definitions[symbol_name]
444
- # Try suffix match (e.g. "discover_files" matches "CodebaseContextManager.discover_files")
445
- results: list[SymbolLocation] = []
446
- for qname, locs in self.definitions.items():
447
- if qname == symbol_name or qname.endswith(f".{symbol_name}"):
448
- results.extend(locs)
449
- return results
441
+ # The lock keeps a background index writer from changing the dict during the scan.
442
+ with self._lock:
443
+ # Try exact qualified name first
444
+ if symbol_name in self.definitions and not include_shadowed:
445
+ return self.definitions[symbol_name]
446
+ # Try suffix match (e.g. "discover_files" matches "CodebaseContextManager.discover_files")
447
+ results: list[SymbolLocation] = []
448
+ for qname, locs in self.definitions.items():
449
+ if qname == symbol_name or qname.endswith(f".{symbol_name}"):
450
+ results.extend(locs)
451
+ return results
450
452
 
451
453
  def search_definitions(
452
454
  self,
@@ -455,7 +457,18 @@ class CrossRefIndex:
455
457
  limit: int = 50,
456
458
  kind_filter: str = "",
457
459
  ) -> list[tuple[SymbolLocation, float]]:
458
- """Multi-strategy symbol search returning (location, score) pairs.
460
+ """Multi-strategy symbol search returning (location, score) pairs."""
461
+ with self._lock:
462
+ return self._search_definitions_locked(symbol_name, limit=limit, kind_filter=kind_filter)
463
+
464
+ def _search_definitions_locked(
465
+ self,
466
+ symbol_name: str,
467
+ *,
468
+ limit: int,
469
+ kind_filter: str,
470
+ ) -> list[tuple[SymbolLocation, float]]:
471
+ """Search the definitions. The caller holds the lock.
459
472
 
460
473
  Search strategies (in priority order):
461
474
  1. Exact qualified name match (score 1.0)
@@ -536,9 +549,10 @@ class CrossRefIndex:
536
549
  # Include exact and qualified candidates; an exact key must not hide others.
537
550
  # Suffix match (e.g. "clear" matches refs keyed as "MCPMetaTools.clear")
538
551
  results: list[SymbolRef] = []
539
- for ref_name, refs in self.references.items():
540
- if ref_name == symbol_name or ref_name.endswith(f".{symbol_name}"):
541
- results.extend(refs)
552
+ with self._lock:
553
+ for ref_name, refs in self.references.items():
554
+ if ref_name == symbol_name or ref_name.endswith(f".{symbol_name}"):
555
+ results.extend(refs)
542
556
  return results
543
557
 
544
558
  def get_dependents(self, file_path: str) -> set[str]:
@@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
23
23
  SCHEMA_VERSION = "6"
24
24
  # Bump the suffix when a change alters the saved graph edges, for example import resolution.
25
25
  # Stores keep their tables, and the next start rebuilds the index once.
26
- SNAPSHOT_KEY = "structural_snapshot_v2"
26
+ SNAPSHOT_KEY = "structural_snapshot_v3"
27
27
  SQLITE_BUSY_TIMEOUT_MS = 30_000
28
28
  INDEX_INIT_LOCK_TIMEOUT_SECONDS = 30
29
29
 
@@ -340,6 +340,9 @@ class DbAnalysisProvider:
340
340
 
341
341
  from sqlalchemy import select
342
342
 
343
+ from attocode_intel._internal.integrations.context.codebase_context import (
344
+ python_module_index,
345
+ )
343
346
  from attocode_intel.db.models import FileContent
344
347
  from attocode_intel.indexing.full_indexer import _resolve_import_path
345
348
  from attocode_intel.indexing.parser import detect_language, extract_imports
@@ -347,6 +350,7 @@ class DbAnalysisProvider:
347
350
  logger = logging.getLogger(__name__)
348
351
  manifest = branch_ctx.manifest # path -> sha
349
352
  known_paths = set(manifest.keys())
353
+ python_index = python_module_index(known_paths)
350
354
  sha_to_path = {sha: path for path, sha in manifest.items()}
351
355
  content_shas = list(set(manifest.values()))
352
356
 
@@ -378,7 +382,8 @@ class DbAnalysisProvider:
378
382
  raw_content = content if isinstance(content, bytes) else content.encode("utf-8")
379
383
  imports = extract_imports(raw_content, source_path, language)
380
384
  for imp in imports:
381
- target = _resolve_import_path(imp, source_path, known_paths, language)
385
+ target = _resolve_import_path(imp, source_path, known_paths, language,
386
+ python_index=python_index)
382
387
  if target and target != source_path:
383
388
  edges.append({
384
389
  "source": source_path,
@@ -69,18 +69,23 @@ def _resolve_import_path(
69
69
  known_paths: set[str],
70
70
  language: str | None,
71
71
  aliases: dict[str, str] | None = None,
72
+ python_index: dict[str, str] | None = None,
72
73
  ) -> str | None:
73
74
  """Resolve an import string to a file path in the repo.
74
75
 
75
- Returns the matching path or None if unresolvable.
76
+ Returns the matching path or None if unresolvable. For Python, pass
77
+ ``python_index = python_module_index(known_paths)`` when resolving many imports.
76
78
  """
77
79
  from pathlib import PurePosixPath
78
80
 
79
81
  if language == "python":
80
- # foo.bar -> foo/bar.py or foo/bar/__init__.py
81
- parts = import_name.replace(".", "/")
82
- candidates = [f"{parts}.py", f"{parts}/__init__.py"]
83
- elif language in ("javascript", "typescript"):
82
+ # The resolver of the local index: relative imports and import roots such as src/ or lib/.
83
+ from attocode_intel._internal.integrations.context.codebase_context import (
84
+ _resolve_python_import,
85
+ python_module_index,
86
+ )
87
+ return _resolve_python_import(import_name, source_path, python_index or python_module_index(known_paths))
88
+ if language in ("javascript", "typescript"):
84
89
  if import_name.startswith("."):
85
90
  # Relative import — resolve against source dir
86
91
  source_dir = str(PurePosixPath(source_path).parent)
@@ -249,8 +254,13 @@ class FullIndexer:
249
254
  if overlay_updates:
250
255
  await overlay.set_files_batch(branch_id, overlay_updates)
251
256
 
257
+ from attocode_intel._internal.integrations.context.codebase_context import (
258
+ python_module_index,
259
+ )
260
+
252
261
  # Resolve path aliases from tsconfig/jsconfig
253
262
  aliases = _load_path_aliases(known_paths, config_contents)
263
+ python_index = python_module_index(known_paths)
254
264
 
255
265
  # Second pass: resolve imports to dependencies
256
266
  self._progress({"phase": "resolving_dependencies", "total": len(deferred_deps), "current": 0})
@@ -260,7 +270,8 @@ class FullIndexer:
260
270
  continue
261
271
  deps: list[dict] = []
262
272
  for imp in imports:
263
- target_path = _resolve_import_path(imp, source_path, known_paths, language, aliases=aliases)
273
+ target_path = _resolve_import_path(imp, source_path, known_paths, language, aliases=aliases,
274
+ python_index=python_index)
264
275
  if target_path and target_path in path_to_sha:
265
276
  deps.append({
266
277
  "target_sha": path_to_sha[target_path],
@@ -159,9 +159,15 @@ class IncrementalPipeline:
159
159
  for u_path, u_sha, _ in overlay_updates:
160
160
  path_to_sha[u_path] = u_sha
161
161
 
162
+ python_index = None
163
+ if language == "python":
164
+ from attocode_intel._internal.integrations.context.codebase_context import (
165
+ python_module_index,
166
+ )
167
+ python_index = python_module_index(known_paths)
162
168
  deps = []
163
169
  for imp in imports:
164
- target = _resolve_import_path(imp, path, known_paths, language)
170
+ target = _resolve_import_path(imp, path, known_paths, language, python_index=python_index)
165
171
  if target and target in path_to_sha:
166
172
  deps.append({
167
173
  "target_sha": path_to_sha[target],
@@ -1,6 +1,7 @@
1
1
  """Symbol-focused test evidence, reusing the parsed index instead of scanning file bodies."""
2
2
  from __future__ import annotations
3
3
 
4
+ import re
4
5
  from pathlib import PurePosixPath
5
6
 
6
7
  from attocode_intel.focused_evidence import task_terms, terms
@@ -10,8 +11,77 @@ def is_test_path(path):
10
11
  parts = PurePosixPath(path).parts
11
12
  name = parts[-1] if parts else ""
12
13
  return (any(p in {"test", "tests", "__tests__", "spec", "specs"} for p in parts)
14
+ # .NET test projects: UnitsNet.Tests/, Kavita.Services.Tests/
15
+ or any(p.endswith((".Tests", ".Test", ".UnitTests", ".IntegrationTests")) for p in parts[:-1])
13
16
  or name.startswith("test_") or ".test." in name or ".spec." in name
14
- or name.endswith(("_test.py", "_test.go", "Test.java", "Test.kt")))
17
+ or name.endswith(("_test.py", "_test.go", "Test.java", "Test.kt", "Tests.java", "Tests.kt",
18
+ "Test.cs", "Tests.cs", "_test.c", "_test.cc", "_test.cpp", "_unittest.cc")))
19
+
20
+
21
+ _TEST_PREFIX = re.compile(r"^(?:unit)?tests?[_-]|^Tests?(?=[A-Z])")
22
+ _TEST_SUFFIX = re.compile(r"(?:[_-](?:unit)?(?:tests?|spec)|Tests?|Spec)$")
23
+ # These names say little; the folder names the module (pkg/__init__.py, src/index.ts).
24
+ _GENERIC_STEMS = {"__init__", "index", "mod", "lib", "main"}
25
+
26
+
27
+ def _plain(name):
28
+ return name.lower().replace("_", "").replace("-", "")
29
+
30
+
31
+ def file_subject(path):
32
+ """The name that a test for this file would carry: lib/pkg/figure.py -> figure."""
33
+ p = PurePosixPath(path)
34
+ stem = p.name.split(".")[0]
35
+ if stem in _GENERIC_STEMS and p.parent.name:
36
+ stem = p.parent.name
37
+ return _plain(stem)
38
+
39
+
40
+ def test_subject(path):
41
+ """The name that a test file is for: test_figure.py, FigureTest.java, figure.test.ts -> figure.
42
+
43
+ None when the name has no test affix: a fixture or generated file in a test folder.
44
+ """
45
+ p = PurePosixPath(path)
46
+ stem = p.name.split(".")[0]
47
+ core = _TEST_SUFFIX.sub("", _TEST_PREFIX.sub("", stem))
48
+ if core == stem and ".test." not in p.name and ".spec." not in p.name and "__tests__" not in p.parts:
49
+ return None
50
+ return _plain(core)
51
+
52
+
53
+ def folder_overlap(path, other):
54
+ """The number of folder names that two paths share, in any position."""
55
+ return len(set(PurePosixPath(path).parent.parts) & set(PurePosixPath(other).parent.parts))
56
+
57
+
58
+ def name_matched_tests(changed_file, test_paths, limit=10):
59
+ """Test files named for ``changed_file``, best first, as (path, priority, reason).
60
+
61
+ Priority 1: the nearest tests whose name without the test affix is the file name, if
62
+ they share a folder name with it. Priority 3: the same name farther away. Priority 4: the test file name only
63
+ contains the file name, as a plain file-name search finds it. Nearest means the most
64
+ folder names in common, so src/test/java/org/x mirrors src/main/java/org/x.
65
+ """
66
+ subject = file_subject(changed_file)
67
+ if len(subject) < 2:
68
+ return []
69
+
70
+ def shared(path):
71
+ return folder_overlap(path, changed_file)
72
+
73
+ exact = [path for path in test_paths if test_subject(path) == subject]
74
+ named = set(exact)
75
+ # A short name is part of too many file names: cp.rs gets test_cp.rs, not every *cp* file.
76
+ loose = [path for path in test_paths if len(subject) >= 3 and path not in named
77
+ and subject in _plain(PurePosixPath(path).name)]
78
+ exact.sort(key=lambda path: (-shared(path), len(path), path))
79
+ loose.sort(key=lambda path: (-shared(path), len(path), path))
80
+ nearest = shared(exact[0]) if exact else 0
81
+ rows = [(path, 1 if nearest and shared(path) == nearest else 3, f"Test file named for `{changed_file}`")
82
+ for path in exact]
83
+ rows += [(path, 4, f"Test file name contains `{PurePosixPath(changed_file).stem}`") for path in loose]
84
+ return rows[:limit]
15
85
 
16
86
 
17
87
  def rank_symbol_tests(ast, suggestions, files, symbol_name, task_hint, distances,
@@ -123,6 +123,30 @@ def _find_test_files_by_convention(file_path: str, project_dir: str) -> list[str
123
123
  return existing
124
124
 
125
125
 
126
+ def _test_paths(project_dir: str) -> list[str]:
127
+ """Tracked test source files. The index can leave out tests of a large repository."""
128
+ from pathlib import PurePosixPath
129
+
130
+ from attocode_intel._internal.integrations.context.codebase_context import EXTENSION_LANGUAGES
131
+ from attocode_intel.test_ranking import is_test_path
132
+
133
+ try:
134
+ listed = subprocess.run(
135
+ ["git", "ls-files", "-z"],
136
+ cwd=project_dir, capture_output=True, text=True, timeout=30, check=True,
137
+ ).stdout.split("\0")
138
+ except (OSError, subprocess.SubprocessError):
139
+ listed = []
140
+ if not any(listed): # Not a git repository, or nothing tracked yet.
141
+ try:
142
+ listed = [f.relative_path for f in _get_context_mgr()._files]
143
+ except Exception:
144
+ return []
145
+ data = {"data", "yaml", "json", "toml", "markdown", "html", "css", "scss"}
146
+ return [path for path in listed if path
147
+ and EXTENSION_LANGUAGES.get(PurePosixPath(path).suffix, "data") not in data and is_test_path(path)]
148
+
149
+
126
150
  # ---------------------------------------------------------------------------
127
151
  # Tools
128
152
  # ---------------------------------------------------------------------------
@@ -429,6 +453,13 @@ def suggest_tests_data(files: list[str], *, symbol_name: str | None = None,
429
453
  reason=f"Direct test file for `{f}`",
430
454
  )
431
455
 
456
+ # Test files named for a changed file, anywhere in the repository.
457
+ from attocode_intel.test_ranking import folder_overlap, name_matched_tests
458
+ test_paths = _test_paths(project_dir)
459
+ for f in files:
460
+ for test_file, priority, reason in name_matched_tests(f, test_paths):
461
+ _add_suggestion(test_file, priority, reason)
462
+
432
463
  # --- Priority 2: Import-based discovery ---
433
464
  try:
434
465
  ctx = _get_context_mgr()
@@ -558,10 +589,14 @@ def suggest_tests_data(files: list[str], *, symbol_name: str | None = None,
558
589
  except (AttributeError, OSError) as exc:
559
590
  logger.debug("Test reference ranking incomplete: %s", exc)
560
591
 
561
- # Sort by evidence, then put repository tests before documentation examples.
592
+ # Sort by evidence, then put repository tests before documentation examples, then nearest first.
593
+ def nearness(path):
594
+ return max(folder_overlap(path, changed) for changed in files) if files else 0
595
+
562
596
  sorted_suggestions = sorted(
563
597
  suggestions.items(),
564
- key=lambda kv: (kv[1]["priority"], kv[0] not in representatives, -symbol_hits.get(kv[0], 0), kv[0].startswith("docs"), kv[0]),
598
+ key=lambda kv: (kv[1]["priority"], kv[0] not in representatives, -symbol_hits.get(kv[0], 0),
599
+ kv[0].startswith("docs"), -nearness(kv[0]), kv[0]),
565
600
  )
566
601
 
567
602
  return {"files": files, "candidates": [
@@ -598,6 +633,7 @@ def format_test_suggestions(data: dict) -> str:
598
633
  1: "DIRECT",
599
634
  2: "IMPORTS",
600
635
  3: "INDIRECT",
636
+ 4: "NAME",
601
637
  }
602
638
 
603
639
  lines = [