codegraph-brain 0.23.3__tar.gz → 0.23.4__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 (371) hide show
  1. codegraph_brain-0.23.4/.github/test-count-baseline +1 -0
  2. codegraph_brain-0.23.4/.release-please-manifest.json +3 -0
  3. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/CHANGELOG.md +12 -0
  4. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/PKG-INFO +1 -1
  5. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/how-to/CLI_USAGE.md +17 -8
  6. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/how-to/MCP_REFERENCE.md +21 -10
  7. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/plugin/skills/cgis/SKILL.md +1 -1
  8. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/pyproject.toml +1 -1
  9. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/check_pytest_raises.py +0 -1
  10. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/server.json +2 -2
  11. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/api/mcp_server.py +63 -18
  12. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/python_extractor.py +48 -33
  13. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/storage/sqlite_store.py +18 -10
  14. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_martian_script.py +4 -1
  15. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_mcp_server.py +174 -0
  16. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_python_extractor.py +14 -0
  17. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/uv.lock +1 -1
  18. codegraph_brain-0.23.3/.github/test-count-baseline +0 -1
  19. codegraph_brain-0.23.3/.release-please-manifest.json +0 -3
  20. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.claude-plugin/marketplace.json +0 -0
  21. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.gitattributes +0 -0
  22. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.github/workflows/autodoc.yml +0 -0
  23. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.github/workflows/ci.yml +0 -0
  24. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.github/workflows/guardian.yml +0 -0
  25. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.github/workflows/mcp-registry.yml +0 -0
  26. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.github/workflows/pr-title.yml +0 -0
  27. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.github/workflows/release-please.yml +0 -0
  28. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.gitignore +0 -0
  29. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.pre-commit-config.yaml +0 -0
  30. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/.python-version +0 -0
  31. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/CLAUDE.md +0 -0
  32. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/CONTRIBUTING.md +0 -0
  33. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/LICENSE +0 -0
  34. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/Makefile +0 -0
  35. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/PRIVACY.md +0 -0
  36. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/README.md +0 -0
  37. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/CURATION.md +0 -0
  38. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/calibration.jsonl +0 -0
  39. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/246-cross-vendor/README.md +0 -0
  40. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/246-cross-vendor/free-nemotron-quota-cutoff.jsonl +0 -0
  41. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/401-evidence/README.md +0 -0
  42. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/401-evidence/pr-399-control-rows.jsonl +0 -0
  43. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/401-evidence/pr-399-recording.json +0 -0
  44. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/401-evidence/pr-399-treatment-rows.jsonl +0 -0
  45. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/407-no-checker-appeal/README.md +0 -0
  46. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-directive-rows.jsonl +0 -0
  47. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-prohibition-rows.jsonl +0 -0
  48. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-122.yaml +0 -0
  49. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-140.yaml +0 -0
  50. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-141.yaml +0 -0
  51. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-142.yaml +0 -0
  52. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-143.yaml +0 -0
  53. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-144.yaml +0 -0
  54. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-278.yaml +0 -0
  55. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/pr-313.yaml +0 -0
  56. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/guardian/results.jsonl +0 -0
  57. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian/README.md +0 -0
  58. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian/cal_dot_com.json +0 -0
  59. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian/discourse.json +0 -0
  60. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian/grafana.json +0 -0
  61. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian/keycloak.json +0 -0
  62. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian/sentry.json +0 -0
  63. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-judged.jsonl +0 -0
  64. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-p3-judged-run1.jsonl +0 -0
  65. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-p3-judged-run1.jsonl.corrupted-backup +0 -0
  66. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-p3-run1.jsonl +0 -0
  67. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-p3-run2.jsonl +0 -0
  68. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-p3-run3.jsonl +0 -0
  69. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-plan.json +0 -0
  70. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-repeat-judged.jsonl +0 -0
  71. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-repeat-reviews.jsonl +0 -0
  72. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/benchmarks/martian-reviews.jsonl +0 -0
  73. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/data/.gitkeep +0 -0
  74. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/AUDIT.md +0 -0
  75. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/CASE_STUDY.md +0 -0
  76. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/GUARDIAN_LOCAL_BENCH.md +0 -0
  77. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/GUARDIAN_REMOTE_OLLAMA.md +0 -0
  78. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/architecture/HOW_IT_WORKS.md +0 -0
  79. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/architecture/ONTOLOGY.md +0 -0
  80. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/architecture/PATTERNS_AND_TRIADS.md +0 -0
  81. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/architecture/SELF_PORTRAIT.md +0 -0
  82. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/architecture/diagrams/pipeline_flow.mermaid +0 -0
  83. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/architecture/health_badge.json +0 -0
  84. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/assets/.gitignore +0 -0
  85. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/assets/cgis-app-avatar.png +0 -0
  86. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/assets/cgis-app-avatar.svg +0 -0
  87. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/assets/generate_avatar.py +0 -0
  88. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/examples/.gitkeep +0 -0
  89. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/how-to/AGENT_ONBOARDING.md +0 -0
  90. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/lab-notes/2026-06-11-chunked-review-negative-result.md +0 -0
  91. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/ontology/.gitkeep +0 -0
  92. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/ontology/core.yaml +0 -0
  93. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/ontology/domains.yaml +0 -0
  94. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/ontology/patterns.yaml +0 -0
  95. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/ontology/tolerances.lock +0 -0
  96. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/plans/2026-09-09-graph-freshness.md +0 -0
  97. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-09-domain-pattern-fingerprint-design.md +0 -0
  98. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-09-pattern-alphabet-motif-basis-design.md +0 -0
  99. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-10-guardian-sprint-design.md +0 -0
  100. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-11-fastapi-di-edges-design.md +0 -0
  101. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-11-guardian-chunked-review-design.md +0 -0
  102. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-11-guardian-chunker-design.md +0 -0
  103. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-11-mcp-drift-validate-fqn-design.md +0 -0
  104. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-11-resolver-split-design.md +0 -0
  105. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-11-symbol-import-edges-design.md +0 -0
  106. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-12-drift-empty-domains-design.md +0 -0
  107. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-12-gate-semantics-design.md +0 -0
  108. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-12-init-ontology-design.md +0 -0
  109. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-12-release-please-ci-design.md +0 -0
  110. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-13-suggest-packages-design.md +0 -0
  111. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-06-13-tangle-anti-pattern-design.md +0 -0
  112. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-29-guardian-skeptic-scoring-design.md +0 -0
  113. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-cgis-fractal-design.md +0 -0
  114. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-cgis-fractal-plan.md +0 -0
  115. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-chunk-source-filter-design.md +0 -0
  116. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-chunk-source-filter-plan.md +0 -0
  117. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-genai-client-close-design.md +0 -0
  118. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-genai-client-close-plan.md +0 -0
  119. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-guardian-precision-bench-design.md +0 -0
  120. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-guardian-precision-bench-plan.md +0 -0
  121. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-guardian-timeout-retry-design.md +0 -0
  122. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-30-guardian-timeout-retry-plan.md +0 -0
  123. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-07-31-finder-bug-class-taxonomy.md +0 -0
  124. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-08-01-aura-autoevolution-poc.md +0 -0
  125. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-08-11-guardian-code-review-bench.md +0 -0
  126. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-08-14-review-fingerprint-design.md +0 -0
  127. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-09-05-annotation-graph-design.md +0 -0
  128. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/2026-09-09-graph-freshness-design.md +0 -0
  129. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/BLUEPRINT.md +0 -0
  130. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/PRD.md +0 -0
  131. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/TDD.md +0 -0
  132. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-09-fingerprint-drift.md +0 -0
  133. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-10-guardian-context-skeptic-inline.md +0 -0
  134. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-10-guardian-structured-findings-bench.md +0 -0
  135. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-10-motif-basis-part-b.md +0 -0
  136. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-10-unified-pattern-alphabet.md +0 -0
  137. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-11-fastapi-di-edges.md +0 -0
  138. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-11-guardian-chunked-review.md +0 -0
  139. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-11-guardian-chunker.md +0 -0
  140. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-11-mcp-drift-validate-fqn.md +0 -0
  141. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-11-resolver-split.md +0 -0
  142. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-12-drift-empty-domains.md +0 -0
  143. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-12-gate-semantics.md +0 -0
  144. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-12-init-ontology.md +0 -0
  145. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-12-release-please-ci.md +0 -0
  146. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-12-symbol-import-edges.md +0 -0
  147. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-06-13-suggest-packages.md +0 -0
  148. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-07-29-guardian-skeptic-scoring.md +0 -0
  149. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-08-14-review-fingerprint.md +0 -0
  150. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-09-05-annotation-graph-pr1.md +0 -0
  151. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/docs/specs/plans/2026-09-05-annotation-graph-pr2.md +0 -0
  152. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/glama.json +0 -0
  153. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/main.py +0 -0
  154. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/plugin/.claude-plugin/plugin.json +0 -0
  155. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/plugin/.mcp.json +0 -0
  156. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/plugin/README.md +0 -0
  157. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/plugin/skills/ingest/SKILL.md +0 -0
  158. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/release-please-config.json +0 -0
  159. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/backfill_calibration_fingerprint.py +0 -0
  160. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/backfill_review_fingerprint.py +0 -0
  161. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/check_test_count.py +0 -0
  162. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/colab_bench.sh +0 -0
  163. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/gen_ideal_graph.py +0 -0
  164. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/generate_health.py +0 -0
  165. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/generate_mcp_ref.py +0 -0
  166. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/generate_schema_docs.py +0 -0
  167. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/guardian_bench.py +0 -0
  168. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/guardian_calibrate.py +0 -0
  169. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/guardian_martian.py +0 -0
  170. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/guardian_replay_skeptic.py +0 -0
  171. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/guardian_review.py +0 -0
  172. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/inject_architecture_graph.py +0 -0
  173. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/mcp_registry_gate.sh +0 -0
  174. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/ollama_visitor.sh +0 -0
  175. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/probe_closure_gap.py +0 -0
  176. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/probe_tier_ladder.py +0 -0
  177. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/recordings_from_corpus.py +0 -0
  178. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/scripts/skeptic_arms.py +0 -0
  179. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/__init__.py +0 -0
  180. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/__main__.py +0 -0
  181. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/api/.gitkeep +0 -0
  182. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/api/__init__.py +0 -0
  183. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/cli.py +0 -0
  184. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/core/.gitkeep +0 -0
  185. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/core/coverage.py +0 -0
  186. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/core/freshness.py +0 -0
  187. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/core/generated.py +0 -0
  188. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/core/js_globals.py +0 -0
  189. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/core/models.py +0 -0
  190. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/core/paths.py +0 -0
  191. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/.gitkeep +0 -0
  192. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/_python_annotations.py +0 -0
  193. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/_python_ast.py +0 -0
  194. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/_python_classes.py +0 -0
  195. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/_python_functions.py +0 -0
  196. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/_python_imports.py +0 -0
  197. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/_python_types.py +0 -0
  198. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/_typescript_bindings.py +0 -0
  199. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/base.py +0 -0
  200. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/registry.py +0 -0
  201. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/extractors/typescript_extractor.py +0 -0
  202. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/__init__.py +0 -0
  203. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/axes.py +0 -0
  204. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/bench.py +0 -0
  205. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/calibrate.py +0 -0
  206. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/chunked.py +0 -0
  207. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/chunker.py +0 -0
  208. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/collector.py +0 -0
  209. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/core.py +0 -0
  210. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/diff_index.py +0 -0
  211. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/evidence.py +0 -0
  212. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/findings.py +0 -0
  213. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/github_poster.py +0 -0
  214. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/martian.py +0 -0
  215. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/metrics.py +0 -0
  216. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/prompts.py +0 -0
  217. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/providers/__init__.py +0 -0
  218. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/providers/base.py +0 -0
  219. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/providers/gemini.py +0 -0
  220. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/providers/mistral.py +0 -0
  221. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/providers/ollama.py +0 -0
  222. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/providers/openrouter.py +0 -0
  223. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/recording.py +0 -0
  224. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/render.py +0 -0
  225. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/review_fingerprint.py +0 -0
  226. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/runner.py +0 -0
  227. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/guardian/skeptic.py +0 -0
  228. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/pipeline.py +0 -0
  229. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/py.typed +0 -0
  230. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/analysis/__init__.py +0 -0
  231. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/analysis/analyzer.py +0 -0
  232. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/analysis/anomaly.py +0 -0
  233. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/analysis/cohesion.py +0 -0
  234. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/analysis/health.py +0 -0
  235. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/analysis/suggest_service.py +0 -0
  236. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/context/__init__.py +0 -0
  237. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/context/audit.py +0 -0
  238. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/context/context_service.py +0 -0
  239. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/context/orphans.py +0 -0
  240. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/context/prompt.py +0 -0
  241. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/context/snippet.py +0 -0
  242. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/__init__.py +0 -0
  243. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/_scc.py +0 -0
  244. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/drift.py +0 -0
  245. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/drift_service.py +0 -0
  246. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/fingerprint.py +0 -0
  247. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/fractal.py +0 -0
  248. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/ontology_init.py +0 -0
  249. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/quotient.py +0 -0
  250. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/drift/triads.py +0 -0
  251. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/engine.py +0 -0
  252. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/fqn.py +0 -0
  253. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/render/__init__.py +0 -0
  254. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/render/graph_json.py +0 -0
  255. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/render/mermaid.py +0 -0
  256. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/query/render/metrics.py +0 -0
  257. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/resolver/.gitkeep +0 -0
  258. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/resolver/__init__.py +0 -0
  259. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/resolver/engine.py +0 -0
  260. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/resolver/indices.py +0 -0
  261. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/resolver/js_builtins.py +0 -0
  262. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/resolver/symbols.py +0 -0
  263. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/resolver/uplift.py +0 -0
  264. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/src/cgis/storage/.gitkeep +0 -0
  265. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/integration/.gitkeep +0 -0
  266. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/.gitkeep +0 -0
  267. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/__init__.py +0 -0
  268. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/conftest.py +0 -0
  269. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_annotation_calibration.py +0 -0
  270. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_architecture.py +0 -0
  271. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_drift.py +0 -0
  272. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_fractal.py +0 -0
  273. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_init_ontology_roundtrip.py +0 -0
  274. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_receiver_resolution.py +0 -0
  275. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_self_parse.py +0 -0
  276. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_self_parse_ts.py +0 -0
  277. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/self_parsing/test_suggest.py +0 -0
  278. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/.gitkeep +0 -0
  279. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/conftest.py +0 -0
  280. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/guardian_stubs.py +0 -0
  281. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/review_path_inventory.txt +0 -0
  282. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test___main__.py +0 -0
  283. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_analyzer.py +0 -0
  284. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_annotation_edges.py +0 -0
  285. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_audit.py +0 -0
  286. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_backfill_calibration_fingerprint.py +0 -0
  287. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_backfill_review_fingerprint.py +0 -0
  288. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_check_pytest_raises.py +0 -0
  289. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_check_test_count.py +0 -0
  290. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_cli.py +0 -0
  291. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_cohesion.py +0 -0
  292. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_context_service.py +0 -0
  293. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_di_acceptance.py +0 -0
  294. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_drift.py +0 -0
  295. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_drift_service.py +0 -0
  296. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_extractor_registry.py +0 -0
  297. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_fingerprint.py +0 -0
  298. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_fqn.py +0 -0
  299. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_fractal.py +0 -0
  300. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_freshness.py +0 -0
  301. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_gen_ideal_graph.py +0 -0
  302. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_generate_mcp_ref.py +0 -0
  303. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_generated.py +0 -0
  304. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_graph_json.py +0 -0
  305. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_axes.py +0 -0
  306. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_bench.py +0 -0
  307. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_bench_script.py +0 -0
  308. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_calibrate.py +0 -0
  309. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_calibrate_script.py +0 -0
  310. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_chunked.py +0 -0
  311. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_chunker.py +0 -0
  312. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_collector.py +0 -0
  313. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_core.py +0 -0
  314. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_diff_index.py +0 -0
  315. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_evidence.py +0 -0
  316. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_findings.py +0 -0
  317. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_martian.py +0 -0
  318. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_martian_union.py +0 -0
  319. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_metrics.py +0 -0
  320. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_mistral_sampling.py +0 -0
  321. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_ollama_sampling.py +0 -0
  322. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_ollama_truncation.py +0 -0
  323. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_openrouter.py +0 -0
  324. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_poster.py +0 -0
  325. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_providers.py +0 -0
  326. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_providers_name.py +0 -0
  327. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_recording.py +0 -0
  328. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_render.py +0 -0
  329. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_replay_skeptic.py +0 -0
  330. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_review_script.py +0 -0
  331. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_runner.py +0 -0
  332. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_salvage.py +0 -0
  333. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_guardian_skeptic.py +0 -0
  334. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_health_scorer.py +0 -0
  335. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_import_acceptance.py +0 -0
  336. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_inject_architecture_graph.py +0 -0
  337. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_mcp_tool_schemas.py +0 -0
  338. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_mermaid.py +0 -0
  339. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_metrics.py +0 -0
  340. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_models.py +0 -0
  341. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_name_load_positions.py +0 -0
  342. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_ontology_compliance.py +0 -0
  343. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_ontology_init.py +0 -0
  344. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_orphans.py +0 -0
  345. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_paths.py +0 -0
  346. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_patterns_yaml.py +0 -0
  347. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_pipeline.py +0 -0
  348. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_pipeline_incremental_symbols.py +0 -0
  349. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_prompt.py +0 -0
  350. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_python_annotations.py +0 -0
  351. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_query_coverage.py +0 -0
  352. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_quotient.py +0 -0
  353. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_recordings_from_corpus.py +0 -0
  354. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_resolver.py +0 -0
  355. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_resolver_indices.py +0 -0
  356. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_resolver_js_builtins.py +0 -0
  357. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_resolver_language_scope.py +0 -0
  358. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_resolver_symbols.py +0 -0
  359. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_review_fingerprint_closure.py +0 -0
  360. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_review_fingerprint_contract.py +0 -0
  361. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_review_fingerprint_digest.py +0 -0
  362. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_review_fingerprint_record.py +0 -0
  363. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_self_types.py +0 -0
  364. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_skeptic_arms.py +0 -0
  365. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_snippet.py +0 -0
  366. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_sqlite_store.py +0 -0
  367. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_suggest_service.py +0 -0
  368. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_temperature_source.py +0 -0
  369. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_triads.py +0 -0
  370. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_typescript_extractor.py +0 -0
  371. {codegraph_brain-0.23.3 → codegraph_brain-0.23.4}/tests/unit/test_uplift.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.23.4"
3
+ }
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.23.4](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.3...codegraph-brain-v0.23.4) (2026-09-17)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **mcp:** trace_flow/analyze_impact default to the CLI's view ([#482](https://github.com/zaebee/codegraph-brain/issues/482)) ([8877051](https://github.com/zaebee/codegraph-brain/commit/8877051d9b6f90e6df2a25480c3f608cdacb5f58))
9
+
10
+
11
+ ### Documentation
12
+
13
+ * auto-sync architecture graph and MCP reference ([#484](https://github.com/zaebee/codegraph-brain/issues/484)) ([2f507b0](https://github.com/zaebee/codegraph-brain/commit/2f507b004c232dae3d90577f73d763f4d27be357))
14
+
3
15
  ## [0.23.3](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.2...codegraph-brain-v0.23.3) (2026-09-17)
4
16
 
5
17
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codegraph-brain
3
- Version: 0.23.3
3
+ Version: 0.23.4
4
4
  Summary: Semantic code graph for AI agents — deterministic FQN resolution, impact analysis and architectural drift gates, exposed over MCP.
5
5
  Project-URL: Homepage, https://github.com/zaebee/codegraph-brain
6
6
  Project-URL: Repository, https://github.com/zaebee/codegraph-brain
@@ -47,7 +47,7 @@ cgis ingest ./src --output graph.json
47
47
 
48
48
  ### `cgis trace`
49
49
 
50
- Trace the execution call-graph **downstream** from a starting FQN.
50
+ Everything a FQN reaches **downstream**: every edge except containment, which in practice means calls, imports, inheritance, DI dependencies and references between internal code. Containment stays out unless `--show-structure` adds it, and so do stdlib, third-party and unresolved call targets unless `--show-external` does. The MCP tool `cgis_trace_flow` uses the same defaults (`include_structure`, `include_external`).
51
51
 
52
52
  ```bash
53
53
  cgis trace <fqn> [OPTIONS]
@@ -57,24 +57,30 @@ cgis trace <fqn> [OPTIONS]
57
57
  | :--- | :--- | :--- |
58
58
  | `--db`, `-d` | `graph.db` | Path to the graph database |
59
59
  | `--depth` | `5` | Maximum traversal depth |
60
- | `--format`, `-f` | `text` | Output format: `text` or `mermaid` |
61
- | `--internal-only` | `False` | Exclude external library nodes |
60
+ | `--format`, `-f` | `text` | `text`, `mermaid`, or `json` (joinable `{root, nodes, edges, coverage}`) |
61
+ | `--show-structure` | off | Also follow containment (CONTAINS/DECLARES) |
62
+ | `--show-external` | off | Also show stdlib, third-party and unresolved call targets |
63
+ | `--internal-only` | off | Drop those nodes again from `mermaid`/`json` output; a no-op unless `--show-external` is on, and not valid with `text` |
64
+ | `--min-confidence` | none | Hide edges below this confidence. Resolved calls score 1.0 and inferred ones 0.8, so a threshold above 0.8 is what filters anything |
62
65
 
63
66
  **Examples:**
64
67
 
65
68
  ```bash
66
- # Text tree of what IngestionPipeline.run calls
69
+ # Text tree of what IngestionPipeline.run depends on
67
70
  cgis trace "cgis.pipeline.IngestionPipeline.run" --depth 3
68
71
 
69
72
  # Mermaid diagram for pasting into docs
70
73
  cgis trace "cgis.pipeline.IngestionPipeline.run" --format mermaid
74
+
75
+ # Machine-readable, with the module's own members included
76
+ cgis trace "cgis.query.engine" --format json --show-structure
71
77
  ```
72
78
 
73
79
  ---
74
80
 
75
81
  ### `cgis impact`
76
82
 
77
- Trace **upstream** callers — who depends on this FQN?
83
+ Everything that reaches a FQN **upstream**: callers, importers, subclasses, type references and DI dependents. The enclosing class or file stays out unless `--show-structure` adds it, and so do stdlib, third-party and unresolved call targets unless `--show-external` does. The MCP tool `cgis_analyze_impact` uses the same defaults.
78
84
 
79
85
  ```bash
80
86
  cgis impact <fqn> [OPTIONS]
@@ -84,13 +90,16 @@ cgis impact <fqn> [OPTIONS]
84
90
  | :--- | :--- | :--- |
85
91
  | `--db`, `-d` | `graph.db` | Path to the graph database |
86
92
  | `--depth` | `5` | Maximum traversal depth |
87
- | `--format`, `-f` | `text` | Output format: `text` or `mermaid` |
88
- | `--internal-only` | `False` | Exclude external library nodes |
93
+ | `--format`, `-f` | `text` | `text`, `mermaid`, or `json` (joinable `{root, nodes, edges, coverage}`) |
94
+ | `--show-structure` | off | Also follow containment (CONTAINS/DECLARES) |
95
+ | `--show-external` | off | Also show stdlib, third-party and unresolved call targets |
96
+ | `--internal-only` | off | Drop those nodes again from `mermaid`/`json` output; a no-op unless `--show-external` is on, and not valid with `text` |
97
+ | `--min-confidence` | none | Hide edges below this confidence. Resolved calls score 1.0 and inferred ones 0.8, so a threshold above 0.8 is what filters anything |
89
98
 
90
99
  **Examples:**
91
100
 
92
101
  ```bash
93
- # Who calls SQLiteStore.save_graph?
102
+ # What depends on SQLiteStore.save_graph?
94
103
  cgis impact "cgis.storage.sqlite_store.SQLiteStore.save_graph"
95
104
 
96
105
  # Blast radius of changing the Node model
@@ -9,9 +9,12 @@
9
9
 
10
10
  Upstream subgraph of one FQN: everything that reaches it within ``depth`` hops.
11
11
 
12
- Every edge type counts — callers, but also importers, subclasses, type
13
- references, DI dependents and the enclosing class or file — so this answers
14
- "what breaks if I change X?". For what X depends on use
12
+ Follows every edge except containment — in practice callers, importers,
13
+ subclasses, type references and DI dependents — within internal code, so this
14
+ answers "what breaks if I change X?". The
15
+ enclosing class or file and stdlib/third-party nodes are left out unless
16
+ ``include_structure`` / ``include_external`` ask for them — the same view as
17
+ the CLI's ``impact``. For what X depends on use
15
18
  ``cgis_trace_flow``; for only the members of a module or class,
16
19
  ``cgis_get_structure``; for a source-included brief to read before editing
17
20
  one symbol, ``cgis_context``.
@@ -29,8 +32,10 @@ Upstream subgraph of one FQN: everything that reaches it within ``depth`` hops.
29
32
  | :--- | :--- | :---: | :--- |
30
33
  | `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
31
34
  | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
32
- | `depth` | `integer` | | Maximum edge hops upstream. Every edge type counts as a hop — callers, importers, subclasses, type references, DI dependents and the enclosing class or file all appear alongside each other. |
35
+ | `depth` | `integer` | | Maximum edge hops upstream, over callers, importers, subclasses, type references and DI dependents (plus the enclosing class or file with include_structure). |
33
36
  | `output_format` | `string` | | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. |
37
+ | `include_structure` | `boolean` | | Also follow containment (CONTAINS/DECLARES): a module's or class's own members, and the class or file enclosing a symbol. Off by default, as in the CLI; cgis_get_structure is the tool for members alone. |
38
+ | `include_external` | `boolean` | | Also return stdlib, third-party and unresolved call targets — calls on values whose type is decided at runtime. Off by default, as in the CLI, because they dominate the payload; in json, coverage/top_unresolved still counts what was dropped. |
34
39
 
35
40
  ---
36
41
 
@@ -69,7 +74,8 @@ Prompt-ready brief on one FQN: its source, class, direct callers and callees.
69
74
  calls only, one hop by default. Source is included when the file is found
70
75
  (see ``source_root``), and the domain when the graph was tagged with one.
71
76
  For a multi-hop subgraph
72
- over every edge type without source, use ``cgis_trace_flow`` (downstream) or
77
+ over calls, imports, inheritance and references without source, use
78
+ ``cgis_trace_flow`` (downstream) or
73
79
  ``cgis_analyze_impact`` (upstream).
74
80
 
75
81
  Returns an XML-tagged prompt — the focal node's source, its enclosing class,
@@ -350,10 +356,13 @@ Suggest sub-package boundaries for a package from its dependency communities.
350
356
 
351
357
  Downstream subgraph of one FQN: everything it reaches within ``depth`` hops.
352
358
 
353
- Every edge type counts — calls, imports, inheritance, DI dependencies,
354
- references, and containment (so from a module or class the first hop includes
355
- its own members) — so this answers "what does X depend on?". For what depends
356
- on X use
359
+ Follows every edge except containment — in practice calls, imports,
360
+ inheritance, DI dependencies and references — between internal code, so this
361
+ answers "what does X depend on?". Containment and
362
+ stdlib/third-party nodes are left out unless ``include_structure`` /
363
+ ``include_external`` ask for them (external covers stdlib, third-party and
364
+ unresolved call targets) — the same view as the CLI's ``trace``.
365
+ For what depends on X use
357
366
  ``cgis_analyze_impact``; for only the members of a module or class,
358
367
  ``cgis_get_structure``; for a source-included brief to read before editing
359
368
  one symbol, ``cgis_context``.
@@ -371,8 +380,10 @@ Downstream subgraph of one FQN: everything it reaches within ``depth`` hops.
371
380
  | :--- | :--- | :---: | :--- |
372
381
  | `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
373
382
  | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
374
- | `depth` | `integer` | | Maximum edge hops downstream. Every edge type counts as a hop — calls, imports, inheritance, DI dependencies, references and containment — so from a module or class the first hop is mostly its own members and imports. |
383
+ | `depth` | `integer` | | Maximum edge hops downstream, over calls, imports, inheritance, DI dependencies and references (plus containment with include_structure). |
375
384
  | `output_format` | `string` | | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. |
385
+ | `include_structure` | `boolean` | | Also follow containment (CONTAINS/DECLARES): a module's or class's own members, and the class or file enclosing a symbol. Off by default, as in the CLI; cgis_get_structure is the tool for members alone. |
386
+ | `include_external` | `boolean` | | Also return stdlib, third-party and unresolved call targets — calls on values whose type is decided at runtime. Off by default, as in the CLI, because they dominate the payload; in json, coverage/top_unresolved still counts what was dropped. |
376
387
 
377
388
  ---
378
389
 
@@ -21,7 +21,7 @@ Reading files to answer a structural question is the slow, lossy path: it burns
21
21
  | "Did this change drift the architecture?" | `cgis_drift` | nothing — there is no manual equivalent |
22
22
  | "Does every handler reach its authz guard?" | `cgis_audit_reachability` | auditing routes one by one |
23
23
 
24
- A subgraph at depth 2 costs a few hundred tokens. The equivalent in file chunks costs thousands and is less precise.
24
+ A depth-2 trace or impact of a function or method costs a few hundred tokens: median about 300, and 9 in 10 under 1,600. Measured over every function and method of two real graphs (700 and 5,800 symbols), in the default mermaid format and in json. The equivalent in file chunks costs thousands and is less precise. A module or a heavily used symbol costs more — the worst symbol on the larger graph returns 36k tokens, so raise `depth` deliberately and prefer `cgis_context` for a single symbol. Containment, stdlib/third-party nodes and unresolved call targets are off by default; `include_structure` and `include_external` add them when that is the question.
25
25
 
26
26
  ## First run in a repository
27
27
 
@@ -7,7 +7,7 @@ packages = ["src/cgis"]
7
7
 
8
8
  [project]
9
9
  name = "codegraph-brain"
10
- version = "0.23.3"
10
+ version = "0.23.4"
11
11
  description = "Semantic code graph for AI agents — deterministic FQN resolution, impact analysis and architectural drift gates, exposed over MCP."
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.12"
@@ -54,7 +54,6 @@ GRANDFATHERED: frozenset[str] = frozenset(
54
54
  "unit/test_drift_service.py::test_analyze_drift_bad_suffix_raises",
55
55
  "unit/test_drift_service.py::test_analyze_drift_missing_db_raises",
56
56
  "unit/test_drift_service.py::test_analyze_drift_missing_patterns_raises",
57
- "unit/test_guardian_martian_script.py::test_a_missing_concurrency_raises_instead_of_defaulting",
58
57
  "unit/test_guardian_recording.py::test_a_non_json_path_is_rejected",
59
58
  "unit/test_metrics.py::test_missing_database_raises_file_not_found",
60
59
  "unit/test_ontology_init.py::test_propose_missing_db_raises",
@@ -8,13 +8,13 @@
8
8
  "source": "github",
9
9
  "id": "1260843154"
10
10
  },
11
- "version": "0.23.3",
11
+ "version": "0.23.4",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "pypi",
15
15
  "registryBaseUrl": "https://pypi.org",
16
16
  "identifier": "codegraph-brain",
17
- "version": "0.23.3",
17
+ "version": "0.23.4",
18
18
  "runtimeHint": "uvx",
19
19
  "transport": {
20
20
  "type": "stdio"
@@ -17,7 +17,7 @@ from pydantic import Field
17
17
  from cgis import __version__
18
18
  from cgis.core.coverage import TraversalCoverage
19
19
  from cgis.core.freshness import Freshness, FreshnessState
20
- from cgis.core.models import Edge, Node, NodeType
20
+ from cgis.core.models import Edge, EdgeType, Node, NodeType
21
21
  from cgis.extractors.python_extractor import PythonExtractor
22
22
  from cgis.extractors.typescript_extractor import TypeScriptExtractor
23
23
  from cgis.pipeline import IngestionPipeline
@@ -28,7 +28,7 @@ from cgis.query.context.orphans import find_orphan_classes
28
28
  from cgis.query.drift.drift_service import analyze_drift
29
29
  from cgis.query.drift.fractal import analyze_fractal_db
30
30
  from cgis.query.drift.ontology_init import propose_ontology
31
- from cgis.query.engine import QueryEngine
31
+ from cgis.query.engine import BEHAVIORAL_EDGE_TYPES, QueryEngine
32
32
  from cgis.query.fqn import resolve_fqn
33
33
  from cgis.query.render.graph_json import graph_to_json
34
34
  from cgis.query.render.mermaid import MermaidCompiler
@@ -65,6 +65,31 @@ Fqn = Annotated[
65
65
  "to look a name up."
66
66
  ),
67
67
  ]
68
+ IncludeStructure = Annotated[
69
+ bool,
70
+ Field(
71
+ description="Also follow containment (CONTAINS/DECLARES): a module's or class's own "
72
+ "members, and the class or file enclosing a symbol. Off by default, as in the CLI; "
73
+ "cgis_get_structure is the tool for members alone."
74
+ ),
75
+ ]
76
+ IncludeExternal = Annotated[
77
+ bool,
78
+ Field(
79
+ description="Also return stdlib, third-party and unresolved call targets — calls on "
80
+ "values whose type is decided at runtime. Off by default, as in the CLI, because they "
81
+ "dominate the payload; in json, coverage/top_unresolved still counts what was dropped."
82
+ ),
83
+ ]
84
+
85
+
86
+ def _traversal_filters(
87
+ include_structure: bool, include_external: bool
88
+ ) -> tuple[frozenset[EdgeType] | None, bool]:
89
+ """Edge-type allowlist and external flag for trace/impact — the CLI's defaults (#481)."""
90
+ return (None if include_structure else BEHAVIORAL_EDGE_TYPES), include_external
91
+
92
+
68
93
  OutputFormat = Annotated[
69
94
  str,
70
95
  Field(
@@ -363,19 +388,23 @@ def cgis_trace_flow(
363
388
  depth: Annotated[
364
389
  int,
365
390
  Field(
366
- description="Maximum edge hops downstream. Every edge type counts as a hop — "
367
- "calls, imports, inheritance, DI dependencies, references and containment — so "
368
- "from a module or class the first hop is mostly its own members and imports."
391
+ description="Maximum edge hops downstream, over calls, imports, inheritance, DI "
392
+ "dependencies and references (plus containment with include_structure)."
369
393
  ),
370
394
  ] = 3,
371
395
  output_format: OutputFormat = "mermaid",
396
+ include_structure: IncludeStructure = False,
397
+ include_external: IncludeExternal = False,
372
398
  ) -> str:
373
399
  """Downstream subgraph of one FQN: everything it reaches within ``depth`` hops.
374
400
 
375
- Every edge type counts — calls, imports, inheritance, DI dependencies,
376
- references, and containment (so from a module or class the first hop includes
377
- its own members) — so this answers "what does X depend on?". For what depends
378
- on X use
401
+ Follows every edge except containment — in practice calls, imports,
402
+ inheritance, DI dependencies and references — between internal code, so this
403
+ answers "what does X depend on?". Containment and
404
+ stdlib/third-party nodes are left out unless ``include_structure`` /
405
+ ``include_external`` ask for them (external covers stdlib, third-party and
406
+ unresolved call targets) — the same view as the CLI's ``trace``.
407
+ For what depends on X use
379
408
  ``cgis_analyze_impact``; for only the members of a module or class,
380
409
  ``cgis_get_structure``; for a source-included brief to read before editing
381
410
  one symbol, ``cgis_context``.
@@ -398,8 +427,13 @@ def cgis_trace_flow(
398
427
  res = resolve_fqn(store, fqn)
399
428
  if res.resolved is None:
400
429
  return _resolution_error(fqn, res.candidates, res.truncated)
430
+ allowed, show_external = _traversal_filters(include_structure, include_external)
401
431
  result = QueryEngine(store).get_flow_result(
402
- res.resolved, max_depth=depth, with_coverage=_wants_json(output_format)
432
+ res.resolved,
433
+ max_depth=depth,
434
+ allowed_edge_types=allowed,
435
+ show_external=show_external,
436
+ with_coverage=_wants_json(output_format),
403
437
  )
404
438
  except Exception as exc:
405
439
  return f"❌ {exc}"
@@ -424,18 +458,23 @@ def cgis_analyze_impact(
424
458
  depth: Annotated[
425
459
  int,
426
460
  Field(
427
- description="Maximum edge hops upstream. Every edge type counts as a hop — "
428
- "callers, importers, subclasses, type references, DI dependents and the "
429
- "enclosing class or file all appear alongside each other."
461
+ description="Maximum edge hops upstream, over callers, importers, subclasses, "
462
+ "type references and DI dependents (plus the enclosing class or file with "
463
+ "include_structure)."
430
464
  ),
431
465
  ] = 3,
432
466
  output_format: OutputFormat = "mermaid",
467
+ include_structure: IncludeStructure = False,
468
+ include_external: IncludeExternal = False,
433
469
  ) -> str:
434
470
  """Upstream subgraph of one FQN: everything that reaches it within ``depth`` hops.
435
471
 
436
- Every edge type counts — callers, but also importers, subclasses, type
437
- references, DI dependents and the enclosing class or file — so this answers
438
- "what breaks if I change X?". For what X depends on use
472
+ Follows every edge except containment — in practice callers, importers,
473
+ subclasses, type references and DI dependents — within internal code, so this
474
+ answers "what breaks if I change X?". The
475
+ enclosing class or file and stdlib/third-party nodes are left out unless
476
+ ``include_structure`` / ``include_external`` ask for them — the same view as
477
+ the CLI's ``impact``. For what X depends on use
439
478
  ``cgis_trace_flow``; for only the members of a module or class,
440
479
  ``cgis_get_structure``; for a source-included brief to read before editing
441
480
  one symbol, ``cgis_context``.
@@ -458,8 +497,13 @@ def cgis_analyze_impact(
458
497
  res = resolve_fqn(store, fqn)
459
498
  if res.resolved is None:
460
499
  return _resolution_error(fqn, res.candidates, res.truncated)
500
+ allowed, show_external = _traversal_filters(include_structure, include_external)
461
501
  result = QueryEngine(store).get_impact_result(
462
- res.resolved, max_depth=depth, with_coverage=_wants_json(output_format)
502
+ res.resolved,
503
+ max_depth=depth,
504
+ allowed_edge_types=allowed,
505
+ show_external=show_external,
506
+ with_coverage=_wants_json(output_format),
463
507
  )
464
508
  except Exception as exc:
465
509
  return f"❌ {exc}"
@@ -809,7 +853,8 @@ def cgis_context(
809
853
  calls only, one hop by default. Source is included when the file is found
810
854
  (see ``source_root``), and the domain when the graph was tagged with one.
811
855
  For a multi-hop subgraph
812
- over every edge type without source, use ``cgis_trace_flow`` (downstream) or
856
+ over calls, imports, inheritance and references without source, use
857
+ ``cgis_trace_flow`` (downstream) or
813
858
  ``cgis_analyze_impact`` (upstream).
814
859
 
815
860
  Returns an XML-tagged prompt — the focal node's source, its enclosing class,
@@ -76,7 +76,10 @@ def _identifiers_outside_imports(root: BaseNode, code_bytes: bytes) -> set[str]:
76
76
  # strings (parent `type`): scanning every string would let a docstring
77
77
  # mentioning a name mask a real re-export.
78
78
  text = code_bytes[node.start_byte : node.end_byte].decode("utf8")
79
- used.update(re.findall(r"[A-Za-z_][A-Za-z0-9_]*", text))
79
+ # `\w`, so a non-ASCII identifier in a quoted annotation counts as a
80
+ # use. Matching more here can only mark an import used, which is the
81
+ # safe direction for the unused-import sweep this feeds.
82
+ used.update(re.findall(r"[^\W\d]\w*", text))
80
83
  stack.extend(node.children)
81
84
  return used
82
85
 
@@ -197,6 +200,47 @@ def _collect_local_type(
197
200
  )
198
201
 
199
202
 
203
+ def _walk_one_decorator(
204
+ functions: FunctionHandler,
205
+ decorator: BaseNode,
206
+ code_bytes: bytes,
207
+ file_path: str,
208
+ edges: list[Edge],
209
+ owner_fqn: str,
210
+ name_refs_acc: list[tuple[str, str, int]] | None,
211
+ ) -> None:
212
+ """Record one decorator's calls and names, skipping its own head (#429).
213
+
214
+ Everything except the decorator's own head name, which
215
+ `process_function_node` already records as `raw_call:<name>` from its
216
+ decorator list — walking that too emitted `router.post` twice under two
217
+ ids, and its name a third time as a REFERENCES.
218
+
219
+ Skipping the *head* rather than "everything but the outermost call's
220
+ arguments" is what keeps the rarer shapes: `@a.b(X)(Y)`, `@registry[X]`
221
+ and `@(deco(X))` all name something the narrower rule walked straight past.
222
+ """
223
+ head = _decorator_head(decorator)
224
+ stack = [c for c in decorator.children if c.type not in ("comment", "@")]
225
+ while stack:
226
+ current = stack.pop()
227
+ if head is not None and current.id == head.id:
228
+ continue
229
+ if current.type == "call" and _calls_directly(current, head):
230
+ # `@router.post(...)` — the decorator list already recorded this
231
+ # exact call as `raw_call:router.post`. Its arguments still need
232
+ # walking, so recurse without processing it.
233
+ stack.extend(current.children)
234
+ continue
235
+ if current.type == "call":
236
+ functions.process_call_node(
237
+ current, code_bytes, file_path, owner_fqn, edges, emit_di=False
238
+ )
239
+ elif current.type == "identifier" and name_refs_acc is not None and is_name_load(current):
240
+ _append_name_candidates(current, code_bytes, owner_fqn, name_refs_acc)
241
+ stack.extend(current.children)
242
+
243
+
200
244
  class PythonExtractor(BaseExtractor):
201
245
  """
202
246
  A concrete extractor for Python source code using tree-sitter.
@@ -589,38 +633,9 @@ class PythonExtractor(BaseExtractor):
589
633
  else `_walk` would have handled here.
590
634
  """
591
635
  for decorator in (c for c in node.children if c.type == "decorator"):
592
- # Everything except the decorator's own head name, which
593
- # `process_function_node` already records as `raw_call:<name>` from
594
- # its decorator list — walking that too emitted `router.post` twice
595
- # under two ids, and its name a third time as a REFERENCES.
596
- #
597
- # Skipping the *head* rather than "everything but the outermost
598
- # call's arguments" is what keeps the rarer shapes: `@a.b(X)(Y)`,
599
- # `@registry[X]` and `@(deco(X))` all name something the narrower
600
- # rule walked straight past.
601
- head = _decorator_head(decorator)
602
- stack = [c for c in decorator.children if c.type not in ("comment", "@")]
603
- while stack:
604
- current = stack.pop()
605
- if head is not None and current.id == head.id:
606
- continue
607
- if current.type == "call" and _calls_directly(current, head):
608
- # `@router.post(...)` — the decorator list already recorded
609
- # this exact call as `raw_call:router.post`. Its arguments
610
- # still need walking, so recurse without processing it.
611
- stack.extend(current.children)
612
- continue
613
- if current.type == "call":
614
- self._functions.process_call_node(
615
- current, code_bytes, file_path, owner_fqn, edges, emit_di=False
616
- )
617
- elif (
618
- current.type == "identifier"
619
- and name_refs_acc is not None
620
- and is_name_load(current)
621
- ):
622
- _append_name_candidates(current, code_bytes, owner_fqn, name_refs_acc)
623
- stack.extend(current.children)
636
+ _walk_one_decorator(
637
+ self._functions, decorator, code_bytes, file_path, edges, owner_fqn, name_refs_acc
638
+ )
624
639
 
625
640
  def _handle_decorated_definition(
626
641
  self,
@@ -779,14 +779,25 @@ class SQLiteStore:
779
779
  reason=f"ingest root {base} no longer exists — {hint}",
780
780
  )
781
781
 
782
- tracked = self.get_tracked_source_files()
782
+ changed, missing = self._count_stale(base, self.get_tracked_source_files(), ingested_at)
783
+ if changed or missing:
784
+ return Freshness(state=FreshnessState.STALE, changed=changed, missing=missing)
785
+ return Freshness(state=FreshnessState.FRESH)
786
+
787
+ def _count_stale(self, base: str, tracked: set[str], ingested_at: float) -> tuple[int, int]:
788
+ """Files newer than the ingest, and files the graph has that the tree no longer does.
789
+
790
+ The two halves are complementary: a file's own mtime catches an edit, and
791
+ its directory's mtime catches an addition, a deletion or a new subdirectory.
792
+
793
+ `os.stat` on joined strings, not pathlib — the PTH rules are suppressed
794
+ deliberately here. Measured on this repository's own graph: the same 811
795
+ files cost 3.7 ms this way and 18.8 ms through `Path.stat()`, which is
796
+ slower than the tree walk this design exists to avoid. Tidying these to
797
+ `Path` would triple a cost paid on every query.
798
+ """
783
799
  changed = 0
784
800
  missing = 0
785
- # `os.stat` on joined strings, not pathlib — the PTH rules are suppressed
786
- # deliberately here. Measured on this repository's own graph: the same 811
787
- # files cost 3.7 ms this way and 18.8 ms through `Path.stat()`, which is
788
- # slower than the tree walk this design exists to avoid. Tidying these to
789
- # `Path` would triple a cost paid on every query.
790
801
  for rel in tracked:
791
802
  try:
792
803
  if os.stat(os.path.join(base, rel)).st_mtime > ingested_at: # noqa: PTH116,PTH118
@@ -803,10 +814,7 @@ class SQLiteStore:
803
814
  # Nothing added: the report says "N missing" of *files*, and every
804
815
  # file under a vanished directory has already been counted above.
805
816
  continue
806
-
807
- if changed or missing:
808
- return Freshness(state=FreshnessState.STALE, changed=changed, missing=missing)
809
- return Freshness(state=FreshnessState.FRESH)
817
+ return changed, missing
810
818
 
811
819
  def _directory_gained_a_source(
812
820
  self, path: str, tracked: set[str], base: str, ingested_at: float
@@ -1512,8 +1512,11 @@ class TestArgsContract:
1512
1512
  dry_run=True,
1513
1513
  )
1514
1514
  # dry_run returns before the provider, so this reaches the read itself.
1515
+ # The coroutine is built outside the block: two calls inside one cannot
1516
+ # say which raised (python:S5778).
1517
+ judging = gm.judge(args)
1515
1518
  with pytest.raises(AttributeError, match="concurrency"):
1516
- asyncio.run(gm.judge(args))
1519
+ asyncio.run(judging)
1517
1520
 
1518
1521
 
1519
1522
  class TestAblationArm: