codegraph-brain 0.23.0__tar.gz → 0.23.2__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 (370) hide show
  1. codegraph_brain-0.23.2/.github/workflows/mcp-registry.yml +81 -0
  2. codegraph_brain-0.23.2/.release-please-manifest.json +3 -0
  3. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/CHANGELOG.md +20 -0
  4. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/PKG-INFO +1 -1
  5. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/how-to/MCP_REFERENCE.md +56 -53
  6. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/pyproject.toml +1 -1
  7. codegraph_brain-0.23.2/scripts/mcp_registry_gate.sh +101 -0
  8. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/server.json +2 -2
  9. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/api/mcp_server.py +6 -2
  10. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/cli.py +68 -39
  11. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/context/audit.py +86 -8
  12. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/render/graph_json.py +22 -8
  13. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_audit.py +98 -2
  14. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_cli.py +121 -0
  15. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_graph_json.py +15 -0
  16. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_mcp_server.py +9 -0
  17. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/uv.lock +1 -1
  18. codegraph_brain-0.23.0/.release-please-manifest.json +0 -3
  19. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.claude-plugin/marketplace.json +0 -0
  20. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.gitattributes +0 -0
  21. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.github/test-count-baseline +0 -0
  22. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.github/workflows/autodoc.yml +0 -0
  23. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.github/workflows/ci.yml +0 -0
  24. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.github/workflows/guardian.yml +0 -0
  25. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.github/workflows/pr-title.yml +0 -0
  26. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.github/workflows/release-please.yml +0 -0
  27. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.gitignore +0 -0
  28. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.pre-commit-config.yaml +0 -0
  29. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/.python-version +0 -0
  30. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/CLAUDE.md +0 -0
  31. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/CONTRIBUTING.md +0 -0
  32. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/LICENSE +0 -0
  33. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/Makefile +0 -0
  34. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/PRIVACY.md +0 -0
  35. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/README.md +0 -0
  36. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/CURATION.md +0 -0
  37. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/calibration.jsonl +0 -0
  38. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/246-cross-vendor/README.md +0 -0
  39. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/246-cross-vendor/free-nemotron-quota-cutoff.jsonl +0 -0
  40. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/401-evidence/README.md +0 -0
  41. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/401-evidence/pr-399-control-rows.jsonl +0 -0
  42. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/401-evidence/pr-399-recording.json +0 -0
  43. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/401-evidence/pr-399-treatment-rows.jsonl +0 -0
  44. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/407-no-checker-appeal/README.md +0 -0
  45. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-directive-rows.jsonl +0 -0
  46. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/experiments/407-no-checker-appeal/pr-399-control-prohibition-rows.jsonl +0 -0
  47. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-122.yaml +0 -0
  48. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-140.yaml +0 -0
  49. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-141.yaml +0 -0
  50. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-142.yaml +0 -0
  51. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-143.yaml +0 -0
  52. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-144.yaml +0 -0
  53. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-278.yaml +0 -0
  54. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/pr-313.yaml +0 -0
  55. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/guardian/results.jsonl +0 -0
  56. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian/README.md +0 -0
  57. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian/cal_dot_com.json +0 -0
  58. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian/discourse.json +0 -0
  59. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian/grafana.json +0 -0
  60. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian/keycloak.json +0 -0
  61. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian/sentry.json +0 -0
  62. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-judged.jsonl +0 -0
  63. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-p3-judged-run1.jsonl +0 -0
  64. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-p3-judged-run1.jsonl.corrupted-backup +0 -0
  65. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-p3-run1.jsonl +0 -0
  66. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-p3-run2.jsonl +0 -0
  67. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-p3-run3.jsonl +0 -0
  68. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-plan.json +0 -0
  69. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-repeat-judged.jsonl +0 -0
  70. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-repeat-reviews.jsonl +0 -0
  71. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/benchmarks/martian-reviews.jsonl +0 -0
  72. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/data/.gitkeep +0 -0
  73. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/AUDIT.md +0 -0
  74. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/CASE_STUDY.md +0 -0
  75. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/GUARDIAN_LOCAL_BENCH.md +0 -0
  76. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/GUARDIAN_REMOTE_OLLAMA.md +0 -0
  77. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/architecture/HOW_IT_WORKS.md +0 -0
  78. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/architecture/ONTOLOGY.md +0 -0
  79. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/architecture/PATTERNS_AND_TRIADS.md +0 -0
  80. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/architecture/SELF_PORTRAIT.md +0 -0
  81. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/architecture/diagrams/pipeline_flow.mermaid +0 -0
  82. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/architecture/health_badge.json +0 -0
  83. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/assets/.gitignore +0 -0
  84. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/assets/cgis-app-avatar.png +0 -0
  85. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/assets/cgis-app-avatar.svg +0 -0
  86. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/assets/generate_avatar.py +0 -0
  87. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/examples/.gitkeep +0 -0
  88. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/how-to/AGENT_ONBOARDING.md +0 -0
  89. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/how-to/CLI_USAGE.md +0 -0
  90. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/lab-notes/2026-06-11-chunked-review-negative-result.md +0 -0
  91. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/ontology/.gitkeep +0 -0
  92. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/ontology/core.yaml +0 -0
  93. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/ontology/domains.yaml +0 -0
  94. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/ontology/patterns.yaml +0 -0
  95. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/ontology/tolerances.lock +0 -0
  96. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/plans/2026-09-09-graph-freshness.md +0 -0
  97. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-09-domain-pattern-fingerprint-design.md +0 -0
  98. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-09-pattern-alphabet-motif-basis-design.md +0 -0
  99. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-10-guardian-sprint-design.md +0 -0
  100. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-11-fastapi-di-edges-design.md +0 -0
  101. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-11-guardian-chunked-review-design.md +0 -0
  102. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-11-guardian-chunker-design.md +0 -0
  103. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-11-mcp-drift-validate-fqn-design.md +0 -0
  104. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-11-resolver-split-design.md +0 -0
  105. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-11-symbol-import-edges-design.md +0 -0
  106. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-12-drift-empty-domains-design.md +0 -0
  107. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-12-gate-semantics-design.md +0 -0
  108. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-12-init-ontology-design.md +0 -0
  109. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-12-release-please-ci-design.md +0 -0
  110. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-13-suggest-packages-design.md +0 -0
  111. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-06-13-tangle-anti-pattern-design.md +0 -0
  112. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-29-guardian-skeptic-scoring-design.md +0 -0
  113. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-cgis-fractal-design.md +0 -0
  114. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-cgis-fractal-plan.md +0 -0
  115. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-chunk-source-filter-design.md +0 -0
  116. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-chunk-source-filter-plan.md +0 -0
  117. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-genai-client-close-design.md +0 -0
  118. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-genai-client-close-plan.md +0 -0
  119. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-guardian-precision-bench-design.md +0 -0
  120. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-guardian-precision-bench-plan.md +0 -0
  121. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-guardian-timeout-retry-design.md +0 -0
  122. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-30-guardian-timeout-retry-plan.md +0 -0
  123. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-07-31-finder-bug-class-taxonomy.md +0 -0
  124. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-08-01-aura-autoevolution-poc.md +0 -0
  125. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-08-11-guardian-code-review-bench.md +0 -0
  126. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-08-14-review-fingerprint-design.md +0 -0
  127. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-09-05-annotation-graph-design.md +0 -0
  128. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/2026-09-09-graph-freshness-design.md +0 -0
  129. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/BLUEPRINT.md +0 -0
  130. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/PRD.md +0 -0
  131. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/TDD.md +0 -0
  132. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-09-fingerprint-drift.md +0 -0
  133. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-10-guardian-context-skeptic-inline.md +0 -0
  134. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-10-guardian-structured-findings-bench.md +0 -0
  135. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-10-motif-basis-part-b.md +0 -0
  136. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-10-unified-pattern-alphabet.md +0 -0
  137. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-11-fastapi-di-edges.md +0 -0
  138. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-11-guardian-chunked-review.md +0 -0
  139. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-11-guardian-chunker.md +0 -0
  140. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-11-mcp-drift-validate-fqn.md +0 -0
  141. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-11-resolver-split.md +0 -0
  142. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-12-drift-empty-domains.md +0 -0
  143. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-12-gate-semantics.md +0 -0
  144. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-12-init-ontology.md +0 -0
  145. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-12-release-please-ci.md +0 -0
  146. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-12-symbol-import-edges.md +0 -0
  147. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-06-13-suggest-packages.md +0 -0
  148. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-07-29-guardian-skeptic-scoring.md +0 -0
  149. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-08-14-review-fingerprint.md +0 -0
  150. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-09-05-annotation-graph-pr1.md +0 -0
  151. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/docs/specs/plans/2026-09-05-annotation-graph-pr2.md +0 -0
  152. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/glama.json +0 -0
  153. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/main.py +0 -0
  154. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/plugin/.claude-plugin/plugin.json +0 -0
  155. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/plugin/.mcp.json +0 -0
  156. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/plugin/README.md +0 -0
  157. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/plugin/skills/cgis/SKILL.md +0 -0
  158. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/plugin/skills/ingest/SKILL.md +0 -0
  159. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/release-please-config.json +0 -0
  160. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/backfill_calibration_fingerprint.py +0 -0
  161. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/backfill_review_fingerprint.py +0 -0
  162. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/check_pytest_raises.py +0 -0
  163. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/check_test_count.py +0 -0
  164. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/colab_bench.sh +0 -0
  165. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/gen_ideal_graph.py +0 -0
  166. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/generate_health.py +0 -0
  167. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/generate_mcp_ref.py +0 -0
  168. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/generate_schema_docs.py +0 -0
  169. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/guardian_bench.py +0 -0
  170. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/guardian_calibrate.py +0 -0
  171. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/guardian_martian.py +0 -0
  172. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/guardian_replay_skeptic.py +0 -0
  173. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/guardian_review.py +0 -0
  174. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/inject_architecture_graph.py +0 -0
  175. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/ollama_visitor.sh +0 -0
  176. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/probe_closure_gap.py +0 -0
  177. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/probe_tier_ladder.py +0 -0
  178. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/recordings_from_corpus.py +0 -0
  179. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/scripts/skeptic_arms.py +0 -0
  180. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/__init__.py +0 -0
  181. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/__main__.py +0 -0
  182. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/api/.gitkeep +0 -0
  183. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/api/__init__.py +0 -0
  184. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/core/.gitkeep +0 -0
  185. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/core/coverage.py +0 -0
  186. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/core/freshness.py +0 -0
  187. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/core/generated.py +0 -0
  188. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/core/js_globals.py +0 -0
  189. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/core/models.py +0 -0
  190. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/core/paths.py +0 -0
  191. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/.gitkeep +0 -0
  192. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/_python_annotations.py +0 -0
  193. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/_python_ast.py +0 -0
  194. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/_python_classes.py +0 -0
  195. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/_python_functions.py +0 -0
  196. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/_python_imports.py +0 -0
  197. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/_python_types.py +0 -0
  198. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/_typescript_bindings.py +0 -0
  199. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/base.py +0 -0
  200. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/python_extractor.py +0 -0
  201. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/registry.py +0 -0
  202. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/extractors/typescript_extractor.py +0 -0
  203. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/__init__.py +0 -0
  204. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/axes.py +0 -0
  205. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/bench.py +0 -0
  206. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/calibrate.py +0 -0
  207. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/chunked.py +0 -0
  208. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/chunker.py +0 -0
  209. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/collector.py +0 -0
  210. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/core.py +0 -0
  211. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/diff_index.py +0 -0
  212. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/evidence.py +0 -0
  213. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/findings.py +0 -0
  214. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/github_poster.py +0 -0
  215. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/martian.py +0 -0
  216. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/metrics.py +0 -0
  217. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/prompts.py +0 -0
  218. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/providers/__init__.py +0 -0
  219. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/providers/base.py +0 -0
  220. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/providers/gemini.py +0 -0
  221. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/providers/mistral.py +0 -0
  222. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/providers/ollama.py +0 -0
  223. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/providers/openrouter.py +0 -0
  224. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/recording.py +0 -0
  225. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/render.py +0 -0
  226. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/review_fingerprint.py +0 -0
  227. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/runner.py +0 -0
  228. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/guardian/skeptic.py +0 -0
  229. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/pipeline.py +0 -0
  230. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/py.typed +0 -0
  231. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/analysis/__init__.py +0 -0
  232. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/analysis/analyzer.py +0 -0
  233. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/analysis/anomaly.py +0 -0
  234. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/analysis/cohesion.py +0 -0
  235. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/analysis/health.py +0 -0
  236. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/analysis/suggest_service.py +0 -0
  237. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/context/__init__.py +0 -0
  238. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/context/context_service.py +0 -0
  239. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/context/orphans.py +0 -0
  240. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/context/prompt.py +0 -0
  241. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/context/snippet.py +0 -0
  242. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/__init__.py +0 -0
  243. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/_scc.py +0 -0
  244. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/drift.py +0 -0
  245. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/drift_service.py +0 -0
  246. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/fingerprint.py +0 -0
  247. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/fractal.py +0 -0
  248. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/ontology_init.py +0 -0
  249. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/quotient.py +0 -0
  250. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/drift/triads.py +0 -0
  251. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/engine.py +0 -0
  252. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/fqn.py +0 -0
  253. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/render/__init__.py +0 -0
  254. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/render/mermaid.py +0 -0
  255. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/query/render/metrics.py +0 -0
  256. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/resolver/.gitkeep +0 -0
  257. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/resolver/__init__.py +0 -0
  258. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/resolver/engine.py +0 -0
  259. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/resolver/indices.py +0 -0
  260. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/resolver/js_builtins.py +0 -0
  261. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/resolver/symbols.py +0 -0
  262. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/resolver/uplift.py +0 -0
  263. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/storage/.gitkeep +0 -0
  264. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/src/cgis/storage/sqlite_store.py +0 -0
  265. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/integration/.gitkeep +0 -0
  266. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/.gitkeep +0 -0
  267. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/__init__.py +0 -0
  268. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/conftest.py +0 -0
  269. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_annotation_calibration.py +0 -0
  270. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_architecture.py +0 -0
  271. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_drift.py +0 -0
  272. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_fractal.py +0 -0
  273. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_init_ontology_roundtrip.py +0 -0
  274. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_receiver_resolution.py +0 -0
  275. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_self_parse.py +0 -0
  276. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_self_parse_ts.py +0 -0
  277. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/self_parsing/test_suggest.py +0 -0
  278. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/.gitkeep +0 -0
  279. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/conftest.py +0 -0
  280. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/guardian_stubs.py +0 -0
  281. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/review_path_inventory.txt +0 -0
  282. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test___main__.py +0 -0
  283. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_analyzer.py +0 -0
  284. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_annotation_edges.py +0 -0
  285. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_backfill_calibration_fingerprint.py +0 -0
  286. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_backfill_review_fingerprint.py +0 -0
  287. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_check_pytest_raises.py +0 -0
  288. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_check_test_count.py +0 -0
  289. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_cohesion.py +0 -0
  290. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_context_service.py +0 -0
  291. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_di_acceptance.py +0 -0
  292. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_drift.py +0 -0
  293. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_drift_service.py +0 -0
  294. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_extractor_registry.py +0 -0
  295. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_fingerprint.py +0 -0
  296. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_fqn.py +0 -0
  297. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_fractal.py +0 -0
  298. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_freshness.py +0 -0
  299. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_gen_ideal_graph.py +0 -0
  300. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_generate_mcp_ref.py +0 -0
  301. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_generated.py +0 -0
  302. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_axes.py +0 -0
  303. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_bench.py +0 -0
  304. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_bench_script.py +0 -0
  305. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_calibrate.py +0 -0
  306. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_calibrate_script.py +0 -0
  307. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_chunked.py +0 -0
  308. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_chunker.py +0 -0
  309. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_collector.py +0 -0
  310. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_core.py +0 -0
  311. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_diff_index.py +0 -0
  312. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_evidence.py +0 -0
  313. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_findings.py +0 -0
  314. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_martian.py +0 -0
  315. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_martian_script.py +0 -0
  316. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_martian_union.py +0 -0
  317. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_metrics.py +0 -0
  318. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_mistral_sampling.py +0 -0
  319. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_ollama_sampling.py +0 -0
  320. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_ollama_truncation.py +0 -0
  321. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_openrouter.py +0 -0
  322. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_poster.py +0 -0
  323. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_providers.py +0 -0
  324. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_providers_name.py +0 -0
  325. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_recording.py +0 -0
  326. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_render.py +0 -0
  327. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_replay_skeptic.py +0 -0
  328. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_review_script.py +0 -0
  329. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_runner.py +0 -0
  330. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_salvage.py +0 -0
  331. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_guardian_skeptic.py +0 -0
  332. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_health_scorer.py +0 -0
  333. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_import_acceptance.py +0 -0
  334. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_inject_architecture_graph.py +0 -0
  335. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_mcp_tool_schemas.py +0 -0
  336. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_mermaid.py +0 -0
  337. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_metrics.py +0 -0
  338. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_models.py +0 -0
  339. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_name_load_positions.py +0 -0
  340. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_ontology_compliance.py +0 -0
  341. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_ontology_init.py +0 -0
  342. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_orphans.py +0 -0
  343. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_paths.py +0 -0
  344. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_patterns_yaml.py +0 -0
  345. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_pipeline.py +0 -0
  346. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_pipeline_incremental_symbols.py +0 -0
  347. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_prompt.py +0 -0
  348. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_python_annotations.py +0 -0
  349. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_python_extractor.py +0 -0
  350. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_query_coverage.py +0 -0
  351. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_quotient.py +0 -0
  352. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_recordings_from_corpus.py +0 -0
  353. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_resolver.py +0 -0
  354. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_resolver_indices.py +0 -0
  355. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_resolver_js_builtins.py +0 -0
  356. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_resolver_language_scope.py +0 -0
  357. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_resolver_symbols.py +0 -0
  358. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_review_fingerprint_closure.py +0 -0
  359. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_review_fingerprint_contract.py +0 -0
  360. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_review_fingerprint_digest.py +0 -0
  361. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_review_fingerprint_record.py +0 -0
  362. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_self_types.py +0 -0
  363. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_skeptic_arms.py +0 -0
  364. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_snippet.py +0 -0
  365. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_sqlite_store.py +0 -0
  366. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_suggest_service.py +0 -0
  367. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_temperature_source.py +0 -0
  368. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_triads.py +0 -0
  369. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_typescript_extractor.py +0 -0
  370. {codegraph_brain-0.23.0 → codegraph_brain-0.23.2}/tests/unit/test_uplift.py +0 -0
@@ -0,0 +1,81 @@
1
+ name: Publish to MCP Registry
2
+
3
+ # A separate workflow file, not a job in release-please.yml: PyPI trusted
4
+ # publishing is bound to that file, so nothing here can mint a PyPI upload token
5
+ # whatever the publisher's environment restriction is (#471).
6
+ #
7
+ # Runs after every Release Please run and publishes only a tagged version the
8
+ # registry does not list yet (scripts/mcp_registry_gate.sh), so ordinary pushes
9
+ # to main are no-ops.
10
+ #
11
+ # A failed Release Please run (PyPI publish or relock) skips this workflow: the
12
+ # red run is the signal. Recover with "Re-run failed jobs" there, or dispatch
13
+ # this workflow on main.
14
+ on:
15
+ workflow_run:
16
+ workflows: ["Release Please"]
17
+ types: [completed]
18
+ branches: [main]
19
+ workflow_dispatch:
20
+
21
+ permissions: {}
22
+
23
+ concurrency:
24
+ group: mcp-registry
25
+ cancel-in-progress: false
26
+
27
+ jobs:
28
+ publish:
29
+ name: Publish server.json
30
+ # Dispatch only from main, so an older branch can't publish its own server.json.
31
+ # The repository check is defence in depth: Release Please never runs for forks.
32
+ if: >-
33
+ (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main') ||
34
+ (github.event.workflow_run.conclusion == 'success' &&
35
+ github.event.workflow_run.head_repository.full_name == github.repository)
36
+ runs-on: ubuntu-latest
37
+ permissions:
38
+ contents: read
39
+ # OIDC for `mcp-publisher login github-oidc`: no stored registry secret.
40
+ id-token: write
41
+ env:
42
+ # Pinned and checksum-verified: this job holds a registry identity, so it must
43
+ # not run whatever `releases/latest` happens to be. Bump both together; a
44
+ # binary too old for the registry fails login with "invalid audience".
45
+ MCP_PUBLISHER_VERSION: "1.8.1"
46
+ MCP_PUBLISHER_SHA256: a06c9096dcb9727c13555b6be26c7effa707b01f06a4c561ba7a3635443cf2cc
47
+ steps:
48
+ - name: Checkout the released commit
49
+ uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
50
+ with:
51
+ ref: ${{ github.event.workflow_run.head_sha || github.sha }}
52
+ persist-credentials: false
53
+
54
+ - name: Decide whether to publish
55
+ id: gate
56
+ run: bash scripts/mcp_registry_gate.sh check >> "$GITHUB_OUTPUT"
57
+
58
+ - name: Wait for the version on PyPI
59
+ if: steps.gate.outputs.publish == 'true'
60
+ run: bash scripts/mcp_registry_gate.sh wait-pypi
61
+
62
+ - name: Install mcp-publisher
63
+ if: steps.gate.outputs.publish == 'true'
64
+ run: |
65
+ set -euo pipefail
66
+ url="https://github.com/modelcontextprotocol/registry/releases/download/v${MCP_PUBLISHER_VERSION}/mcp-publisher_linux_amd64.tar.gz"
67
+ curl --proto '=https' --tlsv1.2 -fsSL "$url" -o mcp-publisher.tar.gz
68
+ echo "${MCP_PUBLISHER_SHA256} mcp-publisher.tar.gz" | sha256sum --check --strict
69
+ tar -xzf mcp-publisher.tar.gz mcp-publisher
70
+
71
+ - name: Validate server.json
72
+ if: steps.gate.outputs.publish == 'true'
73
+ run: ./mcp-publisher validate
74
+
75
+ - name: Log in with GitHub OIDC
76
+ if: steps.gate.outputs.publish == 'true'
77
+ run: ./mcp-publisher login github-oidc
78
+
79
+ - name: Publish
80
+ if: steps.gate.outputs.publish == 'true'
81
+ run: ./mcp-publisher publish
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.23.2"
3
+ }
@@ -1,5 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.23.2](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.1...codegraph-brain-v0.23.2) (2026-09-17)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * **cli:** impact/trace list each neighbour once, JSON each edge once ([#475](https://github.com/zaebee/codegraph-brain/issues/475)) ([9c93b4b](https://github.com/zaebee/codegraph-brain/commit/9c93b4ba5748f99fe2aeb43d698c9d9628e6295a))
9
+
10
+ ## [0.23.1](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.23.0...codegraph-brain-v0.23.1) (2026-09-17)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **audit:** an audit that selects no sources is an error, not an empty pass ([#472](https://github.com/zaebee/codegraph-brain/issues/472)) ([9f93010](https://github.com/zaebee/codegraph-brain/commit/9f93010c286d0b189f3c3350833a5cf557316d8f))
16
+
17
+
18
+ ### Documentation
19
+
20
+ * auto-sync architecture graph and MCP reference ([#468](https://github.com/zaebee/codegraph-brain/issues/468)) ([4c02171](https://github.com/zaebee/codegraph-brain/commit/4c021719776d00ae2f3539409ba847995f79c48e))
21
+ * auto-sync architecture graph and MCP reference ([#473](https://github.com/zaebee/codegraph-brain/issues/473)) ([567b091](https://github.com/zaebee/codegraph-brain/commit/567b09190c61ab5fc2b5b26c0b445bff2cbe5a12))
22
+
3
23
  ## [0.23.0](https://github.com/zaebee/codegraph-brain/compare/codegraph-brain-v0.22.0...codegraph-brain-v0.23.0) (2026-09-17)
4
24
 
5
25
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: codegraph-brain
3
- Version: 0.23.0
3
+ Version: 0.23.2
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
@@ -20,10 +20,10 @@ Analyse transitive upstream callers of a specific FQN.
20
20
 
21
21
  | Argument | Type | Required | Description |
22
22
  | :--- | :--- | :---: | :--- |
23
- | `fqn` | `string` | ✓ | |
24
- | `db_path` | `string` | | |
25
- | `depth` | `integer` | | |
26
- | `output_format` | `string` | | |
23
+ | `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
24
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
25
+ | `depth` | `integer` | | Maximum edge hops upstream. Every edge type counts as a hop — CALLS, but also IMPORTS, CONTAINS and REFERENCES — so modules importing the target and the file containing it appear alongside its callers. |
26
+ | `output_format` | `string` | | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. |
27
27
 
28
28
  ---
29
29
 
@@ -41,13 +41,16 @@ Reachability/authorization audit — which sources never reach a checkpoint (#17
41
41
  ``fqn``/``file``/``line``. Generalizes to validators, event tracking, or
42
42
  service-layer-boundary rules by pointing ``target`` at the required node.
43
43
 
44
+ A selection that matches no source returns a ❌ message, not an empty
45
+ ``{covered: [], gaps: []}`` that would read as a passing audit (#467).
46
+
44
47
  | Argument | Type | Required | Description |
45
48
  | :--- | :--- | :---: | :--- |
46
- | `target` | `string` | ✓ | |
47
- | `db_path` | `string` | | |
48
- | `from_type` | `any` | | |
49
- | `from_prefix` | `any` | | |
50
- | `depth` | `integer` | | |
49
+ | `target` | `string` | ✓ | FQN of the checkpoint every source must reach, e.g. an ownership check. A unique dot-boundary suffix also resolves. |
50
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
51
+ | `from_type` | `any` | | NodeType of the sources to audit, e.g. ROUTE_HANDLER, API_ENDPOINT or FUNCTION (any case). Give this, from_prefix, or both. |
52
+ | `from_prefix` | `any` | | Only audit sources at or under this FQN prefix, matched on whole dot-segments. A selection matching no source is an error naming the whole-segment prefixes it may have meant. Combined with from_type when both are given. |
53
+ | `depth` | `integer` | | Maximum reachability depth; a longer path is reported as a gap. |
51
54
 
52
55
  ---
53
56
 
@@ -70,10 +73,10 @@ Compile an agent-facing GraphRAG context package for a focal FQN (#19).
70
73
 
71
74
  | Argument | Type | Required | Description |
72
75
  | :--- | :--- | :---: | :--- |
73
- | `fqn` | `string` | ✓ | |
74
- | `db_path` | `string` | | |
75
- | `depth` | `integer` | | |
76
- | `source_root` | `string` | | |
76
+ | `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
77
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
78
+ | `depth` | `integer` | | Call hops around the focal node; 1 means direct callers and callees. |
79
+ | `source_root` | `string` | | Directory the graph's stored file paths are relative to — normally the project_path given to cgis_ingest; prefer an absolute path. Empty means the server's working directory, so source shows as unavailable when the server runs elsewhere. |
77
80
 
78
81
  ---
79
82
 
@@ -102,11 +105,11 @@ Report per-domain architectural drift against declared ideal patterns.
102
105
 
103
106
  | Argument | Type | Required | Description |
104
107
  | :--- | :--- | :---: | :--- |
105
- | `db_path` | `string` | | |
106
- | `patterns_path` | `string` | | |
107
- | `max_drift` | `number` | | |
108
- | `profile` | `any` | | |
109
- | `max_residual` | `number` | | |
108
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
109
+ | `patterns_path` | `string` | | patterns.yaml (.yaml or .yml) declaring each domain's expected pattern and tolerance, relative to the server's working directory. cgis_init_ontology proposes one. |
110
+ | `max_drift` | `number` | | Drift tolerance for domains that declare no drift_tolerance of their own. |
111
+ | `profile` | `any` | | Score only domains with this profile, plus profile-less ones — e.g. one language when patterns.yaml mixes several. |
112
+ | `max_residual` | `number` | | Distance to the nearest template beyond which a domain's fit band is "none" (no template fits). |
110
113
 
111
114
  ---
112
115
 
@@ -150,10 +153,10 @@ Classes nothing in production builds, extends or names — dead-code candidates
150
153
 
151
154
  | Argument | Type | Required | Description |
152
155
  | :--- | :--- | :---: | :--- |
153
- | `db_path` | `string` | | |
154
- | `prefix` | `any` | | |
155
- | `include_tests` | `boolean` | | |
156
- | `include_generated` | `boolean` | | |
156
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
157
+ | `prefix` | `any` | | Only consider classes under this FQN prefix, cut on a dot boundary. |
158
+ | `include_tests` | `boolean` | | Count test code as a user, so the report means "unreachable from anywhere". |
159
+ | `include_generated` | `boolean` | | Include machine-generated classes, which are hidden by default. |
157
160
 
158
161
  ---
159
162
 
@@ -170,11 +173,11 @@ Resolve a partial symbol name to candidate FQNs (substring match, ranked).
170
173
 
171
174
  | Argument | Type | Required | Description |
172
175
  | :--- | :--- | :---: | :--- |
173
- | `query` | `string` | ✓ | |
174
- | `db_path` | `string` | | |
175
- | `kind` | `any` | | |
176
- | `fqn_prefix` | `any` | | |
177
- | `limit` | `integer` | | |
176
+ | `query` | `string` | ✓ | Leaf symbol name to search for, without dots (e.g. get_flow_result) — not an FQN. Case-insensitive substring match, ranked exact > prefix > substring. |
177
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
178
+ | `kind` | `any` | | Only return this node type, e.g. FUNCTION, METHOD or CLASS (any case). An unknown type matches nothing rather than raising an error. |
179
+ | `fqn_prefix` | `any` | | Only return symbols at or under this FQN prefix, matched on whole dot-segments: app.svc does not match app.svc_alt, and a partial segment matches nothing. |
180
+ | `limit` | `integer` | | Maximum number of candidates to return. |
178
181
 
179
182
  ---
180
183
 
@@ -200,7 +203,7 @@ Report the motif census across the repository's structural tiers.
200
203
 
201
204
  | Argument | Type | Required | Description |
202
205
  | :--- | :--- | :---: | :--- |
203
- | `db_path` | `string` | | |
206
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
204
207
 
205
208
  ---
206
209
 
@@ -215,10 +218,10 @@ Show the structural layout (CONTAINS/DECLARES) of a module or class.
215
218
 
216
219
  | Argument | Type | Required | Description |
217
220
  | :--- | :--- | :---: | :--- |
218
- | `fqn` | `string` | ✓ | |
219
- | `db_path` | `string` | | |
220
- | `depth` | `integer` | | |
221
- | `output_format` | `string` | | |
221
+ | `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
222
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
223
+ | `depth` | `integer` | | Maximum containment levels to descend (module → class → method). |
224
+ | `output_format` | `string` | | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. |
222
225
 
223
226
  ---
224
227
 
@@ -245,9 +248,9 @@ Scan a local directory, extract all symbols, resolve links, and build the graph
245
248
 
246
249
  | Argument | Type | Required | Description |
247
250
  | :--- | :--- | :---: | :--- |
248
- | `project_path` | `string` | ✓ | |
249
- | `db_path` | `string` | | |
250
- | `full_rebuild` | `boolean` | | |
251
+ | `project_path` | `string` | ✓ | Root directory of the project to scan. A relative path resolves against the MCP server's working directory. |
252
+ | `db_path` | `string` | | Where to write the graph: must end in .db, .sqlite or .sqlite3, in a directory that already exists, and must not be an existing non-SQLite file. A relative path resolves against the server's working directory. |
253
+ | `full_rebuild` | `boolean` | | Re-scan every file from scratch instead of the incremental default. |
251
254
 
252
255
  ---
253
256
 
@@ -263,10 +266,10 @@ Propose a starter patterns.yaml from the measured graph (read-only).
263
266
 
264
267
  | Argument | Type | Required | Description |
265
268
  | :--- | :--- | :---: | :--- |
266
- | `db_path` | `string` | | |
267
- | `margin` | `number` | | |
268
- | `min_nodes` | `integer` | | |
269
- | `depth` | `any` | | |
269
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
270
+ | `margin` | `number` | | Headroom added to each measured score to form the proposed tolerance. |
271
+ | `min_nodes` | `integer` | | Domains with fewer nodes stay hygiene-only instead of getting a label. |
272
+ | `depth` | `any` | | Fixed FQN segment depth for domain discovery (positive); omit to pick it automatically. |
270
273
 
271
274
  ---
272
275
 
@@ -297,10 +300,10 @@ Whole-graph architectural metrics — coupling bottlenecks + God classes (#16).
297
300
 
298
301
  | Argument | Type | Required | Description |
299
302
  | :--- | :--- | :---: | :--- |
300
- | `db_path` | `string` | | |
301
- | `limit` | `integer` | | |
302
- | `exclude` | `any` | | |
303
- | `scope` | `any` | | |
303
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
304
+ | `limit` | `integer` | | Top-N rows returned per section. |
305
+ | `exclude` | `any` | | Drop nodes whose FQN contains any of these dot-segments, e.g. ["tests"]; they are removed from PageRank propagation too. |
306
+ | `scope` | `any` | | Keep only nodes under any of these dot-prefixes, e.g. ["domains.billing"]; rank still propagates over the whole graph. |
304
307
 
305
308
  ---
306
309
 
@@ -319,10 +322,10 @@ Suggest sub-package boundaries for a package from its dependency communities.
319
322
 
320
323
  | Argument | Type | Required | Description |
321
324
  | :--- | :--- | :---: | :--- |
322
- | `db_path` | `string` | | |
323
- | `prefix` | `any` | | |
324
- | `with_calls` | `boolean` | | |
325
- | `min_q` | `number` | | |
325
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
326
+ | `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. |
327
+ | `with_calls` | `boolean` | | Use the combined import + call graph instead of imports only. |
328
+ | `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). |
326
329
 
327
330
  ---
328
331
 
@@ -341,10 +344,10 @@ Trace the execution call-graph starting from a specific FQN downwards.
341
344
 
342
345
  | Argument | Type | Required | Description |
343
346
  | :--- | :--- | :---: | :--- |
344
- | `fqn` | `string` | ✓ | |
345
- | `db_path` | `string` | | |
346
- | `depth` | `integer` | | |
347
- | `output_format` | `string` | | |
347
+ | `fqn` | `string` | ✓ | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. |
348
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
349
+ | `depth` | `integer` | | Maximum edge hops downstream. Every edge type counts as a hop — CALLS, but also IMPORTS, CONTAINS and REFERENCES — so from a module the first hops are mostly imports and structure. |
350
+ | `output_format` | `string` | | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. |
348
351
 
349
352
  ---
350
353
 
@@ -357,7 +360,7 @@ Report graph integrity as JSON: edge resolution stats + health verdict.
357
360
 
358
361
  | Argument | Type | Required | Description |
359
362
  | :--- | :--- | :---: | :--- |
360
- | `db_path` | `string` | | |
361
- | `threshold` | `number` | | |
363
+ | `db_path` | `string` | | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's — prefer an absolute path. |
364
+ | `threshold` | `number` | | Highest unresolved-edge ratio (0-1) still reported as healthy. |
362
365
 
363
366
  ---
@@ -7,7 +7,7 @@ packages = ["src/cgis"]
7
7
 
8
8
  [project]
9
9
  name = "codegraph-brain"
10
- version = "0.23.0"
10
+ version = "0.23.2"
11
11
  description = "Semantic code graph for AI agents — deterministic FQN resolution, impact analysis and architectural drift gates, exposed over MCP."
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.12"
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env bash
2
+ # Decide whether server.json's version should be published to the MCP Registry,
3
+ # and wait until PyPI can back it (#471).
4
+ #
5
+ # scripts/mcp_registry_gate.sh check → prints publish=true|false (for $GITHUB_OUTPUT)
6
+ # scripts/mcp_registry_gate.sh wait-pypi → blocks until PyPI serves the version
7
+ #
8
+ # `check` is what makes the workflow safe to run after *every* Release Please run:
9
+ # only a tagged release that the registry does not list yet is published, so a
10
+ # docs push to main is a no-op and a re-run never double-publishes.
11
+ #
12
+ # Every lookup fails closed. `publish=false` is printed only on a definite answer
13
+ # (no such tag, version already listed); a network error or an unexpected
14
+ # response exits non-zero, because a silently skipped release is exactly what
15
+ # this automation exists to prevent.
16
+ #
17
+ # `wait-pypi` exists because the registry verifies ownership by fetching
18
+ # pypi.org/pypi/<pkg>/<version>/json and looking for the mcp-name marker, and a
19
+ # fresh upload is not always visible there straight away (0.23.0 and 0.23.1 both
20
+ # failed a `pip install` for a few minutes after the publish job went green).
21
+ set -euo pipefail
22
+
23
+ REGISTRY="${MCP_REGISTRY_URL:-https://registry.modelcontextprotocol.io}"
24
+ PYPI="${PYPI_URL:-https://pypi.org}"
25
+ TAG_PREFIX="${TAG_PREFIX:-codegraph-brain-v}"
26
+ WAIT_SECONDS="${WAIT_SECONDS:-600}"
27
+ POLL_SECONDS="${POLL_SECONDS:-15}"
28
+
29
+ fail() {
30
+ echo "::error::$*" >&2
31
+ exit 1
32
+ }
33
+
34
+ read_field() {
35
+ local filter="$1" label="$2" value
36
+ value=$(jq -r "${filter} // empty" server.json) || fail "server.json is not valid JSON."
37
+ [[ -n "$value" ]] || fail "server.json has no ${label} (${filter})."
38
+ printf '%s' "$value"
39
+ }
40
+
41
+ name=$(read_field .name "server name")
42
+ version=$(read_field .version "version")
43
+ package=$(read_field 'first(.packages[]? | select(.registryType == "pypi") | .identifier)' "PyPI package")
44
+
45
+ check() {
46
+ local tag="refs/tags/${TAG_PREFIX}${version}" rc=0
47
+ git ls-remote --exit-code --tags origin "$tag" >/dev/null || rc=$?
48
+ case "$rc" in
49
+ 0) ;;
50
+ 2)
51
+ echo "No tag ${TAG_PREFIX}${version}: not a release, nothing to publish." >&2
52
+ echo "publish=false"
53
+ return
54
+ ;;
55
+ *) fail "git ls-remote for ${tag} failed (exit ${rc}); cannot tell whether this is a release." ;;
56
+ esac
57
+
58
+ # The status alone is not enough: a moved API also answers 404, and a proxy can
59
+ # answer 200 with nothing. Each answer must also carry the body that means it.
60
+ local encoded body status
61
+ encoded=$(jq -rn --arg n "$name" '$n | @uri')
62
+ body=$(mktemp)
63
+ status=$(curl -sS -o "$body" -w '%{http_code}' \
64
+ "${REGISTRY}/v0/servers/${encoded}/versions/${version}") ||
65
+ fail "Registry lookup for ${name} ${version} failed."
66
+ if [[ "$status" == 200 ]] &&
67
+ jq -e --arg n "$name" --arg v "$version" \
68
+ '.server.name == $n and .server.version == $v' "$body" >/dev/null 2>&1; then
69
+ echo "${name} ${version} is already in the registry." >&2
70
+ echo "publish=false"
71
+ elif [[ "$status" == 404 ]] &&
72
+ jq -e '.detail == "Server not found"' "$body" >/dev/null 2>&1; then
73
+ echo "${name} ${version} is released and not in the registry yet." >&2
74
+ echo "publish=true"
75
+ else
76
+ fail "Unexpected registry answer for ${name} ${version}: HTTP ${status}, $(head -c 200 "$body")"
77
+ fi
78
+ rm -f "$body"
79
+ }
80
+
81
+ wait_pypi() {
82
+ local marker="mcp-name: ${name}" deadline=$((SECONDS + WAIT_SECONDS))
83
+ until curl -fsS "${PYPI}/pypi/${package}/${version}/json" 2>/dev/null |
84
+ jq -e --arg m "$marker" '(.info.description // "") | contains($m)' >/dev/null 2>&1; do
85
+ if [[ "$SECONDS" -ge "$deadline" ]]; then
86
+ fail "${package} ${version} with '${marker}' not on PyPI after ${WAIT_SECONDS}s." \
87
+ "Publish manually once it is: mcp-publisher login github && mcp-publisher publish"
88
+ fi
89
+ sleep "$POLL_SECONDS"
90
+ done
91
+ echo "${package} ${version} is on PyPI with the mcp-name marker." >&2
92
+ }
93
+
94
+ case "${1:-}" in
95
+ check) check ;;
96
+ wait-pypi) wait_pypi ;;
97
+ *)
98
+ echo "usage: $0 check|wait-pypi" >&2
99
+ exit 2
100
+ ;;
101
+ esac
@@ -8,13 +8,13 @@
8
8
  "source": "github",
9
9
  "id": "1260843154"
10
10
  },
11
- "version": "0.23.0",
11
+ "version": "0.23.2",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "pypi",
15
15
  "registryBaseUrl": "https://pypi.org",
16
16
  "identifier": "codegraph-brain",
17
- "version": "0.23.0",
17
+ "version": "0.23.2",
18
18
  "runtimeHint": "uvx",
19
19
  "transport": {
20
20
  "type": "stdio"
@@ -966,8 +966,9 @@ def cgis_audit_reachability(
966
966
  str | None,
967
967
  Field(
968
968
  description="Only audit sources at or under this FQN prefix, matched on whole "
969
- "dot-segments — a partial segment selects nothing and returns an empty audit, "
970
- "not a clean one. Combined with from_type when both are given."
969
+ "dot-segments. A selection matching no source is an error naming the "
970
+ "whole-segment prefixes it may have meant. Combined with from_type when both "
971
+ "are given."
971
972
  ),
972
973
  ] = None,
973
974
  depth: Annotated[
@@ -986,6 +987,9 @@ def cgis_audit_reachability(
986
987
  one is required. Returns JSON ``{target, covered, gaps}`` where each gap carries
987
988
  ``fqn``/``file``/``line``. Generalizes to validators, event tracking, or
988
989
  service-layer-boundary rules by pointing ``target`` at the required node.
990
+
991
+ A selection that matches no source returns a ❌ message, not an empty
992
+ ``{covered: [], gaps: []}`` that would read as a passing audit (#467).
989
993
  """
990
994
  if blank := _blank_fqn_error(target):
991
995
  return blank
@@ -20,6 +20,7 @@ style tags you wrote yourself and pure numbers need no escaping.
20
20
 
21
21
  import dataclasses
22
22
  import json as _json
23
+ from collections.abc import Callable
23
24
  from enum import StrEnum
24
25
  from pathlib import Path
25
26
 
@@ -42,7 +43,7 @@ from cgis.query.analysis.analyzer import AnalyzerEngine
42
43
  from cgis.query.analysis.anomaly import AnomalyType, ArchitecturalAnomaly
43
44
  from cgis.query.analysis.health import HealthScorer
44
45
  from cgis.query.analysis.suggest_service import SuggestReport, report_to_dict, suggest_packages
45
- from cgis.query.context.audit import ReachabilityAudit, audit_reachability
46
+ from cgis.query.context.audit import NoAuditSourcesError, ReachabilityAudit, audit_reachability
46
47
  from cgis.query.context.context_service import build_context
47
48
  from cgis.query.context.orphans import OrphanReport, find_orphan_classes
48
49
  from cgis.query.drift.drift import DriftReport, FitQuality
@@ -318,6 +319,40 @@ def _resolve_cli_fqn(store: SQLiteStore, target: str, kind: str) -> str:
318
319
  return resolution.resolved
319
320
 
320
321
 
322
+ def _tree_neighbours(
323
+ store: SQLiteStore,
324
+ edges: list[Edge],
325
+ neighbour_of: Callable[[Edge], str],
326
+ *,
327
+ allowed_edge_types: frozenset[EdgeType] | None,
328
+ show_external: bool,
329
+ min_confidence: float | None,
330
+ ) -> list[tuple[str, Node | None]]:
331
+ """The neighbours one tree level shows: filtered, in edge order, each id once.
332
+
333
+ One entry per neighbour, not per edge: two call sites are separate edges to the
334
+ same node, and a tree row shows neither line nor edge type to tell them apart
335
+ (#463). A neighbour absent from the store (an unresolved target) comes back with
336
+ ``None``, and is dropped with the non-INTERNAL ones when ``show_external`` is off.
337
+ """
338
+ if allowed_edge_types is not None:
339
+ edges = [e for e in edges if e.type in allowed_edge_types]
340
+ if min_confidence is not None:
341
+ edges = [e for e in edges if e.confidence >= min_confidence]
342
+ ids = list(dict.fromkeys(neighbour_of(e) for e in edges))
343
+ nodes = {n.id: n for n in store.get_nodes(ids)}
344
+ return [
345
+ (node_id, nodes.get(node_id))
346
+ for node_id in ids
347
+ if show_external or _is_internal(nodes.get(node_id))
348
+ ]
349
+
350
+
351
+ def _is_internal(node: Node | None) -> bool:
352
+ """True for a stored node from the ingested repository."""
353
+ return node is not None and node.namespace == NodeNamespace.INTERNAL
354
+
355
+
321
356
  def build_trace_tree(
322
357
  store: SQLiteStore,
323
358
  current_id: str,
@@ -333,21 +368,15 @@ def build_trace_tree(
333
368
  if current_depth >= max_depth:
334
369
  return
335
370
 
336
- outgoing = store.get_outgoing_edges(current_id)
337
- if allowed_edge_types is not None:
338
- outgoing = [e for e in outgoing if e.type in allowed_edge_types]
339
- if min_confidence is not None:
340
- outgoing = [e for e in outgoing if e.confidence >= min_confidence]
341
- nodes_map = {n.id: n for n in store.get_nodes([e.target for e in outgoing])}
342
- for edge in outgoing:
343
- target_id = edge.target
344
- target_node = nodes_map.get(target_id)
345
-
346
- if not show_external and (
347
- target_node is None or target_node.namespace != NodeNamespace.INTERNAL
348
- ):
349
- continue
350
-
371
+ callees = _tree_neighbours(
372
+ store,
373
+ store.get_outgoing_edges(current_id),
374
+ lambda edge: edge.target,
375
+ allowed_edge_types=allowed_edge_types,
376
+ show_external=show_external,
377
+ min_confidence=min_confidence,
378
+ )
379
+ for target_id, target_node in callees:
351
380
  if target_node:
352
381
  label = (
353
382
  f"[bold green]{target_node.type.value}[/bold green] "
@@ -470,21 +499,15 @@ def build_impact_tree(
470
499
  if current_depth >= max_depth:
471
500
  return
472
501
 
473
- incoming = store.get_incoming_edges(current_id)
474
- if allowed_edge_types is not None:
475
- incoming = [e for e in incoming if e.type in allowed_edge_types]
476
- if min_confidence is not None:
477
- incoming = [e for e in incoming if e.confidence >= min_confidence]
478
- nodes_map = {n.id: n for n in store.get_nodes([e.source for e in incoming])}
479
- for edge in incoming:
480
- source_id = edge.source
481
- source_node = nodes_map.get(source_id)
482
-
483
- if not show_external and (
484
- source_node is None or source_node.namespace != NodeNamespace.INTERNAL
485
- ):
486
- continue
487
-
502
+ callers = _tree_neighbours(
503
+ store,
504
+ store.get_incoming_edges(current_id),
505
+ lambda edge: edge.source,
506
+ allowed_edge_types=allowed_edge_types,
507
+ show_external=show_external,
508
+ min_confidence=min_confidence,
509
+ )
510
+ for source_id, source_node in callers:
488
511
  if source_node:
489
512
  label = (
490
513
  f"[bold magenta]{source_node.type.value}[/bold magenta] "
@@ -1445,7 +1468,7 @@ def audit(
1445
1468
  help="Only audit nodes of this type (e.g. ROUTE_HANDLER, API_ENDPOINT).",
1446
1469
  ),
1447
1470
  from_prefix: str | None = typer.Option(
1448
- None, "--from-prefix", help="Only audit nodes whose FQN starts with this prefix."
1471
+ None, "--from-prefix", help="Only audit nodes under this FQN prefix (whole dot-segments)."
1449
1472
  ),
1450
1473
  db: str = typer.Option(_DEFAULT_DB, "--db", "-d", help=_DEFAULT_DB_HELP),
1451
1474
  depth: int = typer.Option(
@@ -1487,13 +1510,19 @@ def audit(
1487
1510
 
1488
1511
  with SQLiteStore(db) as store:
1489
1512
  resolved = _resolve_checkpoint(store, target)
1490
- result = audit_reachability(
1491
- store,
1492
- target_fqn=resolved,
1493
- from_type=from_type,
1494
- from_prefix=from_prefix,
1495
- max_depth=depth,
1496
- )
1513
+ try:
1514
+ result = audit_reachability(
1515
+ store,
1516
+ target_fqn=resolved,
1517
+ from_type=from_type,
1518
+ from_prefix=from_prefix,
1519
+ max_depth=depth,
1520
+ )
1521
+ except NoAuditSourcesError as exc:
1522
+ # Exit 2 like a bad selector: exit 0 here let a typo'd prefix pass a CI gate (#467).
1523
+ # stderr, like _resolve_checkpoint: `--format json` stdout stays a clean payload.
1524
+ err_console.print(f"[bold red]❌ {escape(str(exc))}[/bold red]")
1525
+ raise typer.Exit(code=2) from exc
1497
1526
 
1498
1527
  if output_format == OutputFormat.JSON:
1499
1528
  typer.echo(_json.dumps(dataclasses.asdict(result), indent=2))