codegraph-brain 0.25.4__tar.gz → 0.27.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 (398) hide show
  1. codegraph_brain-0.27.0/.github/test-count-baseline +1 -0
  2. codegraph_brain-0.27.0/.github/workflows/ui.yml +68 -0
  3. codegraph_brain-0.27.0/.release-please-manifest.json +3 -0
  4. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/CHANGELOG.md +45 -0
  5. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/PKG-INFO +1 -1
  6. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/architecture/HOW_IT_WORKS.md +32 -35
  7. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/architecture/diagrams/pipeline_flow.mermaid +19 -21
  8. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/how-to/AGENT_ONBOARDING.md +54 -0
  9. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/how-to/MCP_REFERENCE.md +37 -8
  10. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/ontology/patterns.yaml +40 -6
  11. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/ontology/tolerances.lock +5 -5
  12. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-11-fastapi-di-edges-design.md +25 -0
  13. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/pyproject.toml +1 -1
  14. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/guardian_bench.py +1 -1
  15. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/guardian_martian.py +8 -3
  16. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/probe_closure_gap.py +1 -1
  17. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/server.json +2 -2
  18. codegraph_brain-0.27.0/src/cgis/api/auto_refresh.py +110 -0
  19. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/api/mcp_server.py +72 -10
  20. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/cli.py +76 -12
  21. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/_python_functions.py +92 -0
  22. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/python_extractor.py +33 -12
  23. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/registry.py +1 -1
  24. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/typescript_extractor.py +5 -0
  25. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/axes.py +1 -1
  26. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/chunked.py +6 -6
  27. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/collector.py +123 -68
  28. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/core.py +1 -1
  29. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/evidence.py +2 -2
  30. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/martian.py +48 -0
  31. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/runner.py +2 -2
  32. codegraph_brain-0.27.0/src/cgis/import_names.py +84 -0
  33. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/pipeline.py +42 -16
  34. codegraph_brain-0.27.0/src/cgis/python_dependencies.py +154 -0
  35. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/analysis/cohesion.py +35 -0
  36. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/analysis/suggest_service.py +88 -32
  37. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/context/orphans.py +42 -4
  38. codegraph_brain-0.27.0/src/cgis/query/drift/catalog.py +313 -0
  39. codegraph_brain-0.27.0/src/cgis/query/drift/drift.py +175 -0
  40. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/drift_service.py +8 -4
  41. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/fingerprint.py +37 -4
  42. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/ontology_init.py +2 -1
  43. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/quotient.py +48 -12
  44. codegraph_brain-0.27.0/src/cgis/query/drift/scoring.py +414 -0
  45. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/render/mermaid.py +9 -4
  46. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/render/metrics.py +303 -1
  47. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/resolver/engine.py +11 -3
  48. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/resolver/indices.py +166 -15
  49. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/resolver/symbols.py +6 -2
  50. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/storage/sqlite_store.py +113 -27
  51. codegraph_brain-0.27.0/src/cgis/tsconfig_paths.py +268 -0
  52. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/workspaces.py +32 -11
  53. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_annotation_calibration.py +8 -2
  54. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_architecture.py +0 -2
  55. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_drift.py +8 -6
  56. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_suggest.py +25 -2
  57. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_audit.py +44 -0
  58. codegraph_brain-0.27.0/tests/unit/test_auto_refresh.py +143 -0
  59. codegraph_brain-0.27.0/tests/unit/test_class_cohesion.py +247 -0
  60. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_cli.py +26 -0
  61. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_cohesion.py +21 -0
  62. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_drift.py +35 -0
  63. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_extractor_registry.py +1 -1
  64. codegraph_brain-0.27.0/tests/unit/test_features_source.py +114 -0
  65. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_fingerprint.py +33 -0
  66. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_freshness.py +92 -1
  67. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_chunked.py +12 -1
  68. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_collector.py +44 -34
  69. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_core.py +9 -7
  70. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_runner.py +7 -7
  71. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_salvage.py +17 -0
  72. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_mermaid.py +10 -0
  73. codegraph_brain-0.27.0/tests/unit/test_metrics_file_coupling.py +179 -0
  74. codegraph_brain-0.27.0/tests/unit/test_metrics_resolution.py +138 -0
  75. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_orphans.py +77 -0
  76. codegraph_brain-0.27.0/tests/unit/test_python_dependencies.py +193 -0
  77. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_quotient.py +26 -2
  78. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver.py +45 -8
  79. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_indices.py +125 -3
  80. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_suggest_service.py +86 -4
  81. codegraph_brain-0.27.0/tests/unit/test_tsconfig_paths.py +380 -0
  82. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_typescript_extractor.py +12 -0
  83. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/uv.lock +17 -18
  84. codegraph_brain-0.25.4/.github/test-count-baseline +0 -1
  85. codegraph_brain-0.25.4/.release-please-manifest.json +0 -3
  86. codegraph_brain-0.25.4/src/cgis/query/drift/drift.py +0 -867
  87. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.claude-plugin/marketplace.json +0 -0
  88. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.gitattributes +0 -0
  89. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.github/workflows/autodoc.yml +0 -0
  90. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.github/workflows/ci.yml +0 -0
  91. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.github/workflows/guardian.yml +0 -0
  92. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.github/workflows/mcp-registry.yml +0 -0
  93. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.github/workflows/pr-title.yml +0 -0
  94. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.github/workflows/release-please.yml +0 -0
  95. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.gitignore +0 -0
  96. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.pre-commit-config.yaml +0 -0
  97. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/.python-version +0 -0
  98. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/CLAUDE.md +0 -0
  99. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/CONTRIBUTING.md +0 -0
  100. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/LICENSE +0 -0
  101. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/Makefile +0 -0
  102. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/PRIVACY.md +0 -0
  103. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/README.md +0 -0
  104. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/CURATION.md +0 -0
  105. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/calibration.jsonl +0 -0
  106. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/246-cross-vendor/README.md +0 -0
  107. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/246-cross-vendor/free-nemotron-quota-cutoff.jsonl +0 -0
  108. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/401-evidence/README.md +0 -0
  109. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/401-evidence/pr-399-control-rows.jsonl +0 -0
  110. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/401-evidence/pr-399-recording.json +0 -0
  111. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/401-evidence/pr-399-treatment-rows.jsonl +0 -0
  112. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/407-no-checker-appeal/README.md +0 -0
  113. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-directive-rows.jsonl +0 -0
  114. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-prohibition-rows.jsonl +0 -0
  115. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-122.yaml +0 -0
  116. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-140.yaml +0 -0
  117. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-141.yaml +0 -0
  118. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-142.yaml +0 -0
  119. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-143.yaml +0 -0
  120. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-144.yaml +0 -0
  121. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-278.yaml +0 -0
  122. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/pr-313.yaml +0 -0
  123. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/guardian/results.jsonl +0 -0
  124. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian/README.md +0 -0
  125. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian/cal_dot_com.json +0 -0
  126. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian/discourse.json +0 -0
  127. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian/grafana.json +0 -0
  128. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian/keycloak.json +0 -0
  129. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian/sentry.json +0 -0
  130. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-judged.jsonl +0 -0
  131. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-p3-judged-run1.jsonl +0 -0
  132. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-p3-judged-run1.jsonl.corrupted-backup +0 -0
  133. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-p3-run1.jsonl +0 -0
  134. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-p3-run2.jsonl +0 -0
  135. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-p3-run3.jsonl +0 -0
  136. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-plan.json +0 -0
  137. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-repeat-judged.jsonl +0 -0
  138. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-repeat-reviews.jsonl +0 -0
  139. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/benchmarks/martian-reviews.jsonl +0 -0
  140. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/data/.gitkeep +0 -0
  141. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/AUDIT.md +0 -0
  142. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/CASE_STUDY.md +0 -0
  143. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/GUARDIAN_LOCAL_BENCH.md +0 -0
  144. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/GUARDIAN_REMOTE_OLLAMA.md +0 -0
  145. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/architecture/ONTOLOGY.md +0 -0
  146. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/architecture/PATTERNS_AND_TRIADS.md +0 -0
  147. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/architecture/SELF_PORTRAIT.md +0 -0
  148. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/architecture/health_badge.json +0 -0
  149. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/assets/.gitignore +0 -0
  150. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/assets/cgis-app-avatar.png +0 -0
  151. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/assets/cgis-app-avatar.svg +0 -0
  152. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/assets/generate_avatar.py +0 -0
  153. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/examples/.gitkeep +0 -0
  154. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/how-to/CLI_USAGE.md +0 -0
  155. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/lab-notes/2026-06-11-chunked-review-negative-result.md +0 -0
  156. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/ontology/.gitkeep +0 -0
  157. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/ontology/core.yaml +0 -0
  158. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/ontology/domains.yaml +0 -0
  159. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/plans/2026-09-09-graph-freshness.md +0 -0
  160. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-09-domain-pattern-fingerprint-design.md +0 -0
  161. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-09-pattern-alphabet-motif-basis-design.md +0 -0
  162. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-10-guardian-sprint-design.md +0 -0
  163. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-11-guardian-chunked-review-design.md +0 -0
  164. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-11-guardian-chunker-design.md +0 -0
  165. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-11-mcp-drift-validate-fqn-design.md +0 -0
  166. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-11-resolver-split-design.md +0 -0
  167. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-11-symbol-import-edges-design.md +0 -0
  168. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-12-drift-empty-domains-design.md +0 -0
  169. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-12-gate-semantics-design.md +0 -0
  170. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-12-init-ontology-design.md +0 -0
  171. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-12-release-please-ci-design.md +0 -0
  172. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-13-suggest-packages-design.md +0 -0
  173. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-06-13-tangle-anti-pattern-design.md +0 -0
  174. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-29-guardian-skeptic-scoring-design.md +0 -0
  175. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-cgis-fractal-design.md +0 -0
  176. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-cgis-fractal-plan.md +0 -0
  177. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-chunk-source-filter-design.md +0 -0
  178. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-chunk-source-filter-plan.md +0 -0
  179. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-genai-client-close-design.md +0 -0
  180. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-genai-client-close-plan.md +0 -0
  181. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-guardian-precision-bench-design.md +0 -0
  182. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-guardian-precision-bench-plan.md +0 -0
  183. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-guardian-timeout-retry-design.md +0 -0
  184. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-30-guardian-timeout-retry-plan.md +0 -0
  185. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-07-31-finder-bug-class-taxonomy.md +0 -0
  186. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-08-01-aura-autoevolution-poc.md +0 -0
  187. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-08-11-guardian-code-review-bench.md +0 -0
  188. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-08-14-review-fingerprint-design.md +0 -0
  189. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-09-05-annotation-graph-design.md +0 -0
  190. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/2026-09-09-graph-freshness-design.md +0 -0
  191. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/BLUEPRINT.md +0 -0
  192. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/PRD.md +0 -0
  193. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/TDD.md +0 -0
  194. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-09-fingerprint-drift.md +0 -0
  195. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-10-guardian-context-skeptic-inline.md +0 -0
  196. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-10-guardian-structured-findings-bench.md +0 -0
  197. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-10-motif-basis-part-b.md +0 -0
  198. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-10-unified-pattern-alphabet.md +0 -0
  199. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-11-fastapi-di-edges.md +0 -0
  200. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-11-guardian-chunked-review.md +0 -0
  201. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-11-guardian-chunker.md +0 -0
  202. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-11-mcp-drift-validate-fqn.md +0 -0
  203. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-11-resolver-split.md +0 -0
  204. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-12-drift-empty-domains.md +0 -0
  205. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-12-gate-semantics.md +0 -0
  206. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-12-init-ontology.md +0 -0
  207. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-12-release-please-ci.md +0 -0
  208. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-12-symbol-import-edges.md +0 -0
  209. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-06-13-suggest-packages.md +0 -0
  210. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-07-29-guardian-skeptic-scoring.md +0 -0
  211. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-08-14-review-fingerprint.md +0 -0
  212. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-09-05-annotation-graph-pr1.md +0 -0
  213. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/docs/specs/plans/2026-09-05-annotation-graph-pr2.md +0 -0
  214. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/glama.json +0 -0
  215. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/main.py +0 -0
  216. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/plugin/.claude-plugin/plugin.json +0 -0
  217. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/plugin/.mcp.json +0 -0
  218. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/plugin/README.md +0 -0
  219. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/plugin/skills/cgis/SKILL.md +0 -0
  220. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/plugin/skills/ingest/SKILL.md +0 -0
  221. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/release-please-config.json +0 -0
  222. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/backfill_calibration_fingerprint.py +0 -0
  223. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/backfill_review_fingerprint.py +0 -0
  224. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/check_pytest_raises.py +0 -0
  225. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/check_test_count.py +0 -0
  226. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/colab_bench.sh +0 -0
  227. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/gen_ideal_graph.py +0 -0
  228. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/generate_health.py +0 -0
  229. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/generate_mcp_ref.py +0 -0
  230. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/generate_schema_docs.py +0 -0
  231. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/guardian_calibrate.py +0 -0
  232. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/guardian_replay_skeptic.py +0 -0
  233. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/guardian_review.py +0 -0
  234. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/inject_architecture_graph.py +0 -0
  235. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/mcp_registry_gate.sh +0 -0
  236. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/ollama_visitor.sh +0 -0
  237. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/probe_tier_ladder.py +0 -0
  238. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/recordings_from_corpus.py +0 -0
  239. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/scripts/skeptic_arms.py +0 -0
  240. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/__init__.py +0 -0
  241. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/__main__.py +0 -0
  242. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/api/.gitkeep +0 -0
  243. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/api/__init__.py +0 -0
  244. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/core/.gitkeep +0 -0
  245. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/core/coverage.py +0 -0
  246. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/core/freshness.py +0 -0
  247. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/core/generated.py +0 -0
  248. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/core/js_globals.py +0 -0
  249. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/core/models.py +0 -0
  250. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/core/paths.py +0 -0
  251. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/.gitkeep +0 -0
  252. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/_python_annotations.py +0 -0
  253. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/_python_ast.py +0 -0
  254. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/_python_classes.py +0 -0
  255. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/_python_imports.py +0 -0
  256. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/_python_types.py +0 -0
  257. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/_typescript_bindings.py +0 -0
  258. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/extractors/base.py +0 -0
  259. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/__init__.py +0 -0
  260. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/bench.py +0 -0
  261. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/calibrate.py +0 -0
  262. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/chunker.py +0 -0
  263. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/diff_index.py +0 -0
  264. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/findings.py +0 -0
  265. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/github_poster.py +0 -0
  266. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/metrics.py +0 -0
  267. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/prompts.py +0 -0
  268. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/providers/__init__.py +0 -0
  269. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/providers/base.py +0 -0
  270. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/providers/gemini.py +0 -0
  271. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/providers/mistral.py +0 -0
  272. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/providers/ollama.py +0 -0
  273. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/providers/openrouter.py +0 -0
  274. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/recording.py +0 -0
  275. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/render.py +0 -0
  276. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/review_fingerprint.py +0 -0
  277. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/guardian/skeptic.py +0 -0
  278. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/py.typed +0 -0
  279. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/analysis/__init__.py +0 -0
  280. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/analysis/analyzer.py +0 -0
  281. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/analysis/anomaly.py +0 -0
  282. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/analysis/health.py +0 -0
  283. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/analysis/overview.py +0 -0
  284. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/context/__init__.py +0 -0
  285. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/context/audit.py +0 -0
  286. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/context/context_service.py +0 -0
  287. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/context/prompt.py +0 -0
  288. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/context/snippet.py +0 -0
  289. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/__init__.py +0 -0
  290. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/_scc.py +0 -0
  291. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/fractal.py +0 -0
  292. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/drift/triads.py +0 -0
  293. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/engine.py +0 -0
  294. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/fqn.py +0 -0
  295. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/render/__init__.py +0 -0
  296. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/query/render/graph_json.py +0 -0
  297. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/resolver/.gitkeep +0 -0
  298. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/resolver/__init__.py +0 -0
  299. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/resolver/js_builtins.py +0 -0
  300. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/resolver/uplift.py +0 -0
  301. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/src/cgis/storage/.gitkeep +0 -0
  302. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/integration/.gitkeep +0 -0
  303. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/.gitkeep +0 -0
  304. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/__init__.py +0 -0
  305. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/conftest.py +0 -0
  306. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_fractal.py +0 -0
  307. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_init_ontology_roundtrip.py +0 -0
  308. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_overview.py +0 -0
  309. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_receiver_resolution.py +0 -0
  310. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_self_parse.py +0 -0
  311. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/self_parsing/test_self_parse_ts.py +0 -0
  312. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/.gitkeep +0 -0
  313. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/conftest.py +0 -0
  314. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/guardian_stubs.py +0 -0
  315. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/review_path_inventory.txt +0 -0
  316. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test___main__.py +0 -0
  317. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_analyzer.py +0 -0
  318. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_annotation_edges.py +0 -0
  319. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_backfill_calibration_fingerprint.py +0 -0
  320. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_backfill_review_fingerprint.py +0 -0
  321. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_check_pytest_raises.py +0 -0
  322. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_check_test_count.py +0 -0
  323. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_context_service.py +0 -0
  324. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_di_acceptance.py +0 -0
  325. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_drift_service.py +0 -0
  326. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_fqn.py +0 -0
  327. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_fractal.py +0 -0
  328. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_gen_ideal_graph.py +0 -0
  329. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_generate_mcp_ref.py +0 -0
  330. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_generated.py +0 -0
  331. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_graph_json.py +0 -0
  332. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_axes.py +0 -0
  333. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_bench.py +0 -0
  334. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_bench_script.py +0 -0
  335. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_calibrate.py +0 -0
  336. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_calibrate_script.py +0 -0
  337. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_chunker.py +0 -0
  338. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_diff_index.py +0 -0
  339. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_evidence.py +0 -0
  340. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_findings.py +0 -0
  341. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_martian.py +0 -0
  342. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_martian_script.py +0 -0
  343. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_martian_union.py +0 -0
  344. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_metrics.py +0 -0
  345. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_mistral_sampling.py +0 -0
  346. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_ollama_sampling.py +0 -0
  347. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_ollama_truncation.py +0 -0
  348. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_openrouter.py +0 -0
  349. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_poster.py +0 -0
  350. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_providers.py +0 -0
  351. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_providers_name.py +0 -0
  352. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_recording.py +0 -0
  353. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_render.py +0 -0
  354. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_replay_skeptic.py +0 -0
  355. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_review_script.py +0 -0
  356. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_guardian_skeptic.py +0 -0
  357. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_health_scorer.py +0 -0
  358. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_import_acceptance.py +0 -0
  359. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_inject_architecture_graph.py +0 -0
  360. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_mcp_server.py +0 -0
  361. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_mcp_tool_schemas.py +0 -0
  362. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_metrics.py +0 -0
  363. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_models.py +0 -0
  364. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_name_load_positions.py +0 -0
  365. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_ontology_compliance.py +0 -0
  366. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_ontology_init.py +0 -0
  367. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_overview.py +0 -0
  368. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_overview_tools.py +0 -0
  369. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_package_view.py +0 -0
  370. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_paths.py +0 -0
  371. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_patterns_yaml.py +0 -0
  372. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_pipeline.py +0 -0
  373. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_pipeline_incremental_symbols.py +0 -0
  374. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_pipeline_ts_workspaces.py +0 -0
  375. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_prompt.py +0 -0
  376. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_python_annotations.py +0 -0
  377. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_python_extractor.py +0 -0
  378. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_query_coverage.py +0 -0
  379. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_recordings_from_corpus.py +0 -0
  380. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_import_layout.py +0 -0
  381. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_js_builtins.py +0 -0
  382. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_language_scope.py +0 -0
  383. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_phantom_internal.py +0 -0
  384. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_symbols.py +0 -0
  385. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_ts_declarations.py +0 -0
  386. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_resolver_ts_workspaces.py +0 -0
  387. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_review_fingerprint_closure.py +0 -0
  388. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_review_fingerprint_contract.py +0 -0
  389. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_review_fingerprint_digest.py +0 -0
  390. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_review_fingerprint_record.py +0 -0
  391. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_self_types.py +0 -0
  392. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_skeptic_arms.py +0 -0
  393. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_snippet.py +0 -0
  394. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_sqlite_store.py +0 -0
  395. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_temperature_source.py +0 -0
  396. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_triads.py +0 -0
  397. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_type_checking_imports.py +0 -0
  398. {codegraph_brain-0.25.4 → codegraph_brain-0.27.0}/tests/unit/test_uplift.py +0 -0
@@ -0,0 +1,68 @@
1
+ name: UI
2
+
3
+ # The graph debugger in ui/ had no CI at all (#452): ci.yml runs only the Python
4
+ # toolchain, so a change there could break the build and still merge green. It
5
+ # had already happened — when this job was added, main carried six eslint errors
6
+ # and two TypeScript errors that nothing had reported.
7
+ #
8
+ # Path-filtered so Python-only changes do not pay for a bun install, and the
9
+ # workflow file itself is in the filter so an edit to it runs it.
10
+ on:
11
+ push:
12
+ branches: [ main, dev, "feat/**", "fix/**", "docs/**" ]
13
+ paths: [ "ui/**", ".github/workflows/ui.yml" ]
14
+ pull_request:
15
+ branches: [ main ]
16
+ paths: [ "ui/**", ".github/workflows/ui.yml" ]
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ ui-ci:
23
+ name: UI Verification
24
+ runs-on: ubuntu-latest
25
+ defaults:
26
+ run:
27
+ working-directory: ui
28
+ steps:
29
+ - name: Checkout Code
30
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
31
+
32
+ - name: Setup Bun
33
+ uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
34
+ with:
35
+ # Pinned rather than "latest": the lockfile format moves with bun, and
36
+ # a runner picking up a new release must not be what turns this red.
37
+ bun-version: 1.3.14
38
+
39
+ - name: Install Dependencies
40
+ # --frozen-lockfile fails when bun.lock is out of step with package.json,
41
+ # the job's equivalent of `uv lock --check` in ci.yml. --ignore-scripts
42
+ # because no dependency here needs an install hook — verified by running
43
+ # every step below from a clean install with it — so none gets to run
44
+ # code on the runner (Sonar githubactions:S6505).
45
+ run: bun install --frozen-lockfile --ignore-scripts
46
+
47
+ - name: ESLint
48
+ run: bun run lint
49
+
50
+ - name: Prettier
51
+ # eslint-config-prettier turns ESLint's style rules off, so formatting is
52
+ # checked here or nowhere; 31 files had drifted before this step existed.
53
+ run: bun run format:check
54
+
55
+ - name: TypeScript
56
+ # Vite transpiles TypeScript without type-checking it, so `build` below
57
+ # passes a type error. This is the only step that reads the types.
58
+ # Through a package script, so it runs the `typescript` pinned in
59
+ # bun.lock; `bunx tsc` could fetch an unpinned one (Sonar S8543).
60
+ run: bun run typecheck
61
+
62
+ - name: Tests
63
+ # vitest, not `bun test`: the native runner has no `vi.mock` hoisting, and
64
+ # component tests that use it fail under it (ui/AGENTS.md).
65
+ run: bun run test:run
66
+
67
+ - name: Build
68
+ run: bun run build
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.27.0"
3
+ }
@@ -1,5 +1,50 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.27.0](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.26.0...codegraph-brain-v0.27.0) (2026-10-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * **mcp:** opt-in refresh of a stale graph before read tools answer ([#538](https://github.com/zaebee/codegraph-brain/issues/538)) ([b26a2c8](https://github.com/zaebee/codegraph-brain/commit/b26a2c8d335fbb2f19a217fcaced715f16454664))
9
+ * **orphans:** consider module-level classes only by default ([#432](https://github.com/zaebee/codegraph-brain/issues/432)) ([#534](https://github.com/zaebee/codegraph-brain/issues/534)) ([731d93a](https://github.com/zaebee/codegraph-brain/commit/731d93a8b81fd02fe6b5e71892a408341d034239))
10
+ * **suggest-packages:** judge a package by its direct children ([#446](https://github.com/zaebee/codegraph-brain/issues/446)) ([#536](https://github.com/zaebee/codegraph-brain/issues/536)) ([fd6f05b](https://github.com/zaebee/codegraph-brain/commit/fd6f05b003ea006392e6384170a4bead227f5e85))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **freshness:** report a write made during ingest as stale ([#535](https://github.com/zaebee/codegraph-brain/issues/535)) ([4121919](https://github.com/zaebee/codegraph-brain/commit/4121919148affbad202156d43d01fca458beca23))
16
+ * **resolver:** classify declared Python dependencies as external ([#495](https://github.com/zaebee/codegraph-brain/issues/495)) ([#531](https://github.com/zaebee/codegraph-brain/issues/531)) ([ca4c01d](https://github.com/zaebee/codegraph-brain/commit/ca4c01d1ffa8e8c754317af73ffcf06d534a61d7))
17
+
18
+
19
+ ### Documentation
20
+
21
+ * auto-sync architecture graph and MCP reference ([#532](https://github.com/zaebee/codegraph-brain/issues/532)) ([13c90fd](https://github.com/zaebee/codegraph-brain/commit/13c90fd3ebcc38271b697f514d292c7033d4f81d))
22
+ * auto-sync architecture graph and MCP reference ([#537](https://github.com/zaebee/codegraph-brain/issues/537)) ([c03f60d](https://github.com/zaebee/codegraph-brain/commit/c03f60d4211e3029d02a624ef9d6b4fa92f184df))
23
+ * **onboarding:** refresh the graph from hooks instead of a watcher ([#541](https://github.com/zaebee/codegraph-brain/issues/541)) ([809169d](https://github.com/zaebee/codegraph-brain/commit/809169d19797e280b0810f049215950b3eedf1df)), closes [#175](https://github.com/zaebee/codegraph-brain/issues/175)
24
+
25
+ ## [0.26.0](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.25.4...codegraph-brain-v0.26.0) (2026-10-02)
26
+
27
+
28
+ ### Features
29
+
30
+ * **metrics:** LCOM4 class cohesion ([#521](https://github.com/zaebee/codegraph-brain/issues/521)) ([ed46366](https://github.com/zaebee/codegraph-brain/commit/ed46366f57af23e8b4aba66b6346c246d47a1c24))
31
+ * **metrics:** per-file afferent/efferent coupling and instability ([#520](https://github.com/zaebee/codegraph-brain/issues/520)) ([32393e6](https://github.com/zaebee/codegraph-brain/commit/32393e63f4f8dc9a193cfd6ccba4a18a0d52268a))
32
+ * **metrics:** report the unresolved-edge share beside the rankings ([#519](https://github.com/zaebee/codegraph-brain/issues/519)) ([97699f8](https://github.com/zaebee/codegraph-brain/commit/97699f8bd52eb97c6dc32cbf5d6fcc1bfa752d1b)), closes [#451](https://github.com/zaebee/codegraph-brain/issues/451)
33
+
34
+
35
+ ### Bug Fixes
36
+
37
+ * **drift:** measure unresolved_ratio on stored graphs, carry it to the quotient ([#149](https://github.com/zaebee/codegraph-brain/issues/149)) ([#526](https://github.com/zaebee/codegraph-brain/issues/526)) ([80c3b5a](https://github.com/zaebee/codegraph-brain/commit/80c3b5a0a41bd45ab37cc24d2f4ae06fe24e752c))
38
+ * **guardian:** record GUARDIAN_FEATURES on each review row ([#516](https://github.com/zaebee/codegraph-brain/issues/516)) ([007408c](https://github.com/zaebee/codegraph-brain/commit/007408c0f96e9b175b389db773e51d6838b0738b))
39
+ * **resolver:** resolve TypeScript imports through tsconfig paths aliases ([#513](https://github.com/zaebee/codegraph-brain/issues/513)) ([94219d7](https://github.com/zaebee/codegraph-brain/commit/94219d7e136195bad4eac69a72e25dfd2b3e621f))
40
+ * **resolver:** strip only corroborated layout prefixes when reconciling an FQN ([#319](https://github.com/zaebee/codegraph-brain/issues/319)) ([#527](https://github.com/zaebee/codegraph-brain/issues/527)) ([5fe77f4](https://github.com/zaebee/codegraph-brain/commit/5fe77f47c0ac251a73c8820f91f1cc1f1bc13020))
41
+ * **ui:** fit the view after React Flow renders the new layout ([#523](https://github.com/zaebee/codegraph-brain/issues/523)) ([7be630f](https://github.com/zaebee/codegraph-brain/commit/7be630f5d3734b3d2b7ff23d032380af4a90f19c))
42
+
43
+
44
+ ### Documentation
45
+
46
+ * auto-sync architecture graph and MCP reference ([#514](https://github.com/zaebee/codegraph-brain/issues/514)) ([5abdebd](https://github.com/zaebee/codegraph-brain/commit/5abdebd482071e8e1f24c19559c984fc874d86b6))
47
+
3
48
  ## [0.25.4](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.25.3...codegraph-brain-v0.25.4) (2026-09-25)
4
49
 
5
50
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codegraph-brain
3
- Version: 0.25.4
3
+ Version: 0.27.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
@@ -187,50 +187,48 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
187
187
  models_Edge["Edge (models.py:142)"]:::classNode
188
188
  models_Node["Node (models.py:85)"]:::classNode
189
189
  end
190
+ subgraph sg_import_names["import_names.py"]
191
+ import_names_ImportNameCollector["ImportNameCollector (import_names.py:58)"]:::classNode
192
+ import_names_ImportNameCollector_collect["collect (import_names.py:74)"]:::methodNode
193
+ import_names_ImportNameCollector_note["note (import_names.py:67)"]:::methodNode
194
+ end
190
195
  subgraph sg_pipeline["pipeline.py"]
191
- pipeline_IngestionPipeline_cross_file_inputs_changed["_cross_file_inputs_changed (pipeline.py:266)"]:::methodNode
192
- pipeline_IngestionPipeline_get_extractor["_get_extractor (pipeline.py:401)"]:::methodNode
193
- pipeline_IngestionPipeline_is_noop_incremental["_is_noop_incremental (pipeline.py:327)"]:::methodNode
194
- pipeline_IngestionPipeline_persist_incremental["_persist_incremental (pipeline.py:351)"]:::methodNode
195
- pipeline_IngestionPipeline_process_file["_process_file (pipeline.py:229)"]:::methodNode
196
- pipeline_IngestionPipeline_run["run (pipeline.py:100)"]:::methodNode
197
- pipeline_IngestionPipeline_workspace_root["workspace_root (pipeline.py:83)"]:::methodNode
196
+ pipeline_IngestionPipeline_cross_file_inputs_changed["_cross_file_inputs_changed (pipeline.py:292)"]:::methodNode
197
+ pipeline_IngestionPipeline_get_extractor["_get_extractor (pipeline.py:427)"]:::methodNode
198
+ pipeline_IngestionPipeline_is_noop_incremental["_is_noop_incremental (pipeline.py:353)"]:::methodNode
199
+ pipeline_IngestionPipeline_persist_incremental["_persist_incremental (pipeline.py:377)"]:::methodNode
200
+ pipeline_IngestionPipeline_process_file["_process_file (pipeline.py:252)"]:::methodNode
201
+ pipeline_IngestionPipeline_run["run (pipeline.py:115)"]:::methodNode
202
+ pipeline_IngestionPipeline_workspace_root["workspace_root (pipeline.py:98)"]:::methodNode
203
+ pipeline_observe["_observe (pipeline.py:56)"]:::funcNode
198
204
  end
199
205
  subgraph sg_engine["engine.py"]
200
206
  engine_ResolverEngine["ResolverEngine (engine.py:49)"]:::classNode
201
- engine_ResolverEngine_resolve["resolve (engine.py:77)"]:::methodNode
207
+ engine_ResolverEngine_resolve["resolve (engine.py:85)"]:::methodNode
202
208
  end
203
209
  subgraph sg_uplift["uplift.py"]
204
210
  uplift_SemanticUpliftEngine["SemanticUpliftEngine (uplift.py:66)"]:::classNode
205
211
  uplift_SemanticUpliftEngine_execute_uplift["execute_uplift (uplift.py:91)"]:::methodNode
206
212
  end
207
213
  subgraph sg_sqlite_store["sqlite_store.py"]
208
- sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:56)"]:::classNode
209
- sqlite_store_SQLiteStore_get_workspace_packages["get_workspace_packages (sqlite_store.py:1085)"]:::methodNode
210
- sqlite_store_SQLiteStore_record_workspace_packages["record_workspace_packages (sqlite_store.py:1071)"]:::methodNode
211
- end
212
- subgraph sg_workspaces["workspaces.py"]
213
- workspaces_WorkspacePackages["WorkspacePackages (workspaces.py:23)"]:::classNode
214
- workspaces_WorkspacePackages_note["note (workspaces.py:39)"]:::methodNode
215
- workspaces_WorkspacePackages_unambiguous["unambiguous (workspaces.py:67)"]:::methodNode
214
+ sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:63)"]:::classNode
216
215
  end
217
216
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Node
218
217
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Edge
219
218
  pipeline_IngestionPipeline_run -->|REFERENCES| sqlite_store_SQLiteStore
220
219
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_workspace_root
221
- pipeline_IngestionPipeline_run -->|CALLS| workspaces_WorkspacePackages
222
- pipeline_IngestionPipeline_run -->|CALLS| workspaces_WorkspacePackages_note
220
+ pipeline_IngestionPipeline_run -->|CALLS| import_names_ImportNameCollector
221
+ pipeline_IngestionPipeline_run -->|CALLS| pipeline_observe
222
+ pipeline_IngestionPipeline_run -->|CALLS| import_names_ImportNameCollector_note
223
223
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_get_extractor
224
224
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_process_file
225
- pipeline_IngestionPipeline_run -->|CALLS| workspaces_WorkspacePackages_unambiguous
226
- pipeline_IngestionPipeline_run -->|CALLS| sqlite_store_SQLiteStore_get_workspace_packages
225
+ pipeline_IngestionPipeline_run -->|CALLS| import_names_ImportNameCollector_collect
227
226
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_is_noop_incremental
228
227
  pipeline_IngestionPipeline_run -->|CALLS| engine_ResolverEngine
229
228
  pipeline_IngestionPipeline_run -->|CALLS| engine_ResolverEngine_resolve
230
229
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_run
231
230
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_cross_file_inputs_changed
232
231
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_persist_incremental
233
- pipeline_IngestionPipeline_run -->|CALLS| sqlite_store_SQLiteStore_record_workspace_packages
234
232
  pipeline_IngestionPipeline_run -->|CALLS| uplift_SemanticUpliftEngine_execute_uplift
235
233
  pipeline_IngestionPipeline_run -->|CALLS| uplift_SemanticUpliftEngine
236
234
  ```
@@ -239,21 +237,20 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
239
237
  |--------|------|------|
240
238
  | `Node` | CLASS | [`models.py:85`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L85) |
241
239
  | `Edge` | CLASS | [`models.py:142`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/core/models.py#L142) |
242
- | `workspace_root` | METHOD | [`pipeline.py:83`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L83) |
243
- | `run` | METHOD | [`pipeline.py:100`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L100) |
244
- | `_process_file` | METHOD | [`pipeline.py:229`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L229) |
245
- | `_cross_file_inputs_changed` | METHOD | [`pipeline.py:266`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L266) |
246
- | `_is_noop_incremental` | METHOD | [`pipeline.py:327`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L327) |
247
- | `_persist_incremental` | METHOD | [`pipeline.py:351`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L351) |
248
- | `_get_extractor` | METHOD | [`pipeline.py:401`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L401) |
240
+ | `ImportNameCollector` | CLASS | [`import_names.py:58`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/import_names.py#L58) |
241
+ | `note` | METHOD | [`import_names.py:67`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/import_names.py#L67) |
242
+ | `collect` | METHOD | [`import_names.py:74`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/import_names.py#L74) |
243
+ | `_observe` | FUNCTION | [`pipeline.py:56`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L56) |
244
+ | `workspace_root` | METHOD | [`pipeline.py:98`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L98) |
245
+ | `run` | METHOD | [`pipeline.py:115`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L115) |
246
+ | `_process_file` | METHOD | [`pipeline.py:252`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L252) |
247
+ | `_cross_file_inputs_changed` | METHOD | [`pipeline.py:292`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L292) |
248
+ | `_is_noop_incremental` | METHOD | [`pipeline.py:353`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L353) |
249
+ | `_persist_incremental` | METHOD | [`pipeline.py:377`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L377) |
250
+ | `_get_extractor` | METHOD | [`pipeline.py:427`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/pipeline.py#L427) |
249
251
  | `ResolverEngine` | CLASS | [`engine.py:49`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/engine.py#L49) |
250
- | `resolve` | METHOD | [`engine.py:77`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/engine.py#L77) |
252
+ | `resolve` | METHOD | [`engine.py:85`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/engine.py#L85) |
251
253
  | `SemanticUpliftEngine` | CLASS | [`uplift.py:66`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L66) |
252
254
  | `execute_uplift` | METHOD | [`uplift.py:91`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/resolver/uplift.py#L91) |
253
- | `SQLiteStore` | CLASS | [`sqlite_store.py:56`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L56) |
254
- | `record_workspace_packages` | METHOD | [`sqlite_store.py:1071`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L1071) |
255
- | `get_workspace_packages` | METHOD | [`sqlite_store.py:1085`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L1085) |
256
- | `WorkspacePackages` | CLASS | [`workspaces.py:23`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/workspaces.py#L23) |
257
- | `note` | METHOD | [`workspaces.py:39`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/workspaces.py#L39) |
258
- | `unambiguous` | METHOD | [`workspaces.py:67`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/workspaces.py#L67) |
255
+ | `SQLiteStore` | CLASS | [`sqlite_store.py:63`](https://github.com/zaebee/codegraph-brain/blob/main/src/cgis/storage/sqlite_store.py#L63) |
259
256
  <!-- END_CGIS_GRAPH -->
@@ -11,49 +11,47 @@ classDef externalNode fill:#fff3e0,stroke:#e65100,stroke-width:1px,stroke-dashar
11
11
  models_Edge["Edge (models.py:142)"]:::classNode
12
12
  models_Node["Node (models.py:85)"]:::classNode
13
13
  end
14
+ subgraph sg_import_names["import_names.py"]
15
+ import_names_ImportNameCollector["ImportNameCollector (import_names.py:58)"]:::classNode
16
+ import_names_ImportNameCollector_collect["collect (import_names.py:74)"]:::methodNode
17
+ import_names_ImportNameCollector_note["note (import_names.py:67)"]:::methodNode
18
+ end
14
19
  subgraph sg_pipeline["pipeline.py"]
15
- pipeline_IngestionPipeline_cross_file_inputs_changed["_cross_file_inputs_changed (pipeline.py:266)"]:::methodNode
16
- pipeline_IngestionPipeline_get_extractor["_get_extractor (pipeline.py:401)"]:::methodNode
17
- pipeline_IngestionPipeline_is_noop_incremental["_is_noop_incremental (pipeline.py:327)"]:::methodNode
18
- pipeline_IngestionPipeline_persist_incremental["_persist_incremental (pipeline.py:351)"]:::methodNode
19
- pipeline_IngestionPipeline_process_file["_process_file (pipeline.py:229)"]:::methodNode
20
- pipeline_IngestionPipeline_run["run (pipeline.py:100)"]:::methodNode
21
- pipeline_IngestionPipeline_workspace_root["workspace_root (pipeline.py:83)"]:::methodNode
20
+ pipeline_IngestionPipeline_cross_file_inputs_changed["_cross_file_inputs_changed (pipeline.py:292)"]:::methodNode
21
+ pipeline_IngestionPipeline_get_extractor["_get_extractor (pipeline.py:427)"]:::methodNode
22
+ pipeline_IngestionPipeline_is_noop_incremental["_is_noop_incremental (pipeline.py:353)"]:::methodNode
23
+ pipeline_IngestionPipeline_persist_incremental["_persist_incremental (pipeline.py:377)"]:::methodNode
24
+ pipeline_IngestionPipeline_process_file["_process_file (pipeline.py:252)"]:::methodNode
25
+ pipeline_IngestionPipeline_run["run (pipeline.py:115)"]:::methodNode
26
+ pipeline_IngestionPipeline_workspace_root["workspace_root (pipeline.py:98)"]:::methodNode
27
+ pipeline_observe["_observe (pipeline.py:56)"]:::funcNode
22
28
  end
23
29
  subgraph sg_engine["engine.py"]
24
30
  engine_ResolverEngine["ResolverEngine (engine.py:49)"]:::classNode
25
- engine_ResolverEngine_resolve["resolve (engine.py:77)"]:::methodNode
31
+ engine_ResolverEngine_resolve["resolve (engine.py:85)"]:::methodNode
26
32
  end
27
33
  subgraph sg_uplift["uplift.py"]
28
34
  uplift_SemanticUpliftEngine["SemanticUpliftEngine (uplift.py:66)"]:::classNode
29
35
  uplift_SemanticUpliftEngine_execute_uplift["execute_uplift (uplift.py:91)"]:::methodNode
30
36
  end
31
37
  subgraph sg_sqlite_store["sqlite_store.py"]
32
- sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:56)"]:::classNode
33
- sqlite_store_SQLiteStore_get_workspace_packages["get_workspace_packages (sqlite_store.py:1085)"]:::methodNode
34
- sqlite_store_SQLiteStore_record_workspace_packages["record_workspace_packages (sqlite_store.py:1071)"]:::methodNode
35
- end
36
- subgraph sg_workspaces["workspaces.py"]
37
- workspaces_WorkspacePackages["WorkspacePackages (workspaces.py:23)"]:::classNode
38
- workspaces_WorkspacePackages_note["note (workspaces.py:39)"]:::methodNode
39
- workspaces_WorkspacePackages_unambiguous["unambiguous (workspaces.py:67)"]:::methodNode
38
+ sqlite_store_SQLiteStore["SQLiteStore (sqlite_store.py:63)"]:::classNode
40
39
  end
41
40
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Node
42
41
  pipeline_IngestionPipeline_run -->|REFERENCES| models_Edge
43
42
  pipeline_IngestionPipeline_run -->|REFERENCES| sqlite_store_SQLiteStore
44
43
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_workspace_root
45
- pipeline_IngestionPipeline_run -->|CALLS| workspaces_WorkspacePackages
46
- pipeline_IngestionPipeline_run -->|CALLS| workspaces_WorkspacePackages_note
44
+ pipeline_IngestionPipeline_run -->|CALLS| import_names_ImportNameCollector
45
+ pipeline_IngestionPipeline_run -->|CALLS| pipeline_observe
46
+ pipeline_IngestionPipeline_run -->|CALLS| import_names_ImportNameCollector_note
47
47
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_get_extractor
48
48
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_process_file
49
- pipeline_IngestionPipeline_run -->|CALLS| workspaces_WorkspacePackages_unambiguous
50
- pipeline_IngestionPipeline_run -->|CALLS| sqlite_store_SQLiteStore_get_workspace_packages
49
+ pipeline_IngestionPipeline_run -->|CALLS| import_names_ImportNameCollector_collect
51
50
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_is_noop_incremental
52
51
  pipeline_IngestionPipeline_run -->|CALLS| engine_ResolverEngine
53
52
  pipeline_IngestionPipeline_run -->|CALLS| engine_ResolverEngine_resolve
54
53
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_run
55
54
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_cross_file_inputs_changed
56
55
  pipeline_IngestionPipeline_run -->|CALLS| pipeline_IngestionPipeline_persist_incremental
57
- pipeline_IngestionPipeline_run -->|CALLS| sqlite_store_SQLiteStore_record_workspace_packages
58
56
  pipeline_IngestionPipeline_run -->|CALLS| uplift_SemanticUpliftEngine_execute_uplift
59
57
  pipeline_IngestionPipeline_run -->|CALLS| uplift_SemanticUpliftEngine
@@ -55,6 +55,60 @@ Point `--output` at a `.db` file. For large repos, add `--incremental` to skip u
55
55
  }
56
56
  ```
57
57
 
58
+ ### Keeping the graph current (opt-in)
59
+
60
+ Set `"CGIS_AUTO_REFRESH": "1"` in the server's `env` and every graph-reading
61
+ tool first checks whether the files behind the graph changed since the last
62
+ ingest; if they did, it runs an incremental `cgis_ingest` from the recorded
63
+ root with the recorded `--source-root`/`--domains` options before answering.
64
+ A fresh graph costs a few milliseconds of `stat` calls. A stale one costs an
65
+ incremental ingest: under a second for a body edit, a full rebuild when a
66
+ symbol was added, renamed or removed. It never creates a missing database,
67
+ and a graph ingested before this option existed is only reported stale, not
68
+ refreshed, until it is ingested once more.
69
+
70
+ ### Refreshing outside the MCP server: hooks, not a watcher
71
+
72
+ cgis has no watch mode, on purpose (#175). A watcher re-ingests on every save,
73
+ and an agent's multi-file edit is a burst of saves, each of which can cost a
74
+ full rebuild; the graph only needs to be current when something reads it. If
75
+ you query from the CLI, or want the graph current before the agent's next
76
+ turn, hang an incremental ingest on an event that ends a burst instead. Use the
77
+ same path and `--source-root`/`--domains` the graph was built with (`./src`
78
+ as in Step 1); a different path renames every node.
79
+
80
+ **Claude Code** — once per finished turn, not once per edit
81
+ (`.claude/settings.json`):
82
+
83
+ ```json
84
+ {
85
+ "hooks": {
86
+ "Stop": [
87
+ {
88
+ "hooks": [
89
+ {
90
+ "type": "command",
91
+ "command": "cd \"$CLAUDE_PROJECT_DIR\" && cgis ingest ./src -o graph.db -i >/dev/null 2>&1 || true"
92
+ }
93
+ ]
94
+ }
95
+ ]
96
+ }
97
+ }
98
+ ```
99
+
100
+ **git** — after a checkout, pull or rebase swaps many files at once
101
+ (`.git/hooks/post-checkout`, and the same body in `post-merge` and
102
+ `post-rewrite`; make each executable):
103
+
104
+ ```sh
105
+ #!/bin/sh
106
+ cgis ingest ./src -o graph.db -i >/dev/null 2>&1 || true
107
+ ```
108
+
109
+ `|| true` keeps a failed ingest from failing the hook; the read commands will
110
+ still say the graph is stale.
111
+
58
112
  ---
59
113
 
60
114
  ## Step 3: Available MCP tools
@@ -160,7 +160,14 @@ Classes nothing in production builds, extends or names — dead-code candidates.
160
160
  reported orphans were generated entities and the sixth a nested pydantic
161
161
  ``Config``: the unfiltered report had no actionable row in it (#432).
162
162
 
163
- Returns JSON ``{orphans, considered, test_sources, generated_excluded}``;
163
+ Only **module-level** classes are considered by default; ``include_nested``
164
+ adds classes defined inside a class or function. Across eight measured
165
+ repositories none of the 46 nested rows was dead: most were a ``Meta`` /
166
+ ``Config`` a metaclass reads, the rest live classes reached as
167
+ ``self.Nested(...)``, which the resolver does not follow (#432).
168
+
169
+ Returns JSON ``{orphans, considered, test_sources, generated_excluded,
170
+ nested_excluded}``;
164
171
  each orphan carries ``fqn``/``file``/``line``. **A listing is a candidate for
165
172
  deletion, not a proof** — a class named only inside a decorator (#429) or
166
173
  arriving through a star import is invisible here, so the sweep errs towards
@@ -177,6 +184,7 @@ Classes nothing in production builds, extends or names — dead-code candidates.
177
184
  | `prefix` | `any` | | Only consider classes under this FQN prefix, cut on a dot boundary. |
178
185
  | `include_tests` | `boolean` | | Count test code as a user, so the report means "unreachable from anywhere". |
179
186
  | `include_generated` | `boolean` | | Include machine-generated classes, which are hidden by default. |
187
+ | `include_nested` | `boolean` | | Include classes nested in a class or function, which are hidden by default. |
180
188
 
181
189
  ---
182
190
 
@@ -302,12 +310,28 @@ Propose a starter patterns.yaml from the measured graph (read-only).
302
310
 
303
311
  Whole-graph architectural metrics — coupling bottlenecks, God classes, PageRank.
304
312
 
305
- Returns JSON ``{bottlenecks, god_classes, critical}`` computed with vectorized
306
- DuckDB aggregations over the whole graph (fan-in/fan-out coupling,
307
- declared-member counts, PageRank) — the global "what are the hotspots?" view
308
- that complements the node-local trace/impact/context tools. Requires the
309
- optional ``duckdb`` extra; an unavailable dependency is reported as a normal
310
- ❌ message.
313
+ Returns JSON ``{bottlenecks, god_classes, critical, file_coupling, class_cohesion,
314
+ resolution}``
315
+ computed with vectorized DuckDB aggregations over the whole graph (fan-in/fan-out
316
+ coupling, declared-member counts, PageRank, per-file Ca/Ce/instability) — the
317
+ global "what are the hotspots?" view that complements the node-local
318
+ trace/impact/context tools. Requires the optional ``duckdb`` extra; an
319
+ unavailable dependency is reported as a normal ❌ message.
320
+
321
+ ``file_coupling`` counts *files*, not calls: Ca is how many other files
322
+ depend on a file (by IMPORTS or CALLS), Ce how many it depends on, and
323
+ instability ``I = Ce / (Ca + Ce)`` runs from 0 (stable, expensive to change)
324
+ to 1 (volatile); it is null for a file linked to no other.
325
+
326
+ ``class_cohesion`` ranks classes by LCOM4: the number of groups their instance
327
+ methods fall into when linked by a shared ``self`` attribute or a call. 1 is
328
+ cohesive; 2+ is a class doing unrelated jobs. Dunders (``__init__`` above
329
+ all), abstract, static and class methods are not counted.
330
+
331
+ ``resolution`` is the share of edges the resolver could not place, by the
332
+ same rule as ``cgis validate``. Read the rankings through it: a node whose
333
+ calls are mostly unresolved looks uncoupled because its edges point nowhere.
334
+ Under ``scope``/``exclude`` it counts the edges the selected code *emits*.
311
335
 
312
336
  ``exclude`` drops any node whose FQN contains one of the given dot-segments
313
337
  (e.g. ``["tests"]`` removes both ``tests.*`` and ``domains.*.tests.*``) so
@@ -361,10 +385,14 @@ Suggest sub-package boundaries for a package from its dependency communities.
361
385
 
362
386
  Returns JSON: modularity_q, divergence, direction (under/over/matched),
363
387
  verdict (split/consolidate/aligned/leave/borderline/no_signal), the detected
364
- communities (id + member files), the cross-community bridge edges (cost of
388
+ communities (id + members), the cross-community bridge edges (cost of
365
389
  splitting), and the thresholds used. Default layer is IMPORTS; set
366
390
  ``with_calls`` for the combined import+call graph. Run ``cgis_ingest`` first.
367
391
 
392
+ Members are the package's direct children by default, each sub-package one
393
+ node, so the verdict says whether to regroup them; ``level`` in the result
394
+ says which. ``all_descendants`` clusters every file below the package.
395
+
368
396
  A mis-rooted graph (import targets resolve to no internal file) returns
369
397
  ``no_signal`` with a diagnostic note rather than a silent clean verdict.
370
398
 
@@ -374,6 +402,7 @@ Suggest sub-package boundaries for a package from its dependency communities.
374
402
  | `prefix` | `any` | | FQN prefix of the package to analyse, e.g. cgis.query, matched on whole dot-segments. Needed in practice: without it the verdict is no_signal. |
375
403
  | `with_calls` | `boolean` | | Use the combined import + call graph instead of imports only. |
376
404
  | `min_q` | `number` | | Modularity threshold: at or above it, a package whose layout disagrees with its communities is flagged split (or consolidate, if over-split). |
405
+ | `all_descendants` | `boolean` | | Cluster every file below the package and compare with its sub-directories, instead of treating each sub-package as one node. |
377
406
 
378
407
  ---
379
408
 
@@ -128,18 +128,24 @@ project_domains:
128
128
  # deflating this domain's drift; 0.37 is the honest census of the real structure (no real
129
129
  # edges lost — verified by edge-diff). Correctness-driven re-baseline, not ratchet loosening.
130
130
  drift_tolerance: 0.40
131
+ hygiene_baseline:
132
+ unresolved_ratio: 0.37 # measured 0.3604 when the gate came alive (#149)
131
133
 
132
134
  - name: "resolution"
133
135
  fqn_prefix: "cgis.resolver"
134
136
  expected_pattern: pipeline_stage
135
137
  profile: python
136
138
  drift_tolerance: 0.40 # v2 measured ≈0.25 post-#115 split (tv_imp 0.00 — real 021C chain engine→symbols→indices; residual is tv_calls)
139
+ hygiene_baseline:
140
+ unresolved_ratio: 0.45 # measured 0.4451 when the gate came alive (#149)
137
141
 
138
142
  - name: "pipeline"
139
143
  fqn_prefix: "cgis.pipeline"
140
144
  expected_pattern: orchestrator
141
145
  profile: python
142
146
  drift_tolerance: 0.25 # v2 measured ≈0.20 (tv_calls .36)
147
+ hygiene_baseline:
148
+ unresolved_ratio: 0.43 # measured 0.4220 when the gate came alive (#149)
143
149
 
144
150
  - name: "storage"
145
151
  fqn_prefix: "cgis.storage"
@@ -151,7 +157,17 @@ project_domains:
151
157
  fqn_prefix: "cgis.query"
152
158
  expected_pattern: layered_dag
153
159
  profile: python
154
- drift_tolerance: 0.20 # v2 re-baselined ≈0.19 after ontology_init joined the domain (#174) — was ≈0.14/0.18
160
+ # Re-baselined 0.20 -> 0.21 for #451 LCOM4: origin/main 32393e6 scored 0.1997, one
161
+ # rounding step under the line; the class-cohesion metric's reuse of the shared
162
+ # scope/exclusion helpers adds fan-in calls (T_calls 021U 0.128 -> 0.133) and
163
+ # scores 0.2006. History: v2 ≈0.19 after ontology_init joined (#174), was ≈0.14/0.18.
164
+ # Re-baselined 0.21 -> 0.23 in #149: unresolved_ratio read 0 on every stored graph
165
+ # (only `raw_call:` targets were counted, and the resolver turns those into UNKNOWN
166
+ # nodes before saving). Measured honestly it is 0.2787: the acknowledged debt still
167
+ # scores, and discounts the CALLS layer — 0.2026 -> 0.2212. Correctness-driven, like #183.
168
+ drift_tolerance: 0.23
169
+ hygiene_baseline:
170
+ unresolved_ratio: 0.28 # measured 0.2787 when the gate came alive (#149)
155
171
 
156
172
  # Bound in #182: these three were production code with no architectural gate at
157
173
  # all — 207 of 618 internal nodes (33%) sat outside every domain, guardian alone
@@ -164,6 +180,8 @@ project_domains:
164
180
  profile: python
165
181
  drift_tolerance: 0.26 # v2 measured 0.2282; dag_depth 5 clears the template's min 3
166
182
  # (runner-up dispatcher 0.34 — a clear win, not a coin flip)
183
+ hygiene_baseline:
184
+ unresolved_ratio: 0.28 # measured 0.2778 when the gate came alive (#149)
167
185
 
168
186
  # cli and api are hygiene-only by rule, not by taste: neither has ANY
169
187
  # intra-domain IMPORTS edge (cli is one file, api is two), so there is no
@@ -176,7 +194,9 @@ project_domains:
176
194
  - name: "cli"
177
195
  fqn_prefix: "cgis.cli"
178
196
  profile: python
179
- drift_tolerance: 0.03 # hygiene-only; measured 0.00 (no cycles, nothing unresolved)
197
+ drift_tolerance: 0.03 # hygiene-only; measured 0.00 (no cycles)
198
+ hygiene_baseline:
199
+ unresolved_ratio: 0.24 # measured 0.2309 when the gate came alive (#149)
180
200
 
181
201
  - name: "api"
182
202
  fqn_prefix: "cgis.api"
@@ -189,19 +209,29 @@ project_domains:
189
209
  expected_pattern: layered_dag
190
210
  profile: typescript
191
211
  params: {min_depth: 2} # JSX component trees are legitimately shallower
192
- drift_tolerance: 0.20 # v2 measured ≈0.17 (tv_imp .28; CALLS layer empty → excluded)
212
+ # Re-baselined 0.20 -> 0.24 in #149: unresolved_ratio now counts UNKNOWN targets
213
+ # (0.9036 — the TS resolver places few calls), 0.1667 -> 0.2370. See query.
214
+ drift_tolerance: 0.24
215
+ hygiene_baseline:
216
+ unresolved_ratio: 0.91 # measured 0.9036 when the gate came alive (#149)
193
217
 
194
218
  - name: "layout"
195
219
  fqn_prefix: "layout"
196
220
  expected_pattern: pure_utility
197
221
  profile: typescript
198
222
  drift_tolerance: 0.50 # v2 measured ≈0.46 — 4 CALLS triples (small-N, spec §3.6.1); revisit with TS resolver
223
+ hygiene_baseline:
224
+ unresolved_ratio: 0.66 # measured 0.6522 when the gate came alive (#149)
199
225
 
200
226
  # Hygiene-only domains (no expected_pattern → v1 gate path): acyclic + resolved.
227
+ # hooks, providers and utils: re-baselined in #149 from 0.15. Their whole score is
228
+ # the acknowledged unresolved_ratio debt now that it is measured (see query).
201
229
  - name: "hooks"
202
230
  fqn_prefix: "hooks"
203
231
  profile: typescript
204
- drift_tolerance: 0.15 # measured 0.00
232
+ drift_tolerance: 0.22 # measured 0.2117
233
+ hygiene_baseline:
234
+ unresolved_ratio: 0.84 # measured 0.8351 when the gate came alive (#149)
205
235
 
206
236
  - name: "store"
207
237
  fqn_prefix: "store"
@@ -211,12 +241,16 @@ project_domains:
211
241
  - name: "providers"
212
242
  fqn_prefix: "providers"
213
243
  profile: typescript
214
- drift_tolerance: 0.15 # measured 0.00
244
+ drift_tolerance: 0.17 # measured 0.1641
245
+ hygiene_baseline:
246
+ unresolved_ratio: 0.70 # measured 0.6923 when the gate came alive (#149)
215
247
 
216
248
  - name: "utils"
217
249
  fqn_prefix: "utils"
218
250
  profile: typescript
219
- drift_tolerance: 0.15 # measured 0.00
251
+ drift_tolerance: 0.20 # measured 0.1952
252
+ hygiene_baseline:
253
+ unresolved_ratio: 0.79 # measured 0.7857 when the gate came alive (#149)
220
254
 
221
255
  # ── Project-level quotient binding (spec §3.4) — OBSERVE-ONLY burn-in ────────
222
256
  # Measured quotient IMPORTS census {021D .4, 021U .4, 030T .2}: the domain
@@ -15,16 +15,16 @@ project_domains:
15
15
  resolution: 0.40
16
16
  pipeline: 0.25
17
17
  storage: 0.20
18
- query: 0.20
18
+ query: 0.23
19
19
  guardian: 0.26
20
20
  cli: 0.03
21
21
  api: 0.03
22
- components: 0.20
22
+ components: 0.24
23
23
  layout: 0.50
24
- hooks: 0.15
24
+ hooks: 0.22
25
25
  store: 0.15
26
- providers: 0.15
27
- utils: 0.15
26
+ providers: 0.17
27
+ utils: 0.20
28
28
 
29
29
  project_level:
30
30
  cgis-project: 0.15
@@ -135,6 +135,31 @@ parameter also matched case (b) (an explicit `Depends` inside its
135
135
  `raw_dep:` candidate for the *outer* annotation is still emitted too — it
136
136
  will resolve to a CLASS/external and be dropped; no dedup logic needed.
137
137
 
138
+ **d) DI in a route decorator (#429, added after slice 1).**
139
+ `@router.post(..., dependencies=[Depends(guard)])` declares a guard at the
140
+ decorator instead of the signature. The `Depends`/`Security` call there is
141
+ handled by the same hook as §3.2b, with one deliberate exception to the rule
142
+ that an edge's source is its lexical owner: the DEPENDS_ON edge is sourced at
143
+ the **decorated function**, not the module the decorator sits in. FastAPI runs
144
+ the dependency before that function, and `cgis audit` reads DEPENDS_ON as the
145
+ evidence a route is guarded, so a module-sourced edge would be accurate about
146
+ location and useless as evidence.
147
+
148
+ - Only a decorated `function_definition` / `async_function_definition`
149
+ (including methods) gets the edge. A decorated **class** keeps the
150
+ CALLS-only treatment: FastAPI never treats a class decorator as a
151
+ dependant.
152
+ - Name-extraction rules are §3.2b's: first positional argument only; argless
153
+ and keyword-only (`Depends(dependency=guard)`) calls emit no edge.
154
+ - This is the only place the exception applies. Calls and name references in
155
+ decorators were already sourced at the decorated definition (#434) — a
156
+ decorator has no other owner — so the exception is confined to DI, which is
157
+ the edge kind that carries "this runs before that" semantics.
158
+
159
+ Population note: on owner-api at `b7d02fe6` one route declared its guard this
160
+ way, against 238 in the signature. The edge is cheap and closes a false
161
+ "unguarded" in a security-facing report; it is not expected to move counts.
162
+
138
163
  ### 3.3 Resolver (`src/cgis/resolver/engine.py`)
139
164
 
140
165
  - `RAW_DEP_PREFIX = "raw_dep:"` defined here as a module-level constant,