codegraph-brain 0.17.0__tar.gz → 0.18.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 (353) hide show
  1. codegraph_brain-0.18.0/.github/test-count-baseline +1 -0
  2. codegraph_brain-0.18.0/.release-please-manifest.json +3 -0
  3. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/CHANGELOG.md +22 -0
  4. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/CLAUDE.md +3 -2
  5. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/Makefile +15 -1
  6. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/PKG-INFO +7 -7
  7. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/README.md +6 -6
  8. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/architecture/HOW_IT_WORKS.md +2 -1
  9. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/architecture/diagrams/pipeline_flow.mermaid +3 -3
  10. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/how-to/MCP_REFERENCE.md +35 -0
  11. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-09-05-annotation-graph-design.md +264 -24
  12. codegraph_brain-0.18.0/docs/specs/plans/2026-09-05-annotation-graph-pr2.md +687 -0
  13. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/pyproject.toml +1 -1
  14. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/api/mcp_server.py +44 -0
  15. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/cli.py +95 -0
  16. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/core/models.py +22 -1
  17. codegraph_brain-0.18.0/src/cgis/core/paths.py +39 -0
  18. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/_python_ast.py +119 -0
  19. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/_python_classes.py +23 -2
  20. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/_python_functions.py +80 -5
  21. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/_python_imports.py +15 -2
  22. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/python_extractor.py +269 -8
  23. codegraph_brain-0.18.0/src/cgis/query/context/orphans.py +123 -0
  24. codegraph_brain-0.18.0/src/cgis/resolver/indices.py +448 -0
  25. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/resolver/symbols.py +94 -7
  26. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/storage/sqlite_store.py +58 -4
  27. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_annotation_calibration.py +77 -8
  28. codegraph_brain-0.18.0/tests/self_parsing/test_receiver_resolution.py +242 -0
  29. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_cli.py +99 -0
  30. codegraph_brain-0.18.0/tests/unit/test_name_load_positions.py +128 -0
  31. codegraph_brain-0.18.0/tests/unit/test_orphans.py +234 -0
  32. codegraph_brain-0.18.0/tests/unit/test_paths.py +58 -0
  33. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_resolver.py +743 -0
  34. codegraph_brain-0.18.0/tests/unit/test_resolver_indices.py +353 -0
  35. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/uv.lock +1 -1
  36. codegraph_brain-0.17.0/.github/test-count-baseline +0 -1
  37. codegraph_brain-0.17.0/.release-please-manifest.json +0 -3
  38. codegraph_brain-0.17.0/src/cgis/resolver/indices.py +0 -203
  39. codegraph_brain-0.17.0/tests/unit/test_resolver_indices.py +0 -190
  40. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.claude-plugin/marketplace.json +0 -0
  41. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.gitattributes +0 -0
  42. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.github/workflows/autodoc.yml +0 -0
  43. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.github/workflows/ci.yml +0 -0
  44. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.github/workflows/guardian.yml +0 -0
  45. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.github/workflows/pr-title.yml +0 -0
  46. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.github/workflows/release-please.yml +0 -0
  47. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.gitignore +0 -0
  48. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.pre-commit-config.yaml +0 -0
  49. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/.python-version +0 -0
  50. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/CONTRIBUTING.md +0 -0
  51. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/LICENSE +0 -0
  52. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/PRIVACY.md +0 -0
  53. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/CURATION.md +0 -0
  54. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/calibration.jsonl +0 -0
  55. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/246-cross-vendor/README.md +0 -0
  56. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/246-cross-vendor/free-nemotron-quota-cutoff.jsonl +0 -0
  57. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/401-evidence/README.md +0 -0
  58. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/401-evidence/pr-399-control-rows.jsonl +0 -0
  59. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/401-evidence/pr-399-recording.json +0 -0
  60. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/401-evidence/pr-399-treatment-rows.jsonl +0 -0
  61. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/407-no-checker-appeal/README.md +0 -0
  62. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-directive-rows.jsonl +0 -0
  63. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-prohibition-rows.jsonl +0 -0
  64. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-122.yaml +0 -0
  65. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-140.yaml +0 -0
  66. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-141.yaml +0 -0
  67. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-142.yaml +0 -0
  68. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-143.yaml +0 -0
  69. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-144.yaml +0 -0
  70. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-278.yaml +0 -0
  71. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/pr-313.yaml +0 -0
  72. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/guardian/results.jsonl +0 -0
  73. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian/README.md +0 -0
  74. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian/cal_dot_com.json +0 -0
  75. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian/discourse.json +0 -0
  76. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian/grafana.json +0 -0
  77. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian/keycloak.json +0 -0
  78. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian/sentry.json +0 -0
  79. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-judged.jsonl +0 -0
  80. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-p3-judged-run1.jsonl +0 -0
  81. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-p3-judged-run1.jsonl.corrupted-backup +0 -0
  82. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-p3-run1.jsonl +0 -0
  83. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-p3-run2.jsonl +0 -0
  84. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-p3-run3.jsonl +0 -0
  85. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-plan.json +0 -0
  86. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-repeat-judged.jsonl +0 -0
  87. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-repeat-reviews.jsonl +0 -0
  88. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/benchmarks/martian-reviews.jsonl +0 -0
  89. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/data/.gitkeep +0 -0
  90. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/AUDIT.md +0 -0
  91. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/CASE_STUDY.md +0 -0
  92. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/GUARDIAN_LOCAL_BENCH.md +0 -0
  93. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/GUARDIAN_REMOTE_OLLAMA.md +0 -0
  94. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/architecture/ONTOLOGY.md +0 -0
  95. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/architecture/PATTERNS_AND_TRIADS.md +0 -0
  96. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/architecture/SELF_PORTRAIT.md +0 -0
  97. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/architecture/health_badge.json +0 -0
  98. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/assets/.gitignore +0 -0
  99. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/assets/cgis-app-avatar.png +0 -0
  100. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/assets/cgis-app-avatar.svg +0 -0
  101. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/assets/generate_avatar.py +0 -0
  102. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/examples/.gitkeep +0 -0
  103. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/how-to/AGENT_ONBOARDING.md +0 -0
  104. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/how-to/CLI_USAGE.md +0 -0
  105. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/lab-notes/2026-06-11-chunked-review-negative-result.md +0 -0
  106. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/ontology/.gitkeep +0 -0
  107. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/ontology/core.yaml +0 -0
  108. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/ontology/domains.yaml +0 -0
  109. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/ontology/patterns.yaml +0 -0
  110. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/ontology/tolerances.lock +0 -0
  111. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-09-domain-pattern-fingerprint-design.md +0 -0
  112. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-09-pattern-alphabet-motif-basis-design.md +0 -0
  113. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-10-guardian-sprint-design.md +0 -0
  114. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-11-fastapi-di-edges-design.md +0 -0
  115. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-11-guardian-chunked-review-design.md +0 -0
  116. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-11-guardian-chunker-design.md +0 -0
  117. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-11-mcp-drift-validate-fqn-design.md +0 -0
  118. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-11-resolver-split-design.md +0 -0
  119. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-11-symbol-import-edges-design.md +0 -0
  120. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-12-drift-empty-domains-design.md +0 -0
  121. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-12-gate-semantics-design.md +0 -0
  122. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-12-init-ontology-design.md +0 -0
  123. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-12-release-please-ci-design.md +0 -0
  124. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-13-suggest-packages-design.md +0 -0
  125. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-06-13-tangle-anti-pattern-design.md +0 -0
  126. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-29-guardian-skeptic-scoring-design.md +0 -0
  127. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-cgis-fractal-design.md +0 -0
  128. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-cgis-fractal-plan.md +0 -0
  129. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-chunk-source-filter-design.md +0 -0
  130. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-chunk-source-filter-plan.md +0 -0
  131. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-genai-client-close-design.md +0 -0
  132. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-genai-client-close-plan.md +0 -0
  133. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-guardian-precision-bench-design.md +0 -0
  134. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-guardian-precision-bench-plan.md +0 -0
  135. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-guardian-timeout-retry-design.md +0 -0
  136. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-30-guardian-timeout-retry-plan.md +0 -0
  137. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-07-31-finder-bug-class-taxonomy.md +0 -0
  138. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-08-01-aura-autoevolution-poc.md +0 -0
  139. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-08-11-guardian-code-review-bench.md +0 -0
  140. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/2026-08-14-review-fingerprint-design.md +0 -0
  141. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/BLUEPRINT.md +0 -0
  142. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/PRD.md +0 -0
  143. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/TDD.md +0 -0
  144. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-09-fingerprint-drift.md +0 -0
  145. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-10-guardian-context-skeptic-inline.md +0 -0
  146. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-10-guardian-structured-findings-bench.md +0 -0
  147. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-10-motif-basis-part-b.md +0 -0
  148. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-10-unified-pattern-alphabet.md +0 -0
  149. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-11-fastapi-di-edges.md +0 -0
  150. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-11-guardian-chunked-review.md +0 -0
  151. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-11-guardian-chunker.md +0 -0
  152. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-11-mcp-drift-validate-fqn.md +0 -0
  153. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-11-resolver-split.md +0 -0
  154. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-12-drift-empty-domains.md +0 -0
  155. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-12-gate-semantics.md +0 -0
  156. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-12-init-ontology.md +0 -0
  157. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-12-release-please-ci.md +0 -0
  158. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-12-symbol-import-edges.md +0 -0
  159. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-06-13-suggest-packages.md +0 -0
  160. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-07-29-guardian-skeptic-scoring.md +0 -0
  161. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-08-14-review-fingerprint.md +0 -0
  162. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/docs/specs/plans/2026-09-05-annotation-graph-pr1.md +0 -0
  163. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/main.py +0 -0
  164. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/plugin/.claude-plugin/plugin.json +0 -0
  165. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/plugin/.mcp.json +0 -0
  166. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/plugin/README.md +0 -0
  167. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/plugin/skills/cgis/SKILL.md +0 -0
  168. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/plugin/skills/ingest/SKILL.md +0 -0
  169. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/release-please-config.json +0 -0
  170. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/backfill_calibration_fingerprint.py +0 -0
  171. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/backfill_review_fingerprint.py +0 -0
  172. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/check_pytest_raises.py +0 -0
  173. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/check_test_count.py +0 -0
  174. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/colab_bench.sh +0 -0
  175. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/gen_ideal_graph.py +0 -0
  176. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/generate_health.py +0 -0
  177. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/generate_mcp_ref.py +0 -0
  178. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/generate_schema_docs.py +0 -0
  179. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/guardian_bench.py +0 -0
  180. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/guardian_calibrate.py +0 -0
  181. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/guardian_martian.py +0 -0
  182. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/guardian_replay_skeptic.py +0 -0
  183. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/guardian_review.py +0 -0
  184. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/inject_readme_graph.py +0 -0
  185. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/ollama_visitor.sh +0 -0
  186. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/probe_closure_gap.py +0 -0
  187. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/probe_tier_ladder.py +0 -0
  188. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/recordings_from_corpus.py +0 -0
  189. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/scripts/skeptic_arms.py +0 -0
  190. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/__init__.py +0 -0
  191. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/__main__.py +0 -0
  192. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/api/.gitkeep +0 -0
  193. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/api/__init__.py +0 -0
  194. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/core/.gitkeep +0 -0
  195. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/.gitkeep +0 -0
  196. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/_python_annotations.py +0 -0
  197. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/_python_types.py +0 -0
  198. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/base.py +0 -0
  199. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/registry.py +0 -0
  200. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/extractors/typescript_extractor.py +0 -0
  201. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/__init__.py +0 -0
  202. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/axes.py +0 -0
  203. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/bench.py +0 -0
  204. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/calibrate.py +0 -0
  205. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/chunked.py +0 -0
  206. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/chunker.py +0 -0
  207. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/collector.py +0 -0
  208. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/core.py +0 -0
  209. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/diff_index.py +0 -0
  210. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/evidence.py +0 -0
  211. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/findings.py +0 -0
  212. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/github_poster.py +0 -0
  213. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/martian.py +0 -0
  214. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/metrics.py +0 -0
  215. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/prompts.py +0 -0
  216. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/providers/__init__.py +0 -0
  217. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/providers/base.py +0 -0
  218. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/providers/gemini.py +0 -0
  219. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/providers/mistral.py +0 -0
  220. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/providers/ollama.py +0 -0
  221. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/providers/openrouter.py +0 -0
  222. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/recording.py +0 -0
  223. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/render.py +0 -0
  224. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/review_fingerprint.py +0 -0
  225. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/runner.py +0 -0
  226. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/guardian/skeptic.py +0 -0
  227. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/pipeline.py +0 -0
  228. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/py.typed +0 -0
  229. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/analysis/__init__.py +0 -0
  230. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/analysis/analyzer.py +0 -0
  231. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/analysis/anomaly.py +0 -0
  232. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/analysis/cohesion.py +0 -0
  233. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/analysis/health.py +0 -0
  234. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/analysis/suggest_service.py +0 -0
  235. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/context/__init__.py +0 -0
  236. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/context/audit.py +0 -0
  237. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/context/context_service.py +0 -0
  238. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/context/prompt.py +0 -0
  239. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/context/snippet.py +0 -0
  240. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/__init__.py +0 -0
  241. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/_scc.py +0 -0
  242. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/drift.py +0 -0
  243. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/drift_service.py +0 -0
  244. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/fingerprint.py +0 -0
  245. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/fractal.py +0 -0
  246. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/ontology_init.py +0 -0
  247. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/quotient.py +0 -0
  248. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/drift/triads.py +0 -0
  249. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/engine.py +0 -0
  250. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/fqn.py +0 -0
  251. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/render/__init__.py +0 -0
  252. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/render/graph_json.py +0 -0
  253. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/render/mermaid.py +0 -0
  254. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/query/render/metrics.py +0 -0
  255. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/resolver/.gitkeep +0 -0
  256. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/resolver/__init__.py +0 -0
  257. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/resolver/engine.py +0 -0
  258. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/resolver/uplift.py +0 -0
  259. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/src/cgis/storage/.gitkeep +0 -0
  260. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/integration/.gitkeep +0 -0
  261. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/.gitkeep +0 -0
  262. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/__init__.py +0 -0
  263. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/conftest.py +0 -0
  264. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_architecture.py +0 -0
  265. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_drift.py +0 -0
  266. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_fractal.py +0 -0
  267. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_init_ontology_roundtrip.py +0 -0
  268. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_self_parse.py +0 -0
  269. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_self_parse_ts.py +0 -0
  270. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/self_parsing/test_suggest.py +0 -0
  271. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/.gitkeep +0 -0
  272. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/conftest.py +0 -0
  273. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/guardian_stubs.py +0 -0
  274. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/review_path_inventory.txt +0 -0
  275. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test___main__.py +0 -0
  276. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_analyzer.py +0 -0
  277. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_annotation_edges.py +0 -0
  278. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_audit.py +0 -0
  279. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_backfill_calibration_fingerprint.py +0 -0
  280. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_backfill_review_fingerprint.py +0 -0
  281. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_check_pytest_raises.py +0 -0
  282. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_check_test_count.py +0 -0
  283. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_cohesion.py +0 -0
  284. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_context_service.py +0 -0
  285. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_di_acceptance.py +0 -0
  286. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_drift.py +0 -0
  287. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_drift_service.py +0 -0
  288. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_extractor_registry.py +0 -0
  289. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_fingerprint.py +0 -0
  290. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_fqn.py +0 -0
  291. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_fractal.py +0 -0
  292. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_gen_ideal_graph.py +0 -0
  293. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_generate_mcp_ref.py +0 -0
  294. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_graph_json.py +0 -0
  295. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_axes.py +0 -0
  296. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_bench.py +0 -0
  297. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_bench_script.py +0 -0
  298. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_calibrate.py +0 -0
  299. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_calibrate_script.py +0 -0
  300. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_chunked.py +0 -0
  301. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_chunker.py +0 -0
  302. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_collector.py +0 -0
  303. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_core.py +0 -0
  304. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_diff_index.py +0 -0
  305. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_evidence.py +0 -0
  306. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_findings.py +0 -0
  307. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_martian.py +0 -0
  308. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_martian_script.py +0 -0
  309. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_martian_union.py +0 -0
  310. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_metrics.py +0 -0
  311. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_mistral_sampling.py +0 -0
  312. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_ollama_sampling.py +0 -0
  313. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_ollama_truncation.py +0 -0
  314. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_openrouter.py +0 -0
  315. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_poster.py +0 -0
  316. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_providers.py +0 -0
  317. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_providers_name.py +0 -0
  318. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_recording.py +0 -0
  319. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_render.py +0 -0
  320. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_replay_skeptic.py +0 -0
  321. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_review_script.py +0 -0
  322. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_runner.py +0 -0
  323. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_salvage.py +0 -0
  324. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_guardian_skeptic.py +0 -0
  325. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_health_scorer.py +0 -0
  326. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_import_acceptance.py +0 -0
  327. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_mcp_server.py +0 -0
  328. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_mermaid.py +0 -0
  329. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_metrics.py +0 -0
  330. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_models.py +0 -0
  331. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_ontology_compliance.py +0 -0
  332. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_ontology_init.py +0 -0
  333. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_patterns_yaml.py +0 -0
  334. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_pipeline.py +0 -0
  335. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_prompt.py +0 -0
  336. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_python_annotations.py +0 -0
  337. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_python_extractor.py +0 -0
  338. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_quotient.py +0 -0
  339. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_recordings_from_corpus.py +0 -0
  340. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_resolver_symbols.py +0 -0
  341. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_review_fingerprint_closure.py +0 -0
  342. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_review_fingerprint_contract.py +0 -0
  343. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_review_fingerprint_digest.py +0 -0
  344. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_review_fingerprint_record.py +0 -0
  345. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_self_types.py +0 -0
  346. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_skeptic_arms.py +0 -0
  347. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_snippet.py +0 -0
  348. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_sqlite_store.py +0 -0
  349. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_suggest_service.py +0 -0
  350. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_temperature_source.py +0 -0
  351. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_triads.py +0 -0
  352. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_typescript_extractor.py +0 -0
  353. {codegraph_brain-0.17.0 → codegraph_brain-0.18.0}/tests/unit/test_uplift.py +0 -0
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.18.0"
3
+ }
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.18.0](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.17.0...codegraph-brain-v0.18.0) (2026-09-06)
4
+
5
+
6
+ ### Features
7
+
8
+ * **extractors:** a class named as a value is a reference (D10, [#415](https://github.com/zaebee/codegraph-brain/issues/415)) ([#430](https://github.com/zaebee/codegraph-brain/issues/430)) ([aea4076](https://github.com/zaebee/codegraph-brain/commit/aea4076b45d0761f50bb989936e89c8054402372))
9
+ * **extractors:** a decorator's arguments are edges, and a decorated class keeps its own ([#429](https://github.com/zaebee/codegraph-brain/issues/429)) ([#434](https://github.com/zaebee/codegraph-brain/issues/434)) ([fd0c63f](https://github.com/zaebee/codegraph-brain/commit/fd0c63f1f887a0b65a433d01571654ae79419ef3))
10
+ * **query:** orphan classes — what production no longer builds ([#415](https://github.com/zaebee/codegraph-brain/issues/415)) ([#431](https://github.com/zaebee/codegraph-brain/issues/431)) ([3b4db3c](https://github.com/zaebee/codegraph-brain/commit/3b4db3cb231d43ae388b080d64d19b3244739017))
11
+ * **resolver:** resolve self.<attr>.<method> through the declared receiver ([#414](https://github.com/zaebee/codegraph-brain/issues/414)) ([#423](https://github.com/zaebee/codegraph-brain/issues/423)) ([a1c94a2](https://github.com/zaebee/codegraph-brain/commit/a1c94a2e4629da955deef761467730a7d711c3fe))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * **extractors:** attribute a module-level or class-body call to its owner ([#416](https://github.com/zaebee/codegraph-brain/issues/416)) ([#428](https://github.com/zaebee/codegraph-brain/issues/428)) ([c9f39b8](https://github.com/zaebee/codegraph-brain/commit/c9f39b81bf3a644441b7b5a3215df2d6b39b9489))
17
+ * **resolver:** an import prefix that reaches a node is first-party, not external ([#424](https://github.com/zaebee/codegraph-brain/issues/424)) ([#426](https://github.com/zaebee/codegraph-brain/issues/426)) ([50f8b7c](https://github.com/zaebee/codegraph-brain/commit/50f8b7c03d716c25f9341a879c76a8707f3853fb))
18
+ * **resolver:** resolve a name through the package that re-exports it ([#417](https://github.com/zaebee/codegraph-brain/issues/417)) ([#427](https://github.com/zaebee/codegraph-brain/issues/427)) ([ef76f95](https://github.com/zaebee/codegraph-brain/commit/ef76f9546b4477d4736406eabe417e6e49e68e23))
19
+
20
+
21
+ ### Documentation
22
+
23
+ * auto-sync architecture graph and MCP reference ([#433](https://github.com/zaebee/codegraph-brain/issues/433)) ([40af3ee](https://github.com/zaebee/codegraph-brain/commit/40af3ee6839b53a953124e25f1f39b5379bff890))
24
+
3
25
  ## [0.17.0](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.16.0...codegraph-brain-v0.17.0) (2026-09-05)
4
26
 
5
27
 
@@ -35,8 +35,9 @@ make format && make lint && make type-check && make pytest && make doc-coverage
35
35
  # Single test
36
36
  uv run pytest tests/unit/test_python_extractor.py::test_extract_simple_function -v
37
37
 
38
- # Tests with coverage
39
- uv run pytest --cov=cgis --cov-report=html
38
+ # Line coverage (same scope as CI — see the Makefile comment on why scripts/ counts)
39
+ make coverage # runs: uv run pytest --cov=cgis --cov=scripts --cov-report=term-missing
40
+ make coverage-html # same, writes htmlcov/
40
41
  ```
41
42
 
42
43
  ## Architecture
@@ -1,4 +1,4 @@
1
- .PHONY: format lint type-check pytest doc-coverage check \
1
+ .PHONY: format lint type-check pytest doc-coverage coverage coverage-html check \
2
2
  ui-dev ui-build ui-test ui-lint ui-format ui-preview ui-analyze ui-check \
3
3
  all-checks
4
4
 
@@ -19,6 +19,20 @@ pytest:
19
19
  doc-coverage:
20
20
  uv run interrogate src
21
21
 
22
+ # Line coverage. `--cov=scripts` is not optional and not cosmetic: sonar.sources
23
+ # is `src,scripts`, so SonarCloud counts every executable line under scripts/ as
24
+ # a line to cover whether or not the report mentions it. Omitting the directory
25
+ # does not exclude it — it reports all of it as uncovered, which once put
26
+ # new-code coverage at 37.8% on a PR whose script was covered at 99% locally.
27
+ # Keep this scope identical to the Pytest step in .github/workflows/ci.yml, or
28
+ # the number you read here is not the number the gate reads.
29
+ coverage:
30
+ uv run pytest --cov=cgis --cov=scripts --cov-report=term-missing
31
+
32
+ # Same scope, browsable. Writes htmlcov/ (git-ignored); open htmlcov/index.html.
33
+ coverage-html:
34
+ uv run pytest --cov=cgis --cov=scripts --cov-report=html
35
+
22
36
  # Full Python verification (run before every commit/PR)
23
37
  check: format lint type-check pytest doc-coverage
24
38
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codegraph-brain
3
- Version: 0.17.0
3
+ Version: 0.18.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
@@ -198,8 +198,8 @@ classDef stdlibNode fill:#eceff1,stroke:#607d8b,stroke-width:1px,color:#455a64;
198
198
  classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dasharray: 3 3,color:#bf360c;
199
199
 
200
200
  subgraph sg_models["models.py"]
201
- models_Edge["Edge (models.py:117)"]:::classNode
202
- models_Node["Node (models.py:83)"]:::classNode
201
+ models_Edge["Edge (models.py:138)"]:::classNode
202
+ models_Node["Node (models.py:85)"]:::classNode
203
203
  end
204
204
  subgraph sg_pipeline["pipeline.py"]
205
205
  pipeline_IngestionPipeline_get_extractor["_get_extractor (pipeline.py:245)"]:::methodNode
@@ -217,7 +217,7 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
217
217
  uplift_SemanticUpliftEngine_execute_uplift["execute_uplift (uplift.py:91)"]:::methodNode
218
218
  end
219
219
  subgraph sg_sqlite_store["sqlite_store.py"]
220
- sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:28)"]:::classNode
220
+ sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:30)"]:::classNode
221
221
  end
222
222
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Node
223
223
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Edge
@@ -234,8 +234,8 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
234
234
 
235
235
  | Symbol | Type | File |
236
236
  |--------|------|------|
237
- | `Node` | CLASS | [`models.py:83`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L83) |
238
- | `Edge` | CLASS | [`models.py:117`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L117) |
237
+ | `Node` | CLASS | [`models.py:85`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L85) |
238
+ | `Edge` | CLASS | [`models.py:138`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L138) |
239
239
  | `run` | METHOD | [`pipeline.py:51`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L51) |
240
240
  | `_process_file` | METHOD | [`pipeline.py:155`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L155) |
241
241
  | `_is_noop_incremental` | METHOD | [`pipeline.py:185`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L185) |
@@ -245,7 +245,7 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
245
245
  | `resolve` | METHOD | [`engine.py:36`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/engine.py#L36) |
246
246
  | `SemanticUpliftEngine` | CLASS | [`uplift.py:66`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L66) |
247
247
  | `execute_uplift` | METHOD | [`uplift.py:91`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L91) |
248
- | `SQLiteStore` | CLASS | [`sqlite_store.py:28`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L28) |
248
+ | `SQLiteStore` | CLASS | [`sqlite_store.py:30`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L30) |
249
249
  <!-- END_CGIS_GRAPH -->
250
250
 
251
251
  ---
@@ -148,8 +148,8 @@ classDef stdlibNode fill:#eceff1,stroke:#607d8b,stroke-width:1px,color:#455a64;
148
148
  classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dasharray: 3 3,color:#bf360c;
149
149
 
150
150
  subgraph sg_models["models.py"]
151
- models_Edge["Edge (models.py:117)"]:::classNode
152
- models_Node["Node (models.py:83)"]:::classNode
151
+ models_Edge["Edge (models.py:138)"]:::classNode
152
+ models_Node["Node (models.py:85)"]:::classNode
153
153
  end
154
154
  subgraph sg_pipeline["pipeline.py"]
155
155
  pipeline_IngestionPipeline_get_extractor["_get_extractor (pipeline.py:245)"]:::methodNode
@@ -167,7 +167,7 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
167
167
  uplift_SemanticUpliftEngine_execute_uplift["execute_uplift (uplift.py:91)"]:::methodNode
168
168
  end
169
169
  subgraph sg_sqlite_store["sqlite_store.py"]
170
- sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:28)"]:::classNode
170
+ sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:30)"]:::classNode
171
171
  end
172
172
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Node
173
173
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Edge
@@ -184,8 +184,8 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
184
184
 
185
185
  | Symbol | Type | File |
186
186
  |--------|------|------|
187
- | `Node` | CLASS | [`models.py:83`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L83) |
188
- | `Edge` | CLASS | [`models.py:117`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L117) |
187
+ | `Node` | CLASS | [`models.py:85`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L85) |
188
+ | `Edge` | CLASS | [`models.py:138`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L138) |
189
189
  | `run` | METHOD | [`pipeline.py:51`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L51) |
190
190
  | `_process_file` | METHOD | [`pipeline.py:155`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L155) |
191
191
  | `_is_noop_incremental` | METHOD | [`pipeline.py:185`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L185) |
@@ -195,7 +195,7 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
195
195
  | `resolve` | METHOD | [`engine.py:36`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/engine.py#L36) |
196
196
  | `SemanticUpliftEngine` | CLASS | [`uplift.py:66`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L66) |
197
197
  | `execute_uplift` | METHOD | [`uplift.py:91`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L91) |
198
- | `SQLiteStore` | CLASS | [`sqlite_store.py:28`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L28) |
198
+ | `SQLiteStore` | CLASS | [`sqlite_store.py:30`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L30) |
199
199
  <!-- END_CGIS_GRAPH -->
200
200
 
201
201
  ---
@@ -85,7 +85,8 @@ CREATE TABLE IF NOT EXISTS nodes (
85
85
  domains TEXT,
86
86
  confidence_score REAL NOT NULL,
87
87
  metadata TEXT,
88
- namespace TEXT NOT NULL DEFAULT 'INTERNAL'
88
+ namespace TEXT NOT NULL DEFAULT 'INTERNAL',
89
+ is_test INTEGER NOT NULL DEFAULT 0
89
90
  );
90
91
 
91
92
  CREATE TABLE IF NOT EXISTS edges (
@@ -8,8 +8,8 @@ classDef stdlibNode fill:#eceff1,stroke:#607d8b,stroke-width:1px,color:#455a64;
8
8
  classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dasharray: 3 3,color:#bf360c;
9
9
 
10
10
  subgraph sg_models["models.py"]
11
- models_Edge["Edge (models.py:117)"]:::classNode
12
- models_Node["Node (models.py:83)"]:::classNode
11
+ models_Edge["Edge (models.py:138)"]:::classNode
12
+ models_Node["Node (models.py:85)"]:::classNode
13
13
  end
14
14
  subgraph sg_pipeline["pipeline.py"]
15
15
  pipeline_IngestionPipeline_get_extractor["_get_extractor (pipeline.py:245)"]:::methodNode
@@ -27,7 +27,7 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
27
27
  uplift_SemanticUpliftEngine_execute_uplift["execute_uplift (uplift.py:91)"]:::methodNode
28
28
  end
29
29
  subgraph sg_sqlite_store["sqlite_store.py"]
30
- sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:28)"]:::classNode
30
+ sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:30)"]:::classNode
31
31
  end
32
32
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Node
33
33
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Edge
@@ -106,6 +106,41 @@ Report per-domain architectural drift against declared ideal patterns.
106
106
 
107
107
  ---
108
108
 
109
+ ## `cgis_find_orphans`
110
+
111
+ Classes nothing in production builds, extends or names — dead-code candidates (#415).
112
+
113
+ Finds classes that no test, type checker or linter flags, because each is
114
+ still imported somewhere: a package re-export keeps a class importable long
115
+ after its last real caller is gone. On one mid-sized backend this reported
116
+ 43 of 1 789 classes, and the hand-written equivalent's findings were all
117
+ real and all deleted.
118
+
119
+ Two filters decide the answer. **Tests are not users** — a class built only
120
+ by its own test is exactly the shape being hunted. **A re-export is not a
121
+ use** — ``IMPORTS_SYMBOL`` does not count, or nothing is ever reported. What
122
+ counts is construction (``CALLS``), inheritance (``EXTENDS``) and being named
123
+ (``REFERENCES`` — an annotation, or a class handed to a framework); the last
124
+ keeps abstract ports and Protocols off the list.
125
+
126
+ ``prefix`` narrows to one package on a dot boundary. ``include_tests`` counts
127
+ test code as a user, turning the report into "unreachable from anywhere".
128
+
129
+ Returns JSON ``{orphans, considered, test_sources}``; each orphan carries
130
+ ``fqn``/``file``/``line``. **A listing is a candidate for deletion, not a
131
+ proof** — a class named only inside a decorator (#429) or arriving through a
132
+ star import is invisible here, so the sweep errs towards reporting a live
133
+ class rather than hiding a dead one. ``test_sources: 0`` in a repository that
134
+ has tests means the graph predates the ``is_test`` column: re-ingest.
135
+
136
+ | Argument | Type | Required | Description |
137
+ | :--- | :--- | :---: | :--- |
138
+ | `db_path` | `string` | | |
139
+ | `prefix` | `any` | | |
140
+ | `include_tests` | `boolean` | | |
141
+
142
+ ---
143
+
109
144
  ## `cgis_find_symbol`
110
145
 
111
146
  Resolve a partial symbol name to candidate FQNs (substring match, ranked).
@@ -18,6 +18,12 @@ type against but nobody constructs looks identical to dead code.
18
18
 
19
19
  ## Measurement basis
20
20
 
21
+ All figures below are from `src/cgis/` at HEAD and a graph ingested from it —
22
+ **except D10's**, which are from five repositories ingested at `c9f39b8`, because
23
+ the effect D10 measures is invisible on cgis. That is not incidental: three of
24
+ this spec's findings (#417, #424, D10) do not reproduce on cgis's own source, so
25
+ a cgis-only measurement is evidence of nothing for resolver and reference work.
26
+
21
27
  All figures below are from `src/cgis/` at HEAD and a graph ingested from it:
22
28
 
23
29
  ```
@@ -59,9 +65,28 @@ The implemented feature was run against `Ownima/owner-api` (`ownima-backend/app`
59
65
  | `REFERENCES` edges | 2 004 (0 pointing at a non-CLASS node) |
60
66
  | classes carrying `self_types` | 677 (2 847 attributes) |
61
67
  | `self.<attr>.<method>` sites, **production only** | 554 |
62
- | …receiver resolvable | **476 (86%)** |
68
+ | …receiver resolvable *(forecast, before PR2 existed)* | 476 (86%) |
69
+ | …**actually resolved once PR2 landed** | **347 (63%)** |
63
70
  | …same, tests only | 445 / 1 732 (26%) |
64
71
 
72
+ That 63% is itself a correction. The first measurement said 85%, and an
73
+ adversarial review showed it counted 136 **fabricated** edges as successes:
74
+ `classify_fqn` judges by root string, and `external_roots` is built from
75
+ import-map values, so a first-party FQN whose import root differs from its
76
+ ingest-relative node root classifies EXTERNAL — and D7's library branch then
77
+ minted a boundary node for a class of ours that does not exist,
78
+ `app.api.dependencies.session.AsyncSessionDep.execute` among them, at confidence
79
+ 1.0. Receiver resolution now refuses a receiver whose path reaches a project
80
+ root; fabrications from this path are 0.
81
+
82
+ The forecast counted a receiver as resolvable when its name appeared in
83
+ `self_types`, without asking whether the declared type is a class that has that
84
+ method. On `owner-api` the two nearly coincide, because its receivers are real
85
+ injected classes. On this repository they do not: the same method forecast 89%
86
+ and the truth is 80%, the gap being attributes declared as builtin containers
87
+ (`self._profiles: dict[...]` records `dict`), which name no class. Quote the
88
+ measured number, not the forecast.
89
+
65
90
  86% against the 66% #414 predicted from its two-source rule: the two sources this
66
91
  design adds (`self.x: T = ...` and `self.x = SomeClass()`) are worth ~20 points on
67
92
  the very repository the issue was filed from. The 26% in tests is 876 unannotated
@@ -282,6 +307,170 @@ a dot-boundary test so `Foo` is not treated as inside `FooBar`). A class
282
307
  naming itself is not evidence anyone uses it, and counting it would
283
308
  manufacture a false negative in the orphan query.
284
309
 
310
+ ### D10 — a class named in a load position is a reference, whatever the position
311
+
312
+ PR3's mandate was to "measure the `response_model=` precision gap (D4) and decide
313
+ it here". The measurement was taken on five codebases and found a *different*
314
+ gap, several times larger. This decision is the answer to it.
315
+
316
+ **The measurement.** A prototype of the orphan query — internal production CLASS
317
+ nodes with no incoming `CALLS`/`EXTENDS`/`REFERENCES` from a non-test source —
318
+ was run on five graphs ingested at `c9f39b8`. Each reported orphan was then
319
+ checked against the ground truth #415's own reference implementation uses: a bare
320
+ name load of that class, in a production file that imports it, outside its own
321
+ module.
322
+
323
+ | repo | internal classes | orphans reported | of those, alive | rate |
324
+ |---|---|---|---|---|
325
+ | cgis | 93 | 2 | 0 | 0% |
326
+ | owner-api | 1 789 | 109 | 44 | **40%** |
327
+ | memory-facets | 383 | 18 | 6 | **33%** |
328
+ | aura-core | 124 | 18 | 6 | **33%** |
329
+ | rich (library) | 181 | 31 | 1 | 3% |
330
+
331
+ Three unrelated applications agree at a third to two-fifths wrong. A mature
332
+ library and cgis itself sit near zero, and the reason is not that they are
333
+ better written: **application code hands classes to a framework, library code
334
+ constructs them.** `app.add_middleware(SecurityMiddleware)` names a class and
335
+ never calls it. This is the third feature in this spec that cgis's own source
336
+ cannot exercise, after star imports (#417) and root-prefix mismatch (#424); a
337
+ measurement taken only on cgis would have reported the query ready.
338
+
339
+ The `response_model=` gap D4 predicted turns out to be two occurrences. The
340
+ positions that actually matter, pooled across all five repos (57 false positives):
341
+
342
+ | shape | n | example |
343
+ |---|---|---|
344
+ | attribute head — enum member, classmethod | 25 | `TransactionType.TOP_UP`, `Rule.stats()` |
345
+ | handed to a call as a value | 18 | `add_middleware(X)`, `route_class=X` |
346
+ | `except` clause | 5 | `except ConversationNotFoundError:` |
347
+ | collection literal | 3 | `("fuel_types", FuelType)` |
348
+ | other — `BinOp`, return annotation, `arg` | 6 | |
349
+
350
+ **The decision: one rule, not five.** Every row above is the same thing — a name
351
+ that resolves to an internal class, appearing in a load position. Enumerating
352
+ positions would take more code, draw arbitrary boundaries, and still miss the
353
+ six-item tail. So the extractor emits a `raw_dep:<name>` candidate for an
354
+ `identifier` in a load position when the name is either in the module's
355
+ `import_map` or the name of a class defined in that file.
356
+
357
+ Three kinds of position are excluded. Those that already carry an edge: the
358
+ `function` field of a call (that is `CALLS`) and an annotation (that is the
359
+ annotation path's own `rawdep_` edge — emitting both made ~80% of the
360
+ name-reference edges duplicates, and the band meant to guard the rule was mostly
361
+ measuring annotations). Those that name something other than a class: the member
362
+ half of an attribute — `TOP_UP` in `TransactionType.TOP_UP` is a field lookup on
363
+ whatever the object turns out to be. And every position that *binds* the name
364
+ rather than using it.
365
+
366
+ That last group is where both reviews of the first implementation converged, and
367
+ they were right: the predicate was a denylist over a grammar, and it accepted 29
368
+ binding positions of the 82 probed — loop and comprehension targets, walrus
369
+ targets, `with`/`except`/`case` aliases, unpacking targets, `nonlocal`, `del`,
370
+ `*args`/`**kwargs` names, type parameters. A binding that emits a reference says
371
+ "this class is used" about a loop variable, which is the exact failure the rule
372
+ exists to prevent.
373
+
374
+ The fix is structural rather than a longer list. `is_name_load` first climbs out
375
+ of grouping nodes — tuples, lists, unpacking targets — so the enclosing
376
+ construct decides, and `for a, (b, Widget) in xs` is a binding while
377
+ `f((a, Widget))` is a use without either shape being enumerated. Two node types
378
+ hold a use and a binding side by side, told apart only by order (`except Widget
379
+ as e` versus `case [1] as Widget`), and one bare identifier under a
380
+ `case_pattern` is a capture while `case Widget():` and `case Widget.A:` are not.
381
+ `tests/unit/test_name_load_positions.py` pins all 60 positions this paragraph
382
+ claims, so a position the list has not met fails there instead of silently
383
+ emitting.
384
+
385
+ **A class reached through its module is also named.** `from app.api import
386
+ validators` then `validators.Rule.confirm_by(...)` gives a head that resolves to
387
+ a module, which D3 drops, so the class stayed invisible — two live owner-api
388
+ classes were reported dead for this. An attribute head therefore records the
389
+ two-segment path alongside the bare name; when the head is itself the class
390
+ (`Widget.SIZE`) the extra candidate resolves to nothing and costs nothing.
391
+
392
+ Everything else in the pipeline is reused unchanged. The source is the nearest
393
+ owner — enclosing function, else class, else module — which is the rule #416
394
+ settled. `_resolved_dep_edge` already drops any candidate that does not resolve
395
+ to an internal CLASS node (D3), so a name that is a function, a variable or a
396
+ third-party symbol never reaches the graph. The edge type is `REFERENCES` (D2)
397
+ at confidence 0.9 (D6), and the self-reference drop in D9 applies unchanged.
398
+
399
+ **Cost — stated here so it is not discovered in review.** Counting distinct
400
+ `(owner, class)` pairs, which is what dedupes into edges:
401
+
402
+ | repo | `REFERENCES` | total edges | growth |
403
+ |---|---|---|---|
404
+ | cgis | 592 → 767 | 5 911 → 6 125 | 4% |
405
+ | owner-api | 2 793 → 7 235 | 70 334 → 74 777 | 6% |
406
+ | memory-facets | 1 182 → 1 660 | 12 773 → 13 251 | 4% |
407
+ | aura-core | 88 → 168 | 4 312 → 4 392 | 2% |
408
+ | rich | 652 → 980 | 7 519 → 7 847 | 4% |
409
+
410
+ The whole graph grows 2–6%. An earlier draft of this table predicted 5–13%; the
411
+ difference is the annotation exclusion above, which removed the duplicate half.
412
+ On cgis the 175 new edges split 172 name references and a handful of annotation
413
+ positions the module-path rule newly reaches.
414
+ `audit_reachability` is unaffected: it traverses enforcement edges only.
415
+ `impact` and `trace_flow` apply no edge-type filter and will widen
416
+ correspondingly, several times more than the PR1 risk already noted.
417
+
418
+ **Measured outcome.** Implemented, reviewed, corrected, and re-run over the same
419
+ five graphs:
420
+
421
+ | repo | orphans before | false | orphans after | false |
422
+ |---|---|---|---|---|
423
+ | cgis | 2 | 0 (0%) | 2 | 0 (0%) |
424
+ | owner-api | 109 | 44 (40%) | 43 | 5 (12%) |
425
+ | memory-facets | 18 | 6 (33%) | 11 | 0 (0%) |
426
+ | aura-core | 18 | 6 (33%) | 9 | 0 (0%) |
427
+ | rich | 31 | 1 (3%) | 14 | 0 (0%) |
428
+
429
+ **Owner-api's five residuals are the ground truth being wrong, not the rule** —
430
+ checked one at a time, and independently confirmed by the review. Each is a
431
+ short-name collision the name-based sweep cannot resolve and an FQN graph can:
432
+ `domains.rating.calculator.UserMetrics` is reported dead while
433
+ `domains/admin/users.py` names `UserMetrics`, but that file imports
434
+ `app.domains.admin.schemas.UserMetrics` and nothing imports the calculator's.
435
+ Likewise `CancelReservationResponse` and `CreateReservationRequest` (both
436
+ shadowed by `grpc.services`), a `Config`, and a `Message`. #415's reference
437
+ implementation names this limitation in its own docstring — "a method sharing a
438
+ name with a live one elsewhere hides in that one's shadow" — and resolving
439
+ through the import map is precisely what a graph buys over a name sweep.
440
+
441
+ An earlier draft of this section claimed the same for all seven residuals of the
442
+ first implementation. **Two of those seven were real misses**, not collisions:
443
+ `api.validators.confirmation.Rule` and `domains.pricing.season_validators.Rule`
444
+ are both live, reached as `confirmation.Rule.confirm_by(...)` through a module
445
+ alias. The module-path rule above closes them. The claim was made from
446
+ hand-checking five of the seven and generalising, which is exactly the habit the
447
+ measurement discipline in this spec exists to prevent.
448
+
449
+ The orphan counts fall further than the false-positive count alone explains
450
+ (owner-api 109 → 43). The extra rescues are same-module uses the ground truth
451
+ excludes by construction: `register_message("entities", "Garage", Garage)`,
452
+ `Dep = Annotated[TransactionWalletMonthlyFilter, Query()]`,
453
+ `{"model": BaseValidationError}`. Spot-checked; all real. memory-facets moved the
454
+ other way, 9 → 11, when the binding-position fix stopped two classes being
455
+ rescued by a loop variable that happened to share their name.
456
+
457
+ **What it cannot do.** Three limits, all measured rather than assumed:
458
+
459
+ * A class mentioned only inside code that is itself dead reads as live. #415's
460
+ reference implementation carries the same limitation and states it plainly:
461
+ it under-reports and never over-reports.
462
+ * A class named only inside a **decorator** is invisible, because `_walk` never
463
+ descends into decorators ([#429](https://github.com/zaebee/codegraph-brain/issues/429)).
464
+ 117 known names appear in owner-api decorators, mostly `response_model=Foo`;
465
+ those classes survive only when a return annotation names them too. This
466
+ raises #429 from an audit-precision issue to an orphan-query one.
467
+ * A class arriving through `from x import *` is not gated in, because the gate is
468
+ the module's `import_map` keys and a star import contributes none. One
469
+ production file in owner-api is affected, none in the other four repositories. #415's reference implementation carries
470
+ the same limitation and states it plainly: it under-reports and never
471
+ over-reports. For a check whose whole value is that people trust it, a false
472
+ "live" is the cheap direction.
473
+
285
474
  ## Work breakdown
286
475
 
287
476
  Three sequential PRs. Each merges before the next starts.
@@ -307,14 +496,50 @@ Serves both issues; neither can be precise without it.
307
496
  * Fixes the placeholder collision as a consequence: two unrelated classes with a
308
497
  same-named attribute no longer share one vertex.
309
498
 
310
- ### PR3#415 orphan query
311
-
312
- * `is_test_path()` + `Node.is_test` + column migration (D5).
313
- * Orphans query: internal CLASS nodes with no incoming `CALLS` or `EXTENDS` from
314
- a non-test source. `IMPORTS_SYMBOL` excluded.
315
- * Surfaced as a CLI command and an MCP tool, following the existing
316
- `audit_reachability` shape.
317
- * Measure the `response_model=` precision gap (D4) and decide it here.
499
+ ### PR3athe name-as-value reference edge (D10)
500
+
501
+ * `raw_dep:` emission for an `identifier` in a load position, gated on the
502
+ module's `import_map` or a class defined in the same file.
503
+ * Exclusions: a call's own `function` field, the member half of an attribute.
504
+ * Re-measure the orphan query's false-positive rate on all five repos of D10;
505
+ the acceptance number is that rate, not an edge count.
506
+ * State the `impact` / `trace_flow` density change in the PR.
507
+
508
+ The measurement that motivated this split is D10. The original PR3 owed a
509
+ decision on the `response_model=` gap; taking that measurement found a larger
510
+ one, and shipping the query on top of it would have meant a check that is wrong
511
+ a third of the time on every application codebase tested.
512
+
513
+ ### PR3b — #415 orphan query
514
+
515
+ * `is_test_path()` (`core/paths.py`) + `Node.is_test` + column migration (D5).
516
+ The flag is *derived* from `file_path` in a model validator rather than passed
517
+ in: the query's correctness rests on every node agreeing what a test is, and
518
+ an extractor that forgot to set it would make its own classes look
519
+ production-reachable. An explicit value is still honoured, because the
520
+ resolver mints virtual boundary nodes with no real file to classify.
521
+ * `find_orphan_classes` (`query/context/orphans.py`): internal `CLASS` nodes,
522
+ not in test files, with no incoming `CALLS` / `EXTENDS` / `REFERENCES` from a
523
+ non-test source. `IMPORTS_SYMBOL` excluded; `CONTAINS` excluded (a module
524
+ holding a class is not a user of it). Measured on owner-api, no `DEPENDS_ON`
525
+ edge targets an internal class, so the three types above are exhaustive.
526
+ * `cgis orphans` and the `cgis_find_orphans` MCP tool, in the
527
+ `audit_reachability` shape — including its non-zero exit on findings, so the
528
+ query gates CI like a linter.
529
+ * The report carries `considered` and `test_sources` alongside the findings.
530
+ The denominator because "3 orphans" means something different out of 40
531
+ classes than out of 1 800; `test_sources` because a graph ingested before this
532
+ column has none, which silently counts every test as production — the CLI says
533
+ so rather than under-reporting quietly.
534
+
535
+ **Measured end to end on owner-api** (`ownima-backend/app`, re-ingested):
536
+ 748 internal production classes, 8 418 test-source nodes, **43 orphans** — the
537
+ same 43 the throwaway measurement script reported in PR3a, which is the
538
+ agreement worth having between a product query and the script that justified it.
539
+ `--prefix domains` narrows to 16 of 284, mostly request/response schemas, which
540
+ is the shape #415 predicted for that subtree. `--include-tests` drops the count
541
+ to 39: four classes are alive only because their own tests build them, which is
542
+ the filter doing its work on real code.
318
543
 
319
544
  ## Testing
320
545
 
@@ -334,6 +559,11 @@ must be re-derived from a fresh ingest, never from the stale root `graph.db`.
334
559
  | Fixture: a class referenced only as `list[OnlyInGeneric]` is **not** an orphan | D9 regresses to `clean_python_type_string` |
335
560
  | Fixture: a class constructed only from `tests/` is reported as an orphan | the `is_test` filter stops being applied |
336
561
  | Fixture: a class referenced only by a parameter annotation is **not** an orphan | the annotation edge stops being emitted |
562
+ | Fixture: a class only ever `except`-ed is **not** an orphan | D10's load-position rule stops covering `except` |
563
+ | Fixture: a class only handed to a call (`add_middleware(X)`) is **not** an orphan | D10 regresses to counting constructions |
564
+ | Fixture: an enum named only as `E.MEMBER` is **not** an orphan | the attribute head stops being collected |
565
+ | Fixture: a *function* handed to a call emits no `REFERENCES` | D3's internal-CLASS filter stops applying to D10 candidates |
566
+ | Five-repo sweep: orphan false-positive rate is 0 on the D10 set | any load position stops being covered |
337
567
 
338
568
  The last two are the pair #415 identifies as load-bearing: without the first all
339
569
  six of its rows read as live, and without the second every abstract port reads as
@@ -347,12 +577,18 @@ against the design as originally written.
347
577
  that D8 does not otherwise address. The `.`-prefixed relative-import case
348
578
  shares the condition and must keep its current behavior. Verify each
349
579
  `NodeNamespace.INTERNAL` consumer before the split.
350
- * **Traversal density (PR1).** `impact` and `trace_flow` apply no edge-type
351
- filter by default, so +583 `REFERENCES` edges will widen their results.
352
- Arguably correct an annotation is a real dependency but it changes existing
353
- output and should be stated in the PR, not discovered.
354
- * **Response-schema precision (PR3).** Known and deliberate (D4). PR3 must report
355
- the measured false-positive rate rather than ship silently.
580
+ * **Traversal density (PR1, and several times more in PR3a).** `impact` and
581
+ `trace_flow` apply no edge-type filter by default, so PR1's +583 `REFERENCES`
582
+ edges widened their results, and D10 roughly doubles `REFERENCES` again on top
583
+ (5–13% of the whole graph, per repo see D10's cost table). Arguably correct:
584
+ naming a class is a real dependency. But it changes existing output, and each
585
+ PR must state the movement rather than let a consumer discover it.
586
+ * **Response-schema precision (PR3).** Predicted by D4 as the query's main
587
+ precision limit. Measured in D10: **two occurrences across five repositories.**
588
+ The real limit was a different one — a class named as a value — which D10
589
+ addresses. Recorded here because the prediction being wrong is the reason PR3
590
+ was split, and a reader of D4 should not still expect `response_model=` to be
591
+ the problem.
356
592
  * **`self_types` is wrong in two rare shapes — PR2 reads this map, so its author
357
593
  must know.** Both were found by an adversarial pass over the extractor's
358
594
  heuristics and both measure **zero occurrences** across this repository and
@@ -371,12 +607,16 @@ against the design as originally written.
371
607
  and `self_types` disagree on the third.
372
608
  * **Measurement basis.** Every number here has a five-week-stale twin in the root
373
609
  `graph.db`. Re-ingest before re-measuring.
374
- * **Module-level construction is invisible — [#416](https://github.com/zaebee/codegraph-brain/issues/416).**
375
- A constructor called at module level emits no `CALLS` edge at all: `_walk`
376
- dispatches a call node only when there is an enclosing function. A class built
377
- only in a registry dict, a singleton, or DI wiring therefore has no incoming
378
- `CALLS`, and PR3's orphan query would report it as dead. On this repository
379
- `PythonExtractor` and `TypeScriptExtractor` are already in that state. This is
380
- a **second** precision limit alongside the `response_model=` gap in D4, and
381
- probably the larger one it was found while validating PR1, not predicted
382
- here. PR3 must measure it before the query is trusted.
610
+ * **Module-level construction — [#416](https://github.com/zaebee/codegraph-brain/issues/416), CLOSED (`c9f39b8`).**
611
+ A constructor called at module level emitted no `CALLS` edge at all, so a class
612
+ built only in a registry dict, a singleton, or DI wiring read as dead. Fixed by
613
+ attributing such a call to its nearest owner. On owner-api it rescued 32 classes
614
+ the query would have reported dead.
615
+
616
+ * **Calls inside a decorator expression are still dropped — [#429](https://github.com/zaebee/codegraph-brain/issues/429), OPEN.**
617
+ `_walk` hands a `decorated_definition` off and never descends into the
618
+ decorators, so `@router.post(..., dependencies=[Depends(guard)])` leaves the
619
+ endpoint with no `DEPENDS_ON` and `cgis audit` reads a superuser-only route as
620
+ unguarded. It does not affect the orphan query — D10's rule covers a class
621
+ *named* in a decorator through the same `import_map` gate — but it is the
622
+ remaining hole in "a call outside a function is still a call".