codegraph-brain 0.23.4__tar.gz → 0.24.0__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 (374) hide show
  1. codegraph_brain-0.24.0/.release-please-manifest.json +3 -0
  2. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/CHANGELOG.md +12 -0
  3. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/PKG-INFO +2 -1
  4. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/README.md +1 -0
  5. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/architecture/HOW_IT_WORKS.md +2 -2
  6. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/architecture/diagrams/pipeline_flow.mermaid +1 -1
  7. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/how-to/CLI_USAGE.md +27 -0
  8. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/how-to/MCP_REFERENCE.md +25 -0
  9. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/plugin/skills/cgis/SKILL.md +1 -0
  10. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/pyproject.toml +1 -1
  11. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/server.json +2 -2
  12. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/api/mcp_server.py +37 -0
  13. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/cli.py +64 -0
  14. codegraph_brain-0.24.0/src/cgis/query/analysis/overview.py +87 -0
  15. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/storage/sqlite_store.py +67 -0
  16. codegraph_brain-0.24.0/tests/self_parsing/test_overview.py +74 -0
  17. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_receiver_resolution.py +7 -1
  18. codegraph_brain-0.24.0/tests/unit/test_overview.py +188 -0
  19. codegraph_brain-0.24.0/tests/unit/test_overview_tools.py +149 -0
  20. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/uv.lock +1 -1
  21. codegraph_brain-0.23.4/.release-please-manifest.json +0 -3
  22. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.claude-plugin/marketplace.json +0 -0
  23. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.gitattributes +0 -0
  24. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.github/test-count-baseline +0 -0
  25. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.github/workflows/autodoc.yml +0 -0
  26. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.github/workflows/ci.yml +0 -0
  27. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.github/workflows/guardian.yml +0 -0
  28. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.github/workflows/mcp-registry.yml +0 -0
  29. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.github/workflows/pr-title.yml +0 -0
  30. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.github/workflows/release-please.yml +0 -0
  31. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.gitignore +0 -0
  32. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.pre-commit-config.yaml +0 -0
  33. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/.python-version +0 -0
  34. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/CLAUDE.md +0 -0
  35. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/CONTRIBUTING.md +0 -0
  36. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/LICENSE +0 -0
  37. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/Makefile +0 -0
  38. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/PRIVACY.md +0 -0
  39. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/CURATION.md +0 -0
  40. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/calibration.jsonl +0 -0
  41. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/246-cross-vendor/README.md +0 -0
  42. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/246-cross-vendor/free-nemotron-quota-cutoff.jsonl +0 -0
  43. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/401-evidence/README.md +0 -0
  44. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/401-evidence/pr-399-control-rows.jsonl +0 -0
  45. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/401-evidence/pr-399-recording.json +0 -0
  46. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/401-evidence/pr-399-treatment-rows.jsonl +0 -0
  47. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/407-no-checker-appeal/README.md +0 -0
  48. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-directive-rows.jsonl +0 -0
  49. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-prohibition-rows.jsonl +0 -0
  50. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-122.yaml +0 -0
  51. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-140.yaml +0 -0
  52. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-141.yaml +0 -0
  53. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-142.yaml +0 -0
  54. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-143.yaml +0 -0
  55. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-144.yaml +0 -0
  56. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-278.yaml +0 -0
  57. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/pr-313.yaml +0 -0
  58. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/guardian/results.jsonl +0 -0
  59. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian/README.md +0 -0
  60. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian/cal_dot_com.json +0 -0
  61. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian/discourse.json +0 -0
  62. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian/grafana.json +0 -0
  63. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian/keycloak.json +0 -0
  64. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian/sentry.json +0 -0
  65. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-judged.jsonl +0 -0
  66. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-p3-judged-run1.jsonl +0 -0
  67. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-p3-judged-run1.jsonl.corrupted-backup +0 -0
  68. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-p3-run1.jsonl +0 -0
  69. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-p3-run2.jsonl +0 -0
  70. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-p3-run3.jsonl +0 -0
  71. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-plan.json +0 -0
  72. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-repeat-judged.jsonl +0 -0
  73. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-repeat-reviews.jsonl +0 -0
  74. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/benchmarks/martian-reviews.jsonl +0 -0
  75. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/data/.gitkeep +0 -0
  76. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/AUDIT.md +0 -0
  77. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/CASE_STUDY.md +0 -0
  78. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/GUARDIAN_LOCAL_BENCH.md +0 -0
  79. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/GUARDIAN_REMOTE_OLLAMA.md +0 -0
  80. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/architecture/ONTOLOGY.md +0 -0
  81. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/architecture/PATTERNS_AND_TRIADS.md +0 -0
  82. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/architecture/SELF_PORTRAIT.md +0 -0
  83. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/architecture/health_badge.json +0 -0
  84. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/assets/.gitignore +0 -0
  85. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/assets/cgis-app-avatar.png +0 -0
  86. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/assets/cgis-app-avatar.svg +0 -0
  87. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/assets/generate_avatar.py +0 -0
  88. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/examples/.gitkeep +0 -0
  89. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/how-to/AGENT_ONBOARDING.md +0 -0
  90. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/lab-notes/2026-06-11-chunked-review-negative-result.md +0 -0
  91. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/ontology/.gitkeep +0 -0
  92. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/ontology/core.yaml +0 -0
  93. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/ontology/domains.yaml +0 -0
  94. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/ontology/patterns.yaml +0 -0
  95. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/ontology/tolerances.lock +0 -0
  96. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/plans/2026-09-09-graph-freshness.md +0 -0
  97. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-09-domain-pattern-fingerprint-design.md +0 -0
  98. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-09-pattern-alphabet-motif-basis-design.md +0 -0
  99. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-10-guardian-sprint-design.md +0 -0
  100. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-11-fastapi-di-edges-design.md +0 -0
  101. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-11-guardian-chunked-review-design.md +0 -0
  102. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-11-guardian-chunker-design.md +0 -0
  103. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-11-mcp-drift-validate-fqn-design.md +0 -0
  104. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-11-resolver-split-design.md +0 -0
  105. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-11-symbol-import-edges-design.md +0 -0
  106. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-12-drift-empty-domains-design.md +0 -0
  107. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-12-gate-semantics-design.md +0 -0
  108. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-12-init-ontology-design.md +0 -0
  109. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-12-release-please-ci-design.md +0 -0
  110. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-13-suggest-packages-design.md +0 -0
  111. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-06-13-tangle-anti-pattern-design.md +0 -0
  112. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-29-guardian-skeptic-scoring-design.md +0 -0
  113. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-cgis-fractal-design.md +0 -0
  114. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-cgis-fractal-plan.md +0 -0
  115. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-chunk-source-filter-design.md +0 -0
  116. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-chunk-source-filter-plan.md +0 -0
  117. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-genai-client-close-design.md +0 -0
  118. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-genai-client-close-plan.md +0 -0
  119. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-guardian-precision-bench-design.md +0 -0
  120. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-guardian-precision-bench-plan.md +0 -0
  121. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-guardian-timeout-retry-design.md +0 -0
  122. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-30-guardian-timeout-retry-plan.md +0 -0
  123. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-07-31-finder-bug-class-taxonomy.md +0 -0
  124. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-08-01-aura-autoevolution-poc.md +0 -0
  125. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-08-11-guardian-code-review-bench.md +0 -0
  126. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-08-14-review-fingerprint-design.md +0 -0
  127. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-09-05-annotation-graph-design.md +0 -0
  128. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/2026-09-09-graph-freshness-design.md +0 -0
  129. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/BLUEPRINT.md +0 -0
  130. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/PRD.md +0 -0
  131. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/TDD.md +0 -0
  132. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-09-fingerprint-drift.md +0 -0
  133. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-10-guardian-context-skeptic-inline.md +0 -0
  134. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-10-guardian-structured-findings-bench.md +0 -0
  135. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-10-motif-basis-part-b.md +0 -0
  136. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-10-unified-pattern-alphabet.md +0 -0
  137. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-11-fastapi-di-edges.md +0 -0
  138. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-11-guardian-chunked-review.md +0 -0
  139. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-11-guardian-chunker.md +0 -0
  140. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-11-mcp-drift-validate-fqn.md +0 -0
  141. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-11-resolver-split.md +0 -0
  142. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-12-drift-empty-domains.md +0 -0
  143. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-12-gate-semantics.md +0 -0
  144. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-12-init-ontology.md +0 -0
  145. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-12-release-please-ci.md +0 -0
  146. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-12-symbol-import-edges.md +0 -0
  147. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-06-13-suggest-packages.md +0 -0
  148. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-07-29-guardian-skeptic-scoring.md +0 -0
  149. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-08-14-review-fingerprint.md +0 -0
  150. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-09-05-annotation-graph-pr1.md +0 -0
  151. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/docs/specs/plans/2026-09-05-annotation-graph-pr2.md +0 -0
  152. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/glama.json +0 -0
  153. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/main.py +0 -0
  154. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/plugin/.claude-plugin/plugin.json +0 -0
  155. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/plugin/.mcp.json +0 -0
  156. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/plugin/README.md +0 -0
  157. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/plugin/skills/ingest/SKILL.md +0 -0
  158. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/release-please-config.json +0 -0
  159. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/backfill_calibration_fingerprint.py +0 -0
  160. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/backfill_review_fingerprint.py +0 -0
  161. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/check_pytest_raises.py +0 -0
  162. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/check_test_count.py +0 -0
  163. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/colab_bench.sh +0 -0
  164. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/gen_ideal_graph.py +0 -0
  165. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/generate_health.py +0 -0
  166. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/generate_mcp_ref.py +0 -0
  167. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/generate_schema_docs.py +0 -0
  168. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/guardian_bench.py +0 -0
  169. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/guardian_calibrate.py +0 -0
  170. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/guardian_martian.py +0 -0
  171. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/guardian_replay_skeptic.py +0 -0
  172. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/guardian_review.py +0 -0
  173. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/inject_architecture_graph.py +0 -0
  174. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/mcp_registry_gate.sh +0 -0
  175. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/ollama_visitor.sh +0 -0
  176. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/probe_closure_gap.py +0 -0
  177. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/probe_tier_ladder.py +0 -0
  178. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/recordings_from_corpus.py +0 -0
  179. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/scripts/skeptic_arms.py +0 -0
  180. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/__init__.py +0 -0
  181. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/__main__.py +0 -0
  182. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/api/.gitkeep +0 -0
  183. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/api/__init__.py +0 -0
  184. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/core/.gitkeep +0 -0
  185. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/core/coverage.py +0 -0
  186. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/core/freshness.py +0 -0
  187. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/core/generated.py +0 -0
  188. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/core/js_globals.py +0 -0
  189. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/core/models.py +0 -0
  190. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/core/paths.py +0 -0
  191. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/.gitkeep +0 -0
  192. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/_python_annotations.py +0 -0
  193. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/_python_ast.py +0 -0
  194. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/_python_classes.py +0 -0
  195. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/_python_functions.py +0 -0
  196. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/_python_imports.py +0 -0
  197. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/_python_types.py +0 -0
  198. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/_typescript_bindings.py +0 -0
  199. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/base.py +0 -0
  200. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/python_extractor.py +0 -0
  201. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/registry.py +0 -0
  202. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/extractors/typescript_extractor.py +0 -0
  203. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/__init__.py +0 -0
  204. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/axes.py +0 -0
  205. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/bench.py +0 -0
  206. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/calibrate.py +0 -0
  207. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/chunked.py +0 -0
  208. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/chunker.py +0 -0
  209. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/collector.py +0 -0
  210. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/core.py +0 -0
  211. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/diff_index.py +0 -0
  212. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/evidence.py +0 -0
  213. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/findings.py +0 -0
  214. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/github_poster.py +0 -0
  215. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/martian.py +0 -0
  216. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/metrics.py +0 -0
  217. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/prompts.py +0 -0
  218. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/providers/__init__.py +0 -0
  219. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/providers/base.py +0 -0
  220. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/providers/gemini.py +0 -0
  221. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/providers/mistral.py +0 -0
  222. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/providers/ollama.py +0 -0
  223. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/providers/openrouter.py +0 -0
  224. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/recording.py +0 -0
  225. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/render.py +0 -0
  226. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/review_fingerprint.py +0 -0
  227. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/runner.py +0 -0
  228. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/guardian/skeptic.py +0 -0
  229. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/pipeline.py +0 -0
  230. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/py.typed +0 -0
  231. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/analysis/__init__.py +0 -0
  232. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/analysis/analyzer.py +0 -0
  233. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/analysis/anomaly.py +0 -0
  234. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/analysis/cohesion.py +0 -0
  235. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/analysis/health.py +0 -0
  236. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/analysis/suggest_service.py +0 -0
  237. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/context/__init__.py +0 -0
  238. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/context/audit.py +0 -0
  239. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/context/context_service.py +0 -0
  240. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/context/orphans.py +0 -0
  241. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/context/prompt.py +0 -0
  242. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/context/snippet.py +0 -0
  243. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/__init__.py +0 -0
  244. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/_scc.py +0 -0
  245. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/drift.py +0 -0
  246. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/drift_service.py +0 -0
  247. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/fingerprint.py +0 -0
  248. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/fractal.py +0 -0
  249. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/ontology_init.py +0 -0
  250. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/quotient.py +0 -0
  251. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/drift/triads.py +0 -0
  252. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/engine.py +0 -0
  253. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/fqn.py +0 -0
  254. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/render/__init__.py +0 -0
  255. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/render/graph_json.py +0 -0
  256. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/render/mermaid.py +0 -0
  257. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/query/render/metrics.py +0 -0
  258. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/resolver/.gitkeep +0 -0
  259. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/resolver/__init__.py +0 -0
  260. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/resolver/engine.py +0 -0
  261. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/resolver/indices.py +0 -0
  262. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/resolver/js_builtins.py +0 -0
  263. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/resolver/symbols.py +0 -0
  264. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/resolver/uplift.py +0 -0
  265. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/src/cgis/storage/.gitkeep +0 -0
  266. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/integration/.gitkeep +0 -0
  267. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/.gitkeep +0 -0
  268. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/__init__.py +0 -0
  269. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/conftest.py +0 -0
  270. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_annotation_calibration.py +0 -0
  271. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_architecture.py +0 -0
  272. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_drift.py +0 -0
  273. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_fractal.py +0 -0
  274. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_init_ontology_roundtrip.py +0 -0
  275. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_self_parse.py +0 -0
  276. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_self_parse_ts.py +0 -0
  277. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/self_parsing/test_suggest.py +0 -0
  278. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/.gitkeep +0 -0
  279. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/conftest.py +0 -0
  280. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/guardian_stubs.py +0 -0
  281. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/review_path_inventory.txt +0 -0
  282. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test___main__.py +0 -0
  283. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_analyzer.py +0 -0
  284. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_annotation_edges.py +0 -0
  285. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_audit.py +0 -0
  286. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_backfill_calibration_fingerprint.py +0 -0
  287. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_backfill_review_fingerprint.py +0 -0
  288. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_check_pytest_raises.py +0 -0
  289. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_check_test_count.py +0 -0
  290. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_cli.py +0 -0
  291. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_cohesion.py +0 -0
  292. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_context_service.py +0 -0
  293. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_di_acceptance.py +0 -0
  294. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_drift.py +0 -0
  295. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_drift_service.py +0 -0
  296. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_extractor_registry.py +0 -0
  297. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_fingerprint.py +0 -0
  298. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_fqn.py +0 -0
  299. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_fractal.py +0 -0
  300. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_freshness.py +0 -0
  301. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_gen_ideal_graph.py +0 -0
  302. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_generate_mcp_ref.py +0 -0
  303. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_generated.py +0 -0
  304. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_graph_json.py +0 -0
  305. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_axes.py +0 -0
  306. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_bench.py +0 -0
  307. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_bench_script.py +0 -0
  308. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_calibrate.py +0 -0
  309. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_calibrate_script.py +0 -0
  310. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_chunked.py +0 -0
  311. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_chunker.py +0 -0
  312. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_collector.py +0 -0
  313. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_core.py +0 -0
  314. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_diff_index.py +0 -0
  315. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_evidence.py +0 -0
  316. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_findings.py +0 -0
  317. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_martian.py +0 -0
  318. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_martian_script.py +0 -0
  319. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_martian_union.py +0 -0
  320. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_metrics.py +0 -0
  321. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_mistral_sampling.py +0 -0
  322. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_ollama_sampling.py +0 -0
  323. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_ollama_truncation.py +0 -0
  324. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_openrouter.py +0 -0
  325. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_poster.py +0 -0
  326. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_providers.py +0 -0
  327. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_providers_name.py +0 -0
  328. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_recording.py +0 -0
  329. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_render.py +0 -0
  330. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_replay_skeptic.py +0 -0
  331. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_review_script.py +0 -0
  332. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_runner.py +0 -0
  333. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_salvage.py +0 -0
  334. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_guardian_skeptic.py +0 -0
  335. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_health_scorer.py +0 -0
  336. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_import_acceptance.py +0 -0
  337. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_inject_architecture_graph.py +0 -0
  338. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_mcp_server.py +0 -0
  339. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_mcp_tool_schemas.py +0 -0
  340. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_mermaid.py +0 -0
  341. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_metrics.py +0 -0
  342. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_models.py +0 -0
  343. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_name_load_positions.py +0 -0
  344. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_ontology_compliance.py +0 -0
  345. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_ontology_init.py +0 -0
  346. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_orphans.py +0 -0
  347. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_paths.py +0 -0
  348. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_patterns_yaml.py +0 -0
  349. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_pipeline.py +0 -0
  350. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_pipeline_incremental_symbols.py +0 -0
  351. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_prompt.py +0 -0
  352. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_python_annotations.py +0 -0
  353. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_python_extractor.py +0 -0
  354. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_query_coverage.py +0 -0
  355. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_quotient.py +0 -0
  356. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_recordings_from_corpus.py +0 -0
  357. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_resolver.py +0 -0
  358. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_resolver_indices.py +0 -0
  359. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_resolver_js_builtins.py +0 -0
  360. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_resolver_language_scope.py +0 -0
  361. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_resolver_symbols.py +0 -0
  362. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_review_fingerprint_closure.py +0 -0
  363. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_review_fingerprint_contract.py +0 -0
  364. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_review_fingerprint_digest.py +0 -0
  365. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_review_fingerprint_record.py +0 -0
  366. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_self_types.py +0 -0
  367. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_skeptic_arms.py +0 -0
  368. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_snippet.py +0 -0
  369. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_sqlite_store.py +0 -0
  370. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_suggest_service.py +0 -0
  371. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_temperature_source.py +0 -0
  372. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_triads.py +0 -0
  373. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_typescript_extractor.py +0 -0
  374. {codegraph_brain-0.23.4 → codegraph_brain-0.24.0}/tests/unit/test_uplift.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.24.0"
3
+ }
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.24.0](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.4...codegraph-brain-v0.24.0) (2026-09-17)
4
+
5
+
6
+ ### Features
7
+
8
+ * **mcp:** cgis_overview — a starting map when you have no FQN yet ([#486](https://github.com/zaebee/codegraph-brain/issues/486)) ([1580cfe](https://github.com/zaebee/codegraph-brain/commit/1580cfe53325241e149ba3bbb9388c4ddc7718d7))
9
+
10
+
11
+ ### Documentation
12
+
13
+ * auto-sync architecture graph and MCP reference ([#488](https://github.com/zaebee/codegraph-brain/issues/488)) ([9f169ce](https://github.com/zaebee/codegraph-brain/commit/9f169ce364f0d778c0c59b4de607a3433b800dbd))
14
+
3
15
  ## [0.23.4](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.3...codegraph-brain-v0.23.4) (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.4
3
+ Version: 0.24.0
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
@@ -143,6 +143,7 @@ The main tools:
143
143
  | Tool | Answers |
144
144
  | :--- | :--- |
145
145
  | `cgis_ingest` | Build or incrementally refresh the graph |
146
+ | `cgis_overview` | Where to start: sizes and the largest packages, when you have no FQN yet |
146
147
  | `cgis_find_symbol` | Partial name → candidate FQNs |
147
148
  | `cgis_analyze_impact` | What breaks upstream if this changes? |
148
149
  | `cgis_trace_flow` | What does this call, transitively? |
@@ -93,6 +93,7 @@ The main tools:
93
93
  | Tool | Answers |
94
94
  | :--- | :--- |
95
95
  | `cgis_ingest` | Build or incrementally refresh the graph |
96
+ | `cgis_overview` | Where to start: sizes and the largest packages, when you have no FQN yet |
96
97
  | `cgis_find_symbol` | Partial name → candidate FQNs |
97
98
  | `cgis_analyze_impact` | What breaks upstream if this changes? |
98
99
  | `cgis_trace_flow` | What does this call, transitively? |
@@ -204,7 +204,7 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
204
204
  uplift_SemanticUpliftEngine_execute_uplift["execute_uplift (uplift.py:91)"]:::methodNode
205
205
  end
206
206
  subgraph sg_sqlite_store["sqlite_store.py"]
207
- sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:42)"]:::classNode
207
+ sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:48)"]:::classNode
208
208
  end
209
209
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Node
210
210
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Edge
@@ -237,5 +237,5 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
237
237
  | `resolve` | METHOD | [`engine.py:37`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/engine.py#L37) |
238
238
  | `SemanticUpliftEngine` | CLASS | [`uplift.py:66`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L66) |
239
239
  | `execute_uplift` | METHOD | [`uplift.py:91`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L91) |
240
- | `SQLiteStore` | CLASS | [`sqlite_store.py:42`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L42) |
240
+ | `SQLiteStore` | CLASS | [`sqlite_store.py:48`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L48) |
241
241
  <!-- END_CGIS_GRAPH -->
@@ -29,7 +29,7 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
29
29
  uplift_SemanticUpliftEngine_execute_uplift["execute_uplift (uplift.py:91)"]:::methodNode
30
30
  end
31
31
  subgraph sg_sqlite_store["sqlite_store.py"]
32
- sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:42)"]:::classNode
32
+ sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:48)"]:::classNode
33
33
  end
34
34
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Node
35
35
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Edge
@@ -45,6 +45,33 @@ cgis ingest ./src --output graph.json
45
45
 
46
46
  ---
47
47
 
48
+ ### `cgis overview`
49
+
50
+ Where to start in a graph you know nothing about: how big it is, how much of it resolved, and the largest packages with production and tests listed separately. Every prefix it prints is one `find --prefix` and `metrics --scope` accept. `structure` takes a node's FQN instead — a package is a node only when it has an `__init__.py` — so reach a module through `find` first. The MCP tool is `cgis_overview`.
51
+
52
+ ```bash
53
+ cgis overview [OPTIONS]
54
+ ```
55
+
56
+ | Option | Default | Description |
57
+ | :--- | :--- | :--- |
58
+ | `--db`, `-d` | `graph.db` | Path to the graph database |
59
+ | `--depth` | `2` | FQN segments per package prefix; `1` is the top level |
60
+ | `--limit`, `-n` | `15` | Maximum packages listed per section |
61
+ | `--format`, `-f` | `text` | `text` or `json` |
62
+
63
+ **Examples:**
64
+
65
+ ```bash
66
+ # First call in an unfamiliar repository
67
+ cgis overview
68
+
69
+ # Top-level map only, as JSON
70
+ cgis overview --depth 1 --format json
71
+ ```
72
+
73
+ ---
74
+
48
75
  ### `cgis trace`
49
76
 
50
77
  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`).
@@ -330,6 +330,31 @@ Whole-graph architectural metrics — coupling bottlenecks, God classes, PageRan
330
330
 
331
331
  ---
332
332
 
333
+ ## `cgis_overview`
334
+
335
+ Where to start in a graph you know nothing about: sizes and a package map.
336
+
337
+ Call this first in an unfamiliar repository — every other tool needs a name,
338
+ and this is the one that hands you some. Returns JSON: symbol counts by type,
339
+ file and edge totals, the unresolved-edge ratio, and the largest packages with
340
+ production and tests listed separately. Each ``prefix`` goes straight into
341
+ ``cgis_find_symbol`` (``fqn_prefix``) or ``cgis_metrics`` (``scope``), which
342
+ match on prefixes. ``cgis_get_structure`` takes a node id, not a prefix: a
343
+ package is a node only when it has an ``__init__.py``, and then holds no
344
+ members of its own — reach a module through ``cgis_find_symbol`` first.
345
+
346
+ Listings are capped; ``packages_omitted`` appears when rows were cut. Entry
347
+ points are deliberately not reported — "nothing calls it" is not one on a
348
+ framework codebase, where most handlers have no incoming call edge.
349
+
350
+ | Argument | Type | Required | Description |
351
+ | :--- | :--- | :---: | :--- |
352
+ | `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. |
353
+ | `depth` | `integer` | | FQN segments per package prefix; 1 is the top level. |
354
+ | `limit` | `integer` | | Maximum packages listed per section. |
355
+
356
+ ---
357
+
333
358
  ## `cgis_suggest_packages`
334
359
 
335
360
  Suggest sub-package boundaries for a package from its dependency communities.
@@ -11,6 +11,7 @@ Reading files to answer a structural question is the slow, lossy path: it burns
11
11
 
12
12
  | Question | Tool | Instead of |
13
13
  | :--- | :--- | :--- |
14
+ | "Where do I even start?" | `cgis_overview` | opening files to find the shape of the repo |
14
15
  | "What calls this?" | `cgis_analyze_impact` | grepping the name and hoping |
15
16
  | "Is this rename safe?" | `cgis_analyze_impact` | reading every plausible caller |
16
17
  | "What does this end up calling?" | `cgis_trace_flow` | following imports by hand |
@@ -7,7 +7,7 @@ packages = ["src/cgis"]
7
7
 
8
8
  [project]
9
9
  name = "codegraph-brain"
10
- version = "0.23.4"
10
+ version = "0.24.0"
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"
@@ -8,13 +8,13 @@
8
8
  "source": "github",
9
9
  "id": "1260843154"
10
10
  },
11
- "version": "0.23.4",
11
+ "version": "0.24.0",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "pypi",
15
15
  "registryBaseUrl": "https://pypi.org",
16
16
  "identifier": "codegraph-brain",
17
- "version": "0.23.4",
17
+ "version": "0.24.0",
18
18
  "runtimeHint": "uvx",
19
19
  "transport": {
20
20
  "type": "stdio"
@@ -21,6 +21,7 @@ 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
24
+ from cgis.query.analysis.overview import DEFAULT_DEPTH, DEFAULT_LIMIT, build_overview
24
25
  from cgis.query.analysis.suggest_service import report_to_dict, suggest_packages
25
26
  from cgis.query.context.audit import audit_reachability
26
27
  from cgis.query.context.context_service import build_context
@@ -722,6 +723,42 @@ def cgis_validate(
722
723
  return f"❌ {exc}"
723
724
 
724
725
 
726
+ @mcp.tool()
727
+ def cgis_overview(
728
+ db_path: DbPath = _DEFAULT_DB,
729
+ depth: Annotated[
730
+ int,
731
+ Field(description="FQN segments per package prefix; 1 is the top level."),
732
+ ] = DEFAULT_DEPTH,
733
+ limit: Annotated[
734
+ int, Field(description="Maximum packages listed per section.")
735
+ ] = DEFAULT_LIMIT,
736
+ ) -> str:
737
+ """Where to start in a graph you know nothing about: sizes and a package map.
738
+
739
+ Call this first in an unfamiliar repository — every other tool needs a name,
740
+ and this is the one that hands you some. Returns JSON: symbol counts by type,
741
+ file and edge totals, the unresolved-edge ratio, and the largest packages with
742
+ production and tests listed separately. Each ``prefix`` goes straight into
743
+ ``cgis_find_symbol`` (``fqn_prefix``) or ``cgis_metrics`` (``scope``), which
744
+ match on prefixes. ``cgis_get_structure`` takes a node id, not a prefix: a
745
+ package is a node only when it has an ``__init__.py``, and then holds no
746
+ members of its own — reach a module through ``cgis_find_symbol`` first.
747
+
748
+ Listings are capped; ``packages_omitted`` appears when rows were cut. Entry
749
+ points are deliberately not reported — "nothing calls it" is not one on a
750
+ framework codebase, where most handlers have no incoming call edge.
751
+ """
752
+ if not Path(db_path).exists():
753
+ return f"❌ Database not found at: {db_path}. Run cgis_ingest first."
754
+ try:
755
+ with SQLiteStore(db_path) as store:
756
+ report = build_overview(store, depth=depth, limit=limit)
757
+ except Exception as exc:
758
+ return f"❌ {exc}"
759
+ return json.dumps(_with_freshness(db_path, report), indent=2)
760
+
761
+
725
762
  @mcp.tool()
726
763
  def cgis_find_symbol(
727
764
  query: Annotated[
@@ -23,6 +23,7 @@ import json as _json
23
23
  from collections.abc import Callable
24
24
  from enum import StrEnum
25
25
  from pathlib import Path
26
+ from typing import Any
26
27
 
27
28
  import typer
28
29
  import yaml
@@ -42,6 +43,7 @@ from cgis.pipeline import IngestionPipeline
42
43
  from cgis.query.analysis.analyzer import AnalyzerEngine
43
44
  from cgis.query.analysis.anomaly import AnomalyType, ArchitecturalAnomaly
44
45
  from cgis.query.analysis.health import HealthScorer
46
+ from cgis.query.analysis.overview import DEFAULT_DEPTH, DEFAULT_LIMIT, build_overview
45
47
  from cgis.query.analysis.suggest_service import SuggestReport, report_to_dict, suggest_packages
46
48
  from cgis.query.context.audit import NoAuditSourcesError, ReachabilityAudit, audit_reachability
47
49
  from cgis.query.context.context_service import build_context
@@ -620,6 +622,68 @@ def impact(
620
622
  console.print(tree)
621
623
 
622
624
 
625
+ @app.command()
626
+ def overview(
627
+ db: str = typer.Option(_DEFAULT_DB, "--db", "-d", help=_DEFAULT_DB_HELP),
628
+ depth: int = typer.Option(
629
+ DEFAULT_DEPTH, "--depth", min=1, help="FQN segments per package prefix."
630
+ ),
631
+ limit: int = typer.Option(
632
+ DEFAULT_LIMIT, "--limit", "-n", min=1, help="Max packages listed per section."
633
+ ),
634
+ output_format: OutputFormat = typer.Option(
635
+ OutputFormat.TEXT, "--format", "-f", help=_TEXT_JSON_FORMAT_HELP
636
+ ),
637
+ ) -> None:
638
+ """Where to start in a graph you know nothing about: sizes and a package map (#478).
639
+
640
+ Every other command needs an FQN. This one hands you some: the largest
641
+ packages, production and tests apart, as prefixes `structure`, `find` and
642
+ `metrics --scope` accept directly.
643
+ """
644
+ if output_format == OutputFormat.MERMAID:
645
+ console.print("[bold red]❌ overview supports --format text or json only.[/bold red]")
646
+ raise typer.Exit(code=2)
647
+ if not Path(db).is_file():
648
+ console.print(
649
+ f"[bold red]❌ Database not found:[/bold red] {escape(db)}. Run `ingest` first."
650
+ )
651
+ raise typer.Exit(code=1)
652
+ _warn_if_not_fresh(db)
653
+
654
+ with SQLiteStore(db) as store:
655
+ report = build_overview(store, depth=depth, limit=limit)
656
+
657
+ if output_format == OutputFormat.JSON:
658
+ typer.echo(_json.dumps(report, indent=2))
659
+ return
660
+ _render_overview(report)
661
+
662
+
663
+ def _render_overview(report: dict[str, Any]) -> None:
664
+ """Print the overview as two small tables plus a one-line size summary."""
665
+ counts = ", ".join(
666
+ f"{count} {kind.lower()}" for kind, count in sorted(report["symbols"].items())
667
+ )
668
+ console.print(
669
+ f"[bold]{report['files']} files[/bold] · {counts or 'no symbols'} · "
670
+ f"{report['edges']} edges · {report['unresolved_ratio'] * 100:.1f}% unresolved\n"
671
+ )
672
+ for key, title in (("packages", "Packages"), ("test_packages", "Test packages")):
673
+ rows = report[key]
674
+ if not rows:
675
+ continue
676
+ table = Table(title=title)
677
+ table.add_column("Prefix", style="cyan")
678
+ table.add_column("Symbols", style="magenta", justify="right")
679
+ for row in rows:
680
+ table.add_row(escape(str(row["prefix"])), str(row["symbols"]))
681
+ console.print(table)
682
+ omitted = report.get(f"{key}_omitted")
683
+ if omitted:
684
+ console.print(f"[dim]… {omitted} more not shown (raise --limit)[/dim]")
685
+
686
+
623
687
  @app.command()
624
688
  def validate(
625
689
  db: str = typer.Option(_DEFAULT_DB, "--db", "-d", help=_DEFAULT_DB_HELP),
@@ -0,0 +1,87 @@
1
+ """The map an agent reads before it knows a single FQN (#478).
2
+
3
+ Every other query tool takes a name: `cgis_get_structure` wants a module,
4
+ `cgis_analyze_impact` wants a symbol, and `cgis_find_symbol` wants something to
5
+ search for. In an unfamiliar repository an agent has none of them, so its first
6
+ move is to read files — the thing the graph exists to replace.
7
+
8
+ This answers "what is in this graph, and where do I start?" and nothing else.
9
+ Two rules follow from that:
10
+
11
+ **It stays small.** The listing is capped and says how much it cut. A map that
12
+ costs as much as the files it replaces is not a map.
13
+
14
+ **Every prefix it prints is usable — by the tools that match on prefixes.**
15
+ `cgis_find_symbol(fqn_prefix=…)` and `cgis_metrics(scope=[…])` take a package
16
+ prefix as it appears here. `cgis_get_structure` does not: it looks a node up by
17
+ id, and a package has a node only when it has an `__init__.py` — and even then
18
+ containment runs file→symbol, so the answer is that one empty file. Measured on
19
+ this repository: of ten printed prefixes, four are not nodes at all and three
20
+ resolve to a single node with no edges. So the route to a module is
21
+ `cgis_find_symbol(fqn_prefix=…)` first, `cgis_get_structure` on what it returns.
22
+
23
+ Entry points are deliberately absent. "A function nothing calls" is not one: on
24
+ a 512-file FastAPI backend 4,612 of 5,846 functions and methods have no incoming
25
+ CALLS edge, because frameworks, DI and dynamic dispatch do the calling. Listing
26
+ them would be noise wearing the name of an answer.
27
+ """
28
+
29
+ from typing import Any
30
+
31
+ from cgis.storage.sqlite_store import SQLiteStore
32
+
33
+ #: Rows per listing. Two of these fit in the budget an agent would otherwise
34
+ #: spend opening a single file.
35
+ DEFAULT_LIMIT = 15
36
+
37
+ #: Dot-segments of a package prefix. Two is where a real tree separates:
38
+ #: `domains.admin` and `domains.reservation` are different places to look,
39
+ #: `domains` alone is not a lead.
40
+ DEFAULT_DEPTH = 2
41
+
42
+
43
+ def _package_rows(census: list[tuple[str, int]], limit: int) -> tuple[list[dict[str, Any]], int]:
44
+ """Cap a census, largest first, and report how many rows were dropped."""
45
+ rows = [{"prefix": prefix, "symbols": count} for prefix, count in census[:limit]]
46
+ return rows, max(len(census) - limit, 0)
47
+
48
+
49
+ def build_overview(
50
+ store: SQLiteStore, depth: int = DEFAULT_DEPTH, limit: int = DEFAULT_LIMIT
51
+ ) -> dict[str, Any]:
52
+ """Sizes, a capped package map, and what to call next.
53
+
54
+ Production and test packages are listed separately because on a real tree the
55
+ test packages are the largest ones: on a 512-file backend three of the six
56
+ biggest are under `tests.`, which makes an undivided listing point an agent
57
+ at the tests first. A prefix can appear in both lists when tests live inside
58
+ the package they cover (`domains/admin/tests/`), and the two lists do not sum
59
+ to `symbols` once the cap bites.
60
+ """
61
+ depth = max(depth, 1)
62
+ limit = max(limit, 1)
63
+ stats = store.get_edge_stats()
64
+ production, tests = store.package_census(depth)
65
+ package_rows, omitted = _package_rows(production, limit)
66
+ test_rows, test_omitted = _package_rows(tests, limit)
67
+
68
+ report: dict[str, Any] = {
69
+ "symbols": store.symbol_census(),
70
+ "files": store.file_count(),
71
+ "edges": stats.total,
72
+ "unresolved_ratio": stats.unresolved_ratio,
73
+ "packages": package_rows,
74
+ "test_packages": test_rows,
75
+ "next": [
76
+ "cgis_find_symbol(<name>, fqn_prefix=<prefix>) — symbols inside a package",
77
+ "cgis_metrics(scope=[<prefix>]) — coupling and God classes in one package",
78
+ "cgis_get_structure(<fqn>) — members of a module or class, once you have its "
79
+ "FQN from cgis_find_symbol (a package prefix is not a node)",
80
+ "cgis_validate() — how much of the graph resolved",
81
+ ],
82
+ }
83
+ if omitted:
84
+ report["packages_omitted"] = omitted
85
+ if test_omitted:
86
+ report["test_packages_omitted"] = test_omitted
87
+ return report
@@ -4,6 +4,7 @@ import json
4
4
  import os
5
5
  import sqlite3
6
6
  import time
7
+ from collections import Counter
7
8
  from collections.abc import Iterable
8
9
  from dataclasses import dataclass, field
9
10
  from pathlib import Path
@@ -39,6 +40,11 @@ class EdgeStats:
39
40
  top_unresolved: list[tuple[str, int]] = field(default_factory=list) # top UNKNOWN targets
40
41
 
41
42
 
43
+ def _ranked(census: Counter[str]) -> list[tuple[str, int]]:
44
+ """Largest first, ties broken by prefix — `most_common` alone orders ties by rowid."""
45
+ return sorted(census.items(), key=lambda row: (-row[1], row[0]))
46
+
47
+
42
48
  class SQLiteStore:
43
49
  """
44
50
  Deterministic SQLite Graph Store.
@@ -385,6 +391,67 @@ class SQLiteStore:
385
391
  row = self._conn.execute("SELECT COUNT(*) AS n FROM edges").fetchone()
386
392
  return int(row["n"]) if row else 0
387
393
 
394
+ def symbol_census(self) -> dict[str, int]:
395
+ """Internal declared symbols by node type — CLASS/FUNCTION/METHOD, not FILE.
396
+
397
+ Virtual nodes are excluded by file path: `--domains` mints DOMAIN_CONCEPT
398
+ nodes that are INTERNAL and not FILE, so without this a domain counts as a
399
+ symbol and shows up as a `domain:` package row, pushing real packages off a
400
+ capped listing.
401
+ """
402
+ if not self._conn:
403
+ raise RuntimeError(self._error_message)
404
+ rows = self._conn.execute(
405
+ """
406
+ SELECT type, COUNT(*) FROM nodes
407
+ WHERE namespace = 'INTERNAL' AND type != 'FILE' AND file_path != ?
408
+ GROUP BY type ORDER BY type
409
+ """,
410
+ (VIRTUAL_FILE_PATH,),
411
+ ).fetchall()
412
+ return {row[0]: row[1] for row in rows}
413
+
414
+ def file_count(self) -> int:
415
+ """Internal FILE nodes — the size of the tree the graph was built from."""
416
+ if not self._conn:
417
+ raise RuntimeError(self._error_message)
418
+ row = self._conn.execute(
419
+ "SELECT COUNT(*) FROM nodes WHERE namespace = 'INTERNAL' AND type = 'FILE'"
420
+ ).fetchone()
421
+ return int(row[0]) if row else 0
422
+
423
+ def package_census(self, depth: int) -> tuple[list[tuple[str, int]], list[tuple[str, int]]]:
424
+ """Internal symbols grouped by their first `depth` FQN segments, production and test.
425
+
426
+ The prefix never swallows the symbol's own name: `mod.func` at depth 2 is
427
+ `mod`, not `mod.func`, or the map would list one row per symbol. Grouping
428
+ happens in Python because the cut is per-id — SQL would need a recursive
429
+ expression to find the nth dot, for a pass over ids this already makes.
430
+
431
+ Virtual `domain:` nodes are excluded with the same file-path predicate
432
+ `symbol_census` uses, and ties are broken by prefix so the map is
433
+ reproducible across re-ingests.
434
+ """
435
+ if not self._conn:
436
+ raise RuntimeError(self._error_message)
437
+ # Clamped here too, not only in `build_overview`: depth 0 would key every
438
+ # row on the empty string, which is not an FQN prefix anything accepts.
439
+ depth = max(depth, 1)
440
+ rows = self._conn.execute(
441
+ """
442
+ SELECT id, is_test FROM nodes
443
+ WHERE namespace = 'INTERNAL' AND type != 'FILE' AND file_path != ?
444
+ """,
445
+ (VIRTUAL_FILE_PATH,),
446
+ ).fetchall()
447
+ production: Counter[str] = Counter()
448
+ tests: Counter[str] = Counter()
449
+ for node_id, is_test in rows:
450
+ parts = node_id.split(".")
451
+ prefix = ".".join(parts[: min(depth, max(len(parts) - 1, 1))])
452
+ (tests if is_test else production)[prefix] += 1
453
+ return _ranked(production), _ranked(tests)
454
+
388
455
  def get_node(self, node_id: str) -> Node | None:
389
456
  """Return a single node by FQN, or None if not found."""
390
457
  if not self._conn:
@@ -0,0 +1,74 @@
1
+ """The overview measured against a real tree, not a flat fixture (#478, #486 review).
2
+
3
+ The unit fixture is flat, so every prefix it can produce is a module — which is
4
+ exactly the shape that always works. cgis's own `src/` has the shape that does
5
+ not: `cgis/query/` has no `__init__.py`, so no node bears that name, and
6
+ `cgis/guardian/` has one whose containment edges point at nothing. A promise
7
+ about "the next call" has to be checked here or it checks nothing.
8
+ """
9
+
10
+ from cgis.core.models import Node
11
+ from cgis.query.analysis.overview import build_overview
12
+ from cgis.query.render.metrics import DuckDBAnalyzer
13
+ from cgis.storage.sqlite_store import SQLiteStore
14
+
15
+
16
+ def _prefixes(store: SQLiteStore) -> list[str]:
17
+ report = build_overview(store)
18
+ rows = report["packages"] + report["test_packages"]
19
+ assert rows, "cgis's own graph has packages"
20
+ return [str(row["prefix"]) for row in rows]
21
+
22
+
23
+ def test_every_prefix_finds_symbols_under_it(
24
+ root_graph_data: tuple[SQLiteStore, list[Node], list],
25
+ ) -> None:
26
+ """`cgis_find_symbol(fqn_prefix=…)` is the documented next call, so it must hold here.
27
+
28
+ Walked the way an agent would: take a symbol the package really holds, search
29
+ for it scoped to the prefix, and expect it back.
30
+ """
31
+ store, nodes, _edges = root_graph_data
32
+
33
+ for prefix in _prefixes(store):
34
+ under = [n for n in nodes if n.id.startswith(f"{prefix}.") and n.name]
35
+ assert under, f"{prefix} names a package with no symbols under it"
36
+ wanted = under[0]
37
+ matches = store.search_nodes(wanted.name, kinds=(), fqn_prefix=prefix, limit=20)
38
+ assert any(node.id == wanted.id for node in matches), f"{prefix}: {wanted.id} not found"
39
+
40
+
41
+ def test_every_prefix_scopes_a_metrics_run(
42
+ root_graph_data: tuple[SQLiteStore, list, list],
43
+ ) -> None:
44
+ """`cgis_metrics(scope=[…])` is the other documented next call."""
45
+ store, _nodes, _edges = root_graph_data
46
+
47
+ for prefix in _prefixes(store):
48
+ with DuckDBAnalyzer(store.db_path) as analyzer:
49
+ coupling = analyzer.get_coupling_metrics(limit=3, scope=[prefix])
50
+ assert coupling, f"{prefix} scopes a metrics run to nothing"
51
+ assert all(metric.node_id.startswith(prefix) for metric in coupling)
52
+
53
+
54
+ def test_the_map_names_packages_that_are_not_nodes(
55
+ root_graph_data: tuple[SQLiteStore, list, list],
56
+ ) -> None:
57
+ """Why `cgis_get_structure` is *not* offered for a prefix.
58
+
59
+ A package is a node only when it has an `__init__.py`, and even then holds no
60
+ members: `CONTAINS`/`DECLARES` run file → symbol, never package → module. This
61
+ pins the fact the docs now state, so a future graph model that adds package
62
+ nodes fails here and the wording gets revisited.
63
+ """
64
+ store, _nodes, _edges = root_graph_data
65
+ prefixes = _prefixes(store)
66
+
67
+ missing = [prefix for prefix in prefixes if store.get_node(prefix) is None]
68
+ childless = [
69
+ prefix
70
+ for prefix in prefixes
71
+ if store.get_node(prefix) is not None and not store.get_outgoing_edges(prefix)
72
+ ]
73
+ assert missing, "cgis/query has no __init__.py — expected some prefixes to have no node"
74
+ assert childless, "a package node holds no members of its own"
@@ -32,7 +32,13 @@ _KNOWN_FABRICATED = frozenset(
32
32
  }
33
33
  )
34
34
 
35
- _EXPECTED_PLACEHOLDERS = 46
35
+ #: Re-measured on a fresh self-ingest, 2026-09-17: 54 on `main`, 57 with the three
36
+ #: `cgis_overview` store methods added here. All three are `self._conn.execute(...)`
37
+ #: on a `sqlite3.Connection`, which rule D1 declines by design — a stdlib receiver
38
+ #: has no node to resolve to. The centre was 46 and had drifted 8 low, so the band
39
+ #: was measuring less each time something was added to a store method rather than
40
+ #: catching a regression.
41
+ _EXPECTED_PLACEHOLDERS = 57
36
42
  _TOLERANCE = 10
37
43
 
38
44