roam-code 12.0.0__tar.gz → 12.2.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 (535) hide show
  1. {roam_code-12.0.0/src/roam_code.egg-info → roam_code-12.2.0}/PKG-INFO +42 -12
  2. {roam_code-12.0.0 → roam_code-12.2.0}/README.md +32 -11
  3. {roam_code-12.0.0 → roam_code-12.2.0}/pyproject.toml +24 -1
  4. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/attest/cga.py +34 -9
  5. roam_code-12.2.0/src/roam/bridges/bridge_django.py +662 -0
  6. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/registry.py +4 -0
  7. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/cli.py +7 -1
  8. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/changed_files.py +5 -0
  9. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_cga.py +21 -4
  10. roam_code-12.2.0/src/roam/commands/cmd_eval_retrieve.py +318 -0
  11. roam_code-12.2.0/src/roam/commands/cmd_index_bundle.py +435 -0
  12. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_mcp_setup.py +39 -2
  13. roam_code-12.2.0/src/roam/commands/cmd_oracle.py +306 -0
  14. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_retrieve.py +7 -2
  15. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_sbom.py +26 -2
  16. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/competitor_site_data.py +1 -1
  17. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/config.py +4 -0
  18. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/db/connection.py +8 -0
  19. roam_code-12.2.0/src/roam/git_utils.py +63 -0
  20. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/clusters.py +63 -8
  21. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/discovery.py +8 -1
  22. roam_code-12.2.0/src/roam/index/django_post.py +423 -0
  23. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/git_stats.py +8 -1
  24. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/indexer.py +20 -0
  25. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/mcp_server.py +411 -2
  26. roam_code-12.2.0/src/roam/retrieve/learned_ranker.py +241 -0
  27. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/retrieve/pipeline.py +24 -1
  28. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/retrieve/rerank.py +48 -1
  29. roam_code-12.2.0/src/roam/retrieve/semantic.py +194 -0
  30. roam_code-12.2.0/src/roam/runtime/daemon.py +100 -0
  31. roam_code-12.2.0/src/roam/runtime/graph_backend.py +92 -0
  32. roam_code-12.2.0/src/roam/runtime/lock_modes.py +50 -0
  33. roam_code-12.2.0/src/roam/runtime/lockmgr.py +136 -0
  34. roam_code-12.2.0/src/roam/security/aibom_extension.py +249 -0
  35. roam_code-12.2.0/src/roam/security/taint_classifier.py +224 -0
  36. {roam_code-12.0.0 → roam_code-12.2.0/src/roam_code.egg-info}/PKG-INFO +42 -12
  37. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam_code.egg-info/SOURCES.txt +19 -0
  38. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam_code.egg-info/requires.txt +13 -0
  39. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_batch_mcp.py +9 -1
  40. roam_code-12.2.0/tests/test_bridge_django.py +181 -0
  41. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_defer_loading.py +7 -0
  42. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_eval_retrieve.py +113 -0
  43. roam_code-12.2.0/tests/test_git_utils.py +164 -0
  44. roam_code-12.2.0/tests/test_index_bundle.py +275 -0
  45. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_mcp_server.py +25 -6
  46. roam_code-12.2.0/tests/test_oracle.py +345 -0
  47. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_readme_surface_consistency.py +7 -1
  48. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_retrieve.py +1 -0
  49. roam_code-12.2.0/tests/test_taint_classifier.py +253 -0
  50. roam_code-12.2.0/tests/test_v12_2.py +300 -0
  51. roam_code-12.0.0/src/roam/commands/cmd_eval_retrieve.py +0 -174
  52. {roam_code-12.0.0 → roam_code-12.2.0}/LICENSE +0 -0
  53. {roam_code-12.0.0 → roam_code-12.2.0}/setup.cfg +0 -0
  54. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/__init__.py +0 -0
  55. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/__main__.py +0 -0
  56. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/analysis/__init__.py +0 -0
  57. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/analysis/effects.py +0 -0
  58. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/analysis/taint.py +0 -0
  59. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/api.py +0 -0
  60. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/ask/__init__.py +0 -0
  61. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/ask/classifier.py +0 -0
  62. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/ask/recipes.py +0 -0
  63. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/ask/runner.py +0 -0
  64. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/attest/__init__.py +0 -0
  65. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/__init__.py +0 -0
  66. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/base.py +0 -0
  67. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/bridge_config.py +0 -0
  68. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/bridge_protobuf.py +0 -0
  69. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/bridge_rest_api.py +0 -0
  70. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/bridge_salesforce.py +0 -0
  71. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/bridges/bridge_template.py +0 -0
  72. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/catalog/__init__.py +0 -0
  73. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/catalog/detectors.py +0 -0
  74. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/catalog/fixes.py +0 -0
  75. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/catalog/smells.py +0 -0
  76. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/catalog/tasks.py +0 -0
  77. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/__init__.py +0 -0
  78. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_adrs.py +0 -0
  79. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_adversarial.py +0 -0
  80. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_affected.py +0 -0
  81. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_affected_tests.py +0 -0
  82. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_agent_context.py +0 -0
  83. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_agent_export.py +0 -0
  84. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_agent_plan.py +0 -0
  85. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_ai_ratio.py +0 -0
  86. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_ai_readiness.py +0 -0
  87. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_alerts.py +0 -0
  88. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_annotate.py +0 -0
  89. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_api_changes.py +0 -0
  90. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_api_drift.py +0 -0
  91. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_ask.py +0 -0
  92. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_attest.py +0 -0
  93. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_auth_gaps.py +0 -0
  94. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_bisect.py +0 -0
  95. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_breaking.py +0 -0
  96. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_budget.py +0 -0
  97. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_bus_factor.py +0 -0
  98. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_capsule.py +0 -0
  99. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_check_rules.py +0 -0
  100. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_ci_setup.py +0 -0
  101. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_clean.py +0 -0
  102. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_clones.py +0 -0
  103. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_closure.py +0 -0
  104. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_clusters.py +0 -0
  105. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_codeowners.py +0 -0
  106. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_complexity.py +0 -0
  107. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_config.py +0 -0
  108. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_congestion.py +0 -0
  109. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_context.py +0 -0
  110. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_conventions.py +0 -0
  111. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_coupling.py +0 -0
  112. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_coverage_gaps.py +0 -0
  113. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_critique.py +0 -0
  114. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_cut.py +0 -0
  115. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_dark_matter.py +0 -0
  116. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_dashboard.py +0 -0
  117. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_dead.py +0 -0
  118. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_debt.py +0 -0
  119. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_deps.py +0 -0
  120. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_describe.py +0 -0
  121. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_dev_profile.py +0 -0
  122. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_diagnose.py +0 -0
  123. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_diff.py +0 -0
  124. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_doc_staleness.py +0 -0
  125. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_docs_coverage.py +0 -0
  126. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_doctor.py +0 -0
  127. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_drift.py +0 -0
  128. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_duplicates.py +0 -0
  129. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_effects.py +0 -0
  130. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_endpoints.py +0 -0
  131. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_entry_points.py +0 -0
  132. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_fan.py +0 -0
  133. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_file.py +0 -0
  134. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_fingerprint.py +0 -0
  135. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_fitness.py +0 -0
  136. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_flag_dead.py +0 -0
  137. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_fleet.py +0 -0
  138. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_fn_coupling.py +0 -0
  139. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_forecast.py +0 -0
  140. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_grep.py +0 -0
  141. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_guard.py +0 -0
  142. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_health.py +0 -0
  143. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_hooks.py +0 -0
  144. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_hotspots.py +0 -0
  145. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_impact.py +0 -0
  146. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_index.py +0 -0
  147. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_ingest_trace.py +0 -0
  148. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_init.py +0 -0
  149. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_intent.py +0 -0
  150. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_invariants.py +0 -0
  151. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_layers.py +0 -0
  152. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_map.py +0 -0
  153. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_math.py +0 -0
  154. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_metrics.py +0 -0
  155. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_migration_safety.py +0 -0
  156. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_minimap.py +0 -0
  157. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_missing_index.py +0 -0
  158. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_module.py +0 -0
  159. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_mutate.py +0 -0
  160. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_n1.py +0 -0
  161. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_orchestrate.py +0 -0
  162. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_orphan_routes.py +0 -0
  163. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_over_fetch.py +0 -0
  164. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_owner.py +0 -0
  165. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_partition.py +0 -0
  166. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_path_coverage.py +0 -0
  167. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_patterns.py +0 -0
  168. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_plan.py +0 -0
  169. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_plan_refactor.py +0 -0
  170. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_pr_diff.py +0 -0
  171. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_pr_risk.py +0 -0
  172. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_preflight.py +0 -0
  173. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_relate.py +0 -0
  174. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_report.py +0 -0
  175. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_reset.py +0 -0
  176. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_risk.py +0 -0
  177. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_rules.py +0 -0
  178. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_safe_delete.py +0 -0
  179. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_safe_zones.py +0 -0
  180. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_schema.py +0 -0
  181. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_search.py +0 -0
  182. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_search_semantic.py +0 -0
  183. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_secrets.py +0 -0
  184. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_semantic_diff.py +0 -0
  185. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_simulate.py +0 -0
  186. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_simulate_departure.py +0 -0
  187. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_sketch.py +0 -0
  188. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_smells.py +0 -0
  189. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_spectral.py +0 -0
  190. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_split.py +0 -0
  191. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
  192. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
  193. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_supply_chain.py +0 -0
  194. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_symbol.py +0 -0
  195. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_syntax_check.py +0 -0
  196. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_taint.py +0 -0
  197. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_test_gaps.py +0 -0
  198. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_test_scaffold.py +0 -0
  199. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_testmap.py +0 -0
  200. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_tour.py +0 -0
  201. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_trace.py +0 -0
  202. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_trends.py +0 -0
  203. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_triage.py +0 -0
  204. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_understand.py +0 -0
  205. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_uses.py +0 -0
  206. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_verify.py +0 -0
  207. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_verify_imports.py +0 -0
  208. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_vibe_check.py +0 -0
  209. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_visualize.py +0 -0
  210. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_vuln_map.py +0 -0
  211. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_vuln_reach.py +0 -0
  212. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_vulns.py +0 -0
  213. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_watch.py +0 -0
  214. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_weather.py +0 -0
  215. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_why.py +0 -0
  216. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_ws.py +0 -0
  217. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/cmd_xlang.py +0 -0
  218. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/codeowners_helpers.py +0 -0
  219. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/context_helpers.py +0 -0
  220. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/gate_presets.py +0 -0
  221. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/graph_helpers.py +0 -0
  222. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/metrics_history.py +0 -0
  223. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/next_steps.py +0 -0
  224. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/resolve.py +0 -0
  225. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/commands/suppression.py +0 -0
  226. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/coverage_reports.py +0 -0
  227. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/critique/__init__.py +0 -0
  228. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/critique/aggregator.py +0 -0
  229. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/critique/checks.py +0 -0
  230. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/db/__init__.py +0 -0
  231. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/db/queries.py +0 -0
  232. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/db/schema.py +0 -0
  233. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/eval/__init__.py +0 -0
  234. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/eval/harness.py +0 -0
  235. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/exit_codes.py +0 -0
  236. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/fleet/__init__.py +0 -0
  237. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/fleet/adapters.py +0 -0
  238. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/fleet/manifest.py +0 -0
  239. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/__init__.py +0 -0
  240. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/anomaly.py +0 -0
  241. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/builder.py +0 -0
  242. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/clone_detect.py +0 -0
  243. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/cycles.py +0 -0
  244. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/dark_matter.py +0 -0
  245. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/diff.py +0 -0
  246. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/fingerprint.py +0 -0
  247. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/layers.py +0 -0
  248. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/pagerank.py +0 -0
  249. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/partition.py +0 -0
  250. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/pathfinding.py +0 -0
  251. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/propagation.py +0 -0
  252. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/simulate.py +0 -0
  253. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/spectral.py +0 -0
  254. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/graph/stats.py +0 -0
  255. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/__init__.py +0 -0
  256. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/complexity.py +0 -0
  257. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/file_roles.py +0 -0
  258. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/gitignore.py +0 -0
  259. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/incremental.py +0 -0
  260. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/parser.py +0 -0
  261. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/relations.py +0 -0
  262. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/symbols.py +0 -0
  263. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/index/test_conventions.py +0 -0
  264. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/__init__.py +0 -0
  265. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/apex_lang.py +0 -0
  266. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/aura_lang.py +0 -0
  267. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/base.py +0 -0
  268. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/c_lang.py +0 -0
  269. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/csharp_lang.py +0 -0
  270. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/extractor_schema.py +0 -0
  271. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/foxpro_lang.py +0 -0
  272. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/generic_lang.py +0 -0
  273. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/go_lang.py +0 -0
  274. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/hcl_lang.py +0 -0
  275. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/java_lang.py +0 -0
  276. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/javascript_lang.py +0 -0
  277. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/kotlin_lang.py +0 -0
  278. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/php_lang.py +0 -0
  279. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/python_lang.py +0 -0
  280. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/query_engine.py +0 -0
  281. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/registry.py +0 -0
  282. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/ruby_lang.py +0 -0
  283. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/rust_lang.py +0 -0
  284. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/scala_lang.py +0 -0
  285. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/sfxml_lang.py +0 -0
  286. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/sql_lang.py +0 -0
  287. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/swift_lang.py +0 -0
  288. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/typescript_lang.py +0 -0
  289. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/visualforce_lang.py +0 -0
  290. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/languages/yaml_lang.py +0 -0
  291. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/mcp_extras/__init__.py +0 -0
  292. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/mcp_extras/completions.py +0 -0
  293. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/mcp_extras/progress.py +0 -0
  294. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/mcp_extras/sampling.py +0 -0
  295. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/mcp_extras/session.py +0 -0
  296. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/mcp_extras/watcher.py +0 -0
  297. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/output/__init__.py +0 -0
  298. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/output/formatter.py +0 -0
  299. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/output/mermaid.py +0 -0
  300. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/output/sarif.py +0 -0
  301. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/output/schema_registry.py +0 -0
  302. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/plugins.py +0 -0
  303. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/refactor/__init__.py +0 -0
  304. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/refactor/codegen.py +0 -0
  305. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/refactor/transforms.py +0 -0
  306. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/retrieve/__init__.py +0 -0
  307. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/retrieve/seeds.py +0 -0
  308. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/rules/__init__.py +0 -0
  309. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/rules/ast_match.py +0 -0
  310. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/rules/builtin.py +0 -0
  311. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/rules/dataflow.py +0 -0
  312. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/rules/engine.py +0 -0
  313. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/runtime/__init__.py +0 -0
  314. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/runtime/hotspots.py +0 -0
  315. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/runtime/trace_ingest.py +0 -0
  316. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/search/__init__.py +0 -0
  317. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/search/framework_packs.py +0 -0
  318. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/search/index_embeddings.py +0 -0
  319. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/search/onnx_embeddings.py +0 -0
  320. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/search/tfidf.py +0 -0
  321. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/security/__init__.py +0 -0
  322. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/security/taint_engine.py +0 -0
  323. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/security/vuln_reach.py +0 -0
  324. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/security/vuln_store.py +0 -0
  325. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/surface_counts.py +0 -0
  326. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/templates/__init__.py +0 -0
  327. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/templates/ci/__init__.py +0 -0
  328. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/workspace/__init__.py +0 -0
  329. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/workspace/aggregator.py +0 -0
  330. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/workspace/api_scanner.py +0 -0
  331. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/workspace/config.py +0 -0
  332. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam/workspace/db.py +0 -0
  333. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam_code.egg-info/dependency_links.txt +0 -0
  334. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam_code.egg-info/entry_points.txt +0 -0
  335. {roam_code-12.0.0 → roam_code-12.2.0}/src/roam_code.egg-info/top_level.txt +0 -0
  336. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_adrs.py +0 -0
  337. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_adversarial.py +0 -0
  338. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_affected.py +0 -0
  339. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_agent_export.py +0 -0
  340. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_agent_mode.py +0 -0
  341. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_agent_plan_context.py +0 -0
  342. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ai_ratio.py +0 -0
  343. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ai_readiness.py +0 -0
  344. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_alerts_cmd.py +0 -0
  345. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_annotations.py +0 -0
  346. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_anomaly.py +0 -0
  347. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_api_changes.py +0 -0
  348. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_api_drift.py +0 -0
  349. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ask.py +0 -0
  350. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_attest.py +0 -0
  351. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_auth_gaps.py +0 -0
  352. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_backend_fixes_round2.py +0 -0
  353. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_backend_fixes_round3.py +0 -0
  354. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_basic.py +0 -0
  355. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_bisect.py +0 -0
  356. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_bridges.py +0 -0
  357. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_bridges_extended.py +0 -0
  358. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_budget.py +0 -0
  359. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_budget_flag.py +0 -0
  360. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_budget_phase2.py +0 -0
  361. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_bus_factor.py +0 -0
  362. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_capsule.py +0 -0
  363. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_cga.py +0 -0
  364. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_check_rules.py +0 -0
  365. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ci_gate_eval.py +0 -0
  366. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ci_sarif_guard.py +0 -0
  367. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ci_setup.py +0 -0
  368. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_clones.py +0 -0
  369. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_closure.py +0 -0
  370. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_codeowners.py +0 -0
  371. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_commands_architecture.py +0 -0
  372. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_commands_exploration.py +0 -0
  373. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_commands_health.py +0 -0
  374. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_commands_refactoring.py +0 -0
  375. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_commands_workflow.py +0 -0
  376. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_competitor_site_data.py +0 -0
  377. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_comprehensive.py +0 -0
  378. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_config.py +0 -0
  379. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_congestion.py +0 -0
  380. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_context_propagation.py +0 -0
  381. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_conventions_cmd.py +0 -0
  382. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_coverage_gaps_cmd.py +0 -0
  383. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_coverage_ingestion.py +0 -0
  384. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_critique.py +0 -0
  385. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_cut.py +0 -0
  386. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_dark_matter.py +0 -0
  387. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_dark_matter_helpers.py +0 -0
  388. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_dashboard.py +0 -0
  389. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_dataflow_dead.py +0 -0
  390. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_dead_aging.py +0 -0
  391. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_demo_gif_asset.py +0 -0
  392. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_describe.py +0 -0
  393. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_detail_flag_hints.py +0 -0
  394. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_deterministic_output.py +0 -0
  395. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_dev_profile.py +0 -0
  396. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_difficulty_scoring.py +0 -0
  397. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_doc_staleness.py +0 -0
  398. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_docker_assets.py +0 -0
  399. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_docs_coverage.py +0 -0
  400. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_docs_site_quality.py +0 -0
  401. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_doctor.py +0 -0
  402. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_drift.py +0 -0
  403. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_duplicates.py +0 -0
  404. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_effects.py +0 -0
  405. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_effects_propagation.py +0 -0
  406. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_endpoints.py +0 -0
  407. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_entry_points_cmd.py +0 -0
  408. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_exclude_patterns.py +0 -0
  409. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_exit_codes.py +0 -0
  410. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_file_roles.py +0 -0
  411. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_fingerprint.py +0 -0
  412. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_fixes.py +0 -0
  413. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_flag_dead.py +0 -0
  414. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_fleet.py +0 -0
  415. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_fn_coupling.py +0 -0
  416. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_forecast.py +0 -0
  417. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_formatters.py +0 -0
  418. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_foxpro.py +0 -0
  419. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_framework_detection.py +0 -0
  420. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_gate_presets.py +0 -0
  421. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_guard.py +0 -0
  422. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_health_gate.py +0 -0
  423. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_hooks.py +0 -0
  424. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_hotspots.py +0 -0
  425. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_index.py +0 -0
  426. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_init_cmd.py +0 -0
  427. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_install_check.py +0 -0
  428. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_intent.py +0 -0
  429. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_invariants.py +0 -0
  430. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_json_contracts.py +0 -0
  431. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_json_error_envelope.py +0 -0
  432. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_kotlin_swift_extractors.py +0 -0
  433. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_language_corpus.py +0 -0
  434. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_languages.py +0 -0
  435. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_library_api.py +0 -0
  436. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_math.py +0 -0
  437. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_math_tips.py +0 -0
  438. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_mcp_extras.py +0 -0
  439. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_mcp_setup.py +0 -0
  440. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_mermaid.py +0 -0
  441. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_metrics_cmd.py +0 -0
  442. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_migration_safety.py +0 -0
  443. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_minimap.py +0 -0
  444. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_missing_index.py +0 -0
  445. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_mutate.py +0 -0
  446. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_n1.py +0 -0
  447. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_next_steps.py +0 -0
  448. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_onboard.py +0 -0
  449. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_orchestrate.py +0 -0
  450. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_orphan_routes.py +0 -0
  451. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_oss_bench_harness.py +0 -0
  452. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_over_fetch.py +0 -0
  453. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_pagerank_truncation.py +0 -0
  454. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_partition.py +0 -0
  455. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_path_coverage.py +0 -0
  456. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_patterns_cmd.py +0 -0
  457. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_performance.py +0 -0
  458. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_personalized_pagerank.py +0 -0
  459. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_plan.py +0 -0
  460. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_plugin_discovery.py +0 -0
  461. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_pr_comment_script.py +0 -0
  462. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_pr_diff.py +0 -0
  463. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_pr_risk_author.py +0 -0
  464. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_progress.py +0 -0
  465. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_progressive_disclosure.py +0 -0
  466. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_properties.py +0 -0
  467. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_python_extractor_v2.py +0 -0
  468. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_refactoring_intelligence.py +0 -0
  469. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_relate.py +0 -0
  470. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_report.py +0 -0
  471. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_reset_clean.py +0 -0
  472. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_resolve.py +0 -0
  473. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_retrieve_seeds.py +0 -0
  474. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_risk.py +0 -0
  475. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ruby.py +0 -0
  476. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_rule_profiles.py +0 -0
  477. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_rules.py +0 -0
  478. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_rules_ast_match.py +0 -0
  479. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_rules_community_pack.py +0 -0
  480. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_rules_dataflow.py +0 -0
  481. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_rules_symbol_requirements.py +0 -0
  482. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_runtime.py +0 -0
  483. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_runtime_score.py +0 -0
  484. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_salesforce.py +0 -0
  485. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_sarif_flag.py +0 -0
  486. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_sbom.py +0 -0
  487. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_scala.py +0 -0
  488. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_schema_versioning.py +0 -0
  489. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_search_explain.py +0 -0
  490. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_secrets.py +0 -0
  491. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_secrets_v2.py +0 -0
  492. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_semantic_diff.py +0 -0
  493. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_semantic_onnx.py +0 -0
  494. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_semantic_search.py +0 -0
  495. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_simulate.py +0 -0
  496. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_simulate_departure.py +0 -0
  497. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_sketch.py +0 -0
  498. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_smells.py +0 -0
  499. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_smoke.py +0 -0
  500. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_sna_metrics.py +0 -0
  501. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_spectral.py +0 -0
  502. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_split_cmd.py +0 -0
  503. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_sql.py +0 -0
  504. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_suggest_reviewers.py +0 -0
  505. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_supply_chain.py +0 -0
  506. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_surface_counts.py +0 -0
  507. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_syntax_check.py +0 -0
  508. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_taint.py +0 -0
  509. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_taint_analysis.py +0 -0
  510. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_test_conventions.py +0 -0
  511. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_test_gaps.py +0 -0
  512. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_test_scaffold.py +0 -0
  513. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_testmap.py +0 -0
  514. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_top_flag_consistency.py +0 -0
  515. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_tour_cmd.py +0 -0
  516. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_trends.py +0 -0
  517. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_trends_cohort.py +0 -0
  518. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_triage.py +0 -0
  519. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_uses_cmd.py +0 -0
  520. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_v6_features.py +0 -0
  521. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_v71_features.py +0 -0
  522. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_v7_features.py +0 -0
  523. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_v82_features.py +0 -0
  524. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_verify.py +0 -0
  525. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_verify_imports.py +0 -0
  526. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_vibe_check.py +0 -0
  527. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_visualize.py +0 -0
  528. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_vuln.py +0 -0
  529. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_vulns_cmd.py +0 -0
  530. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_watch.py +0 -0
  531. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_why.py +0 -0
  532. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_workspace.py +0 -0
  533. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_ws_resolve_fixes.py +0 -0
  534. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_xlang.py +0 -0
  535. {roam_code-12.0.0 → roam_code-12.2.0}/tests/test_yaml_hcl.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: roam-code
3
- Version: 12.0.0
3
+ Version: 12.2.0
4
4
  Summary: Instant codebase comprehension for AI coding agents
5
5
  Author: CosmoHac
6
6
  License-Expression: MIT
@@ -37,6 +37,15 @@ Provides-Extra: semantic
37
37
  Requires-Dist: numpy>=1.24; extra == "semantic"
38
38
  Requires-Dist: onnxruntime>=1.16; extra == "semantic"
39
39
  Requires-Dist: tokenizers>=0.15; extra == "semantic"
40
+ Provides-Extra: leiden
41
+ Requires-Dist: igraph>=0.11; extra == "leiden"
42
+ Requires-Dist: leidenalg>=0.10; extra == "leiden"
43
+ Provides-Extra: graph-fast
44
+ Requires-Dist: rustworkx>=0.14; extra == "graph-fast"
45
+ Provides-Extra: sbom
46
+ Requires-Dist: cyclonedx-python-lib>=8.0; extra == "sbom"
47
+ Provides-Extra: learned
48
+ Requires-Dist: lightgbm>=4.0; extra == "learned"
40
49
  Provides-Extra: dev
41
50
  Requires-Dist: pytest>=7.0; extra == "dev"
42
51
  Requires-Dist: pytest-xdist>=3.0; extra == "dev"
@@ -51,7 +60,7 @@ Dynamic: license-file
51
60
 
52
61
  **The architectural intelligence layer for AI coding agents. Structural graph, architecture governance, multi-agent orchestration, vulnerability mapping, runtime analysis -- one CLI, zero API keys.**
53
62
 
54
- *147 commands · 106 MCP tools · 27 languages · 100% local*
63
+ *150 commands · 116 MCP tools · 27 languages · 100% local*
55
64
 
56
65
  [![PyPI version](https://img.shields.io/pypi/v/roam-code?style=flat-square&color=blue)](https://pypi.org/project/roam-code/)
57
66
  [![GitHub stars](https://img.shields.io/github/stars/Cranot/roam-code?style=flat-square)](https://github.com/Cranot/roam-code/stargazers)
@@ -113,14 +122,22 @@ $ roam diff # blast radius of uncommitted changes
113
122
 
114
123
  ## What's New in v12
115
124
 
116
- ### v12.0 (in progress) -- Retrieval substrate + patch verifier
125
+ ### v12.1 (in progress) -- Boolean oracles, IDOR classifier, index portability + Django bridge
126
+ - **`roam oracle <name>`**: 5 boolean oracles for agents — 1-token yes/no answers (`symbol-exists`, `route-exists`, `is-test-only`, `is-reachable-from-entry`, `is-clone-of`). Direct counter to CKB v9.2's `symbolExists` pattern. MCP tools: `roam_oracle_*`.
127
+ - **`roam_taint_classify` (MCP only)**: LLM-augmented taint classification — runs `roam taint` then asks the agent's own model (via MCP sampling) to label each reachable finding as IDOR/AUTHZ/SQLI/XSS/etc. with confidence + reasoning. Counter to Semgrep Multimodal — same LLM-reasoning narrative without a hosted API key. Sequential for v12.1; concurrency-bounded gather lands in v12.2.
128
+ - **`roam index-export` / `roam index-import`**: portable, integrity-checked tarball format with manifest sha256 round-trip + optional cosign signing. Counter to Cursor's "92% similar codebase = reuse teammate's index" without a vendor cloud. Tamper-evident (manifest verifies index.db sha256 on import).
129
+ - **`roam eval-retrieve --emit-format coderag|beir`**: bench-portable JSONL emit for public leaderboard submission. CodeRAG-Bench-compatible `ctxs` array + BEIR-style trec_eval run files.
130
+ - **Django bridge**: full implicit-relationship resolution (admin→model, serializer→model, FK transitive, signal handlers, URL configs, Celery tasks, DRF routers). Ported from `@LukasBerka/roam-code` — credit Lukas Berka. New schema columns: `framework_type`, `field_type`, `field_metadata`. Post-resolver runs after graph metrics.
131
+ - **`worktree_git_env()`** (`git_utils.py`): `GIT_INDEX_FILE` override fixes `.git/index.lock` contention when parallel agents run roam in sibling worktrees. Wired into `discovery.py`, `git_stats.py`, `changed_files.py`. Ported from `@river-mounts/roam-code-sf` — credit Sam Hannan.
132
+
133
+ ### v12.0 (released 2026-05-01) -- Retrieval substrate + patch verifier
117
134
  - **`roam retrieve "<task>"`**: graph-aware context server. Hybrid first stage (FTS5) + structural reranker (personalised PageRank + clone-canonical signal + lexical baseline) + token-budget cap. Returns ranked spans with justification tags (`pagerank=...`, `clone_cluster=...`, `fts=...`) so callers can see *why* each span ranked. MCP tool: `roam_retrieve(task, budget, k, rerank, seed_files)`.
118
135
  - **`roam critique`**: graph-grounded patch verifier. Pipe `git diff | roam critique` to get findings ranked by severity. The killer signal is **clones-not-edited**: for every changed symbol with persisted clone siblings outside the diff, we flag the sibling as a likely missed change. Plus a blast-radius caller-count finding. Exits 5 on high severity (CI-gateable). MCP tool: `roam_critique(diff_text)`.
119
136
  - **`roam clones --persist`**: populate the `clone_pairs` and `clone_clusters` tables so downstream consumers (critique, retrieve) can query clones in O(1) instead of re-running detection.
120
137
  - **`personalized_pagerank()`** in `graph/pagerank.py`: NetworkX `personalization=` wrapper with empty-seed fallback to global PR; biases ranking toward query-relevant nodes for the retrieve reranker.
121
138
  - **`.roam/config.toml`** (new): zero-dep TOML loader (stdlib `tomllib` → `tomli` → in-tree subset parser). Tunable retrieve weights (`alpha`/`beta`/`gamma`/`delta`/`epsilon`), `tokens_per_line`, `lexical_baseline`, `first_stage_token_cap`, `default_budget`, `default_k`, `default_rerank`.
122
139
  - **DX corrections from dogfood pass**: `roam --detail <cmd>` is the canonical group-level flag; misleading "use --detail" hints in 7 commands rewritten to point users at `roam --detail <cmd>`. `--top N` aliased on `complexity`/`algo`/`rules` (`--top 0` means unlimited on `rules`). `roam fingerprint` no longer refuses graphs ≥5,000 symbols (new soft-warn threshold 20k, hard cap 100k).
123
- - **147 CLI commands, 106 MCP tools** (`fleet`, `ask`, `taint`, `cga`, `eval-retrieve` are CLI-only in v12.0; `roam_retrieve`, `roam_critique`, and `roam_fleet_plan` are exposed as MCP tools alongside the existing 103-tool surface). 27-tool `core` preset is the default for token-budget-conscious clients.
140
+ - **150 CLI commands, 116 MCP tools** (`fleet`, `ask`, `taint`, `cga`, `eval-retrieve` remain CLI-only; v12 exposes `roam_retrieve`, `roam_critique`, `roam_fleet_plan`, plus 5 v12.1 boolean oracles (`roam_oracle_*`) and `roam_taint_classify` as MCP tools). 33-tool `core` preset is the default for token-budget-conscious clients.
124
141
 
125
142
  ## What's New in v11
126
143
 
@@ -136,7 +153,7 @@ $ roam diff # blast radius of uncommitted changes
136
153
  - `server.json` for official MCP Registry submission.
137
154
 
138
155
  ### v11.1.1 -- Command Quality Audit
139
- - **Full command audit**: all 147 commands reviewed for usefulness, duplicates, and test coverage. ~20 bugs fixed, 21 new test files (700+ tests), every command docstring updated with cross-references to related commands.
156
+ - **Full command audit**: all 150 commands reviewed for usefulness, duplicates, and test coverage. ~20 bugs fixed, 21 new test files (700+ tests), every command docstring updated with cross-references to related commands.
140
157
  - **Kotlin promoted to Tier 1** via new YAML-based declarative extractor architecture. Classes, interfaces, enums, objects, functions, methods, properties, and inheritance fully extracted.
141
158
  - **7 new commands**: `roam congestion`, `roam adrs`, `roam flag-dead`, `roam test-scaffold`, `roam sbom`, `roam triage`, `roam ci-setup`.
142
159
  - **CI templates**: `roam ci-setup` generates pipelines for GitHub Actions, GitLab CI, Azure Pipelines, Jenkins, and Bitbucket.
@@ -151,7 +168,7 @@ $ roam diff # blast radius of uncommitted changes
151
168
  - MCP token overhead for default core context dropped from ~36K to <3K tokens (about 92% reduction).
152
169
 
153
170
  ### Performance and Retrieval
154
- - Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to milliseconds (about 1000x on benchmarked paths).
171
+ - Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to tens of milliseconds on the indexed cohort (mileage varies by repo size and query selectivity — see `bench/retrieve/` for the methodology).
155
172
  - Incremental indexing shifted from O(N) full-edge rebuild behavior to O(changed) updates.
156
173
  - DB/runtime optimizations (`mmap_size`, safer large-graph guards, batched writes) reduce first-run and reindex friction on larger repos.
157
174
 
@@ -291,7 +308,7 @@ roam health
291
308
 
292
309
  ## Commands
293
310
 
294
- The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. All 147 commands are organized into 7 categories.
311
+ **Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 145 commands are detail surface for specialised workflows (taint, fleet, cga, oracle, eval, …) — they're called by agents on demand, not memorised. This is intentional design; under the hood the canonical surface is **150 commands organised into 7 categories**, but you don't need to know that to start.
295
312
 
296
313
  <details>
297
314
  <summary><strong>Full command reference</strong></summary>
@@ -301,6 +318,8 @@ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows.
301
318
  | Command | Description |
302
319
  |---------|-------------|
303
320
  | `roam index [--force] [--verbose]` | Build or rebuild the codebase index |
321
+ | `roam index-export <bundle.tar.gz> [--sign] [--key K] [--keyless]` | Export the indexed `.roam/index.db` as a signed, integrity-checked tarball. Counter to Cursor's "reuse teammate's index" without a vendor cloud. |
322
+ | `roam index-import <bundle.tar.gz> [--force] [--cosign-bundle B] [--cosign-key K]` | Import a portable index bundle. Verifies manifest sha256 + optional cosign signature; refuses to overwrite without `--force`. |
304
323
  | `roam watch [--interval N] [--debounce N] [--webhook-port P] [--guardian]` | Long-running index daemon: poll/webhook-triggered refreshes plus optional continuous architecture-guardian snapshots and JSONL compliance artifacts |
305
324
  | `roam init` | Guided onboarding: creates `.roam/fitness.yaml`, CI workflow, runs index, shows health |
306
325
  | `roam hooks [--install] [--uninstall]` | Manage git hooks for automated roam index updates and health gates |
@@ -334,7 +353,8 @@ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows.
334
353
  | `roam ask <query> [--list] [--explain] [--recipe NAME]` | One-phrase intent classifier over a 12-recipe registry — composes preflight/retrieve/critique/fleet/understand/diagnose/trace/trends/hotspots/debt/taint/dead/coupling to cover the most common workflows. |
335
354
  | `roam taint [--rules-dir PATH] [--rule NAME] [--ci]` | Graph-reach taint analysis with OpenVEX-correct VEX justifications. YAML rule packs (5 starter rules: Python command-injection / SQLi / path-traversal, JS XSS / SSRF). |
336
355
  | `roam cga emit [--include-taint] [--sign --key]` | Code Graph Attestation — in-toto v1 statement with `roam-code.dev/CodeGraph/v1` predicate, Merkle root + edge bundle digest. `--include-taint` embeds OpenVEX-shaped reachability claims from `roam taint`. `--sign` signs with cosign (graceful skip if absent); `roam cga verify` round-trips both predicate digest and cosign signature. |
337
- | `roam eval-retrieve [--tasks FILE] [--sweep] [--min-recall-at-20 N]` | Recall@K eval harness for `roam retrieve` — measures against a JSONL ground-truth file. CI-gateable. Baseline on this repo: recall@20 = 0.43 across 10 hand-crafted tasks. |
356
+ | `roam eval-retrieve [--tasks FILE] [--sweep] [--min-recall-at-20 N] [--emit-format coderag\|beir]` | Recall@K eval harness for `roam retrieve` — measures against a JSONL ground-truth file. CI-gateable. `--emit-format coderag` writes CodeRAG-Bench-compatible run files for public leaderboard submission. |
357
+ | `roam oracle <name> <subject>` | Boolean oracles for agents — 1-token yes/no answers. Subcommands: `symbol-exists`, `route-exists`, `is-test-only`, `is-reachable-from-entry`, `is-clone-of`. |
338
358
  | `roam search <pattern> [--kind KIND]` | Find symbols by name pattern, PageRank-ranked |
339
359
  | `roam grep <pattern> [-g glob] [-n N]` | Text search annotated with enclosing symbol context |
340
360
  | `roam deps <path> [--full]` | What a file imports and what imports it |
@@ -926,7 +946,7 @@ ROAM_MCP_LITE=0 roam mcp
926
946
  Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`, `roam_complete`, `roam_complexity_report`, `roam_context`, `roam_dead_code`, `roam_deps`, `roam_diagnose`, `roam_diagnose_issue`, `roam_diff`, `roam_expand_toolset`, `roam_explore`, `roam_file_info`, `roam_health`, `roam_impact`, `roam_pr_risk`, `roam_preflight`, `roam_prepare_change`, `roam_review_change`, `roam_search_symbol`, `roam_syntax_check`, `roam_trace`, `roam_understand`, `roam_uses`.
927
947
 
928
948
  <details>
929
- <summary><strong>MCP tool list (all 106)</strong></summary>
949
+ <summary><strong>MCP tool list (all 116)</strong></summary>
930
950
 
931
951
  | Tool | Description |
932
952
  |------|-------------|
@@ -940,6 +960,16 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
940
960
  | `roam_retrieve` | Graph-aware context for free-form tasks (FTS5 + structural rerank + token budget) |
941
961
  | `roam_critique` | Verify a patch against the graph (clones-not-edited + blast radius) |
942
962
  | `roam_fleet_plan` | Plan a multi-agent fleet — graph-aware partition emits .roam-fleet.json |
963
+ | `roam_oracle_symbol_exists` | Boolean oracle: does any symbol with this name exist? |
964
+ | `roam_oracle_route_exists` | Boolean oracle: does any HTTP route handler match this URL path? |
965
+ | `roam_oracle_is_test_only` | Boolean oracle: are ALL callers of this symbol in test files? |
966
+ | `roam_oracle_is_reachable_from_entry` | Boolean oracle: can BFS reach this symbol from any entry-point? |
967
+ | `roam_oracle_is_clone_of` | Boolean oracle: does this symbol participate in a persisted clone cluster? |
968
+ | `roam_taint_classify` | LLM-augmented taint classification (IDOR/AUTHZ/SQLI/...) via MCP sampling |
969
+ | `roam_taint` | Static taint analysis — graph-reach BFS with OpenVEX-correct findings |
970
+ | `roam_sbom` | CycloneDX 1.7 / SPDX 2.3 SBOM emit with optional AIBOM extension (EU AI Act) |
971
+ | `roam_cga_emit` | Emit a Code Graph Attestation (in-toto v1) with optional cosign signing |
972
+ | `roam_cga_verify` | Verify a CGA statement — re-derives Merkle + edge digest, checks cosign signature |
943
973
  | `roam_trace` | Dependency path between two symbols |
944
974
  | `roam_impact` | Blast radius of changing a symbol |
945
975
  | `roam_file_info` | File skeleton with all definitions |
@@ -1550,8 +1580,8 @@ roam-code/
1550
1580
  ├── action.yml # Reusable GitHub Action
1551
1581
  ├── src/roam/
1552
1582
  │ ├── __init__.py # Version (from pyproject.toml)
1553
- │ ├── cli.py # Click CLI (147 commands)
1554
- │ ├── mcp_server.py # MCP server (106 tools, 10 resources, 5 prompts)
1583
+ │ ├── cli.py # Click CLI (150 commands)
1584
+ │ ├── mcp_server.py # MCP server (116 tools, 10 resources, 5 prompts)
1555
1585
  │ ├── db/
1556
1586
  │ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
1557
1587
  │ │ ├── schema.py # Tables, indexes, migrations
@@ -1645,7 +1675,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
1645
1675
  ### Shipped
1646
1676
 
1647
1677
  - [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
1648
- - [x] Full command and MCP inventory parity in docs: 147 CLI commands and 106 MCP tools.
1678
+ - [x] Full command and MCP inventory parity in docs: 150 CLI commands and 116 MCP tools.
1649
1679
  - [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
1650
1680
  - [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
1651
1681
  - [x] Agent governance suite: `vibe-check`, `ai-readiness`, `verify`, `ai-ratio`, `duplicates`, advanced `algo` scoring/SARIF.
@@ -4,7 +4,7 @@
4
4
 
5
5
  **The architectural intelligence layer for AI coding agents. Structural graph, architecture governance, multi-agent orchestration, vulnerability mapping, runtime analysis -- one CLI, zero API keys.**
6
6
 
7
- *147 commands · 106 MCP tools · 27 languages · 100% local*
7
+ *150 commands · 116 MCP tools · 27 languages · 100% local*
8
8
 
9
9
  [![PyPI version](https://img.shields.io/pypi/v/roam-code?style=flat-square&color=blue)](https://pypi.org/project/roam-code/)
10
10
  [![GitHub stars](https://img.shields.io/github/stars/Cranot/roam-code?style=flat-square)](https://github.com/Cranot/roam-code/stargazers)
@@ -66,14 +66,22 @@ $ roam diff # blast radius of uncommitted changes
66
66
 
67
67
  ## What's New in v12
68
68
 
69
- ### v12.0 (in progress) -- Retrieval substrate + patch verifier
69
+ ### v12.1 (in progress) -- Boolean oracles, IDOR classifier, index portability + Django bridge
70
+ - **`roam oracle <name>`**: 5 boolean oracles for agents — 1-token yes/no answers (`symbol-exists`, `route-exists`, `is-test-only`, `is-reachable-from-entry`, `is-clone-of`). Direct counter to CKB v9.2's `symbolExists` pattern. MCP tools: `roam_oracle_*`.
71
+ - **`roam_taint_classify` (MCP only)**: LLM-augmented taint classification — runs `roam taint` then asks the agent's own model (via MCP sampling) to label each reachable finding as IDOR/AUTHZ/SQLI/XSS/etc. with confidence + reasoning. Counter to Semgrep Multimodal — same LLM-reasoning narrative without a hosted API key. Sequential for v12.1; concurrency-bounded gather lands in v12.2.
72
+ - **`roam index-export` / `roam index-import`**: portable, integrity-checked tarball format with manifest sha256 round-trip + optional cosign signing. Counter to Cursor's "92% similar codebase = reuse teammate's index" without a vendor cloud. Tamper-evident (manifest verifies index.db sha256 on import).
73
+ - **`roam eval-retrieve --emit-format coderag|beir`**: bench-portable JSONL emit for public leaderboard submission. CodeRAG-Bench-compatible `ctxs` array + BEIR-style trec_eval run files.
74
+ - **Django bridge**: full implicit-relationship resolution (admin→model, serializer→model, FK transitive, signal handlers, URL configs, Celery tasks, DRF routers). Ported from `@LukasBerka/roam-code` — credit Lukas Berka. New schema columns: `framework_type`, `field_type`, `field_metadata`. Post-resolver runs after graph metrics.
75
+ - **`worktree_git_env()`** (`git_utils.py`): `GIT_INDEX_FILE` override fixes `.git/index.lock` contention when parallel agents run roam in sibling worktrees. Wired into `discovery.py`, `git_stats.py`, `changed_files.py`. Ported from `@river-mounts/roam-code-sf` — credit Sam Hannan.
76
+
77
+ ### v12.0 (released 2026-05-01) -- Retrieval substrate + patch verifier
70
78
  - **`roam retrieve "<task>"`**: graph-aware context server. Hybrid first stage (FTS5) + structural reranker (personalised PageRank + clone-canonical signal + lexical baseline) + token-budget cap. Returns ranked spans with justification tags (`pagerank=...`, `clone_cluster=...`, `fts=...`) so callers can see *why* each span ranked. MCP tool: `roam_retrieve(task, budget, k, rerank, seed_files)`.
71
79
  - **`roam critique`**: graph-grounded patch verifier. Pipe `git diff | roam critique` to get findings ranked by severity. The killer signal is **clones-not-edited**: for every changed symbol with persisted clone siblings outside the diff, we flag the sibling as a likely missed change. Plus a blast-radius caller-count finding. Exits 5 on high severity (CI-gateable). MCP tool: `roam_critique(diff_text)`.
72
80
  - **`roam clones --persist`**: populate the `clone_pairs` and `clone_clusters` tables so downstream consumers (critique, retrieve) can query clones in O(1) instead of re-running detection.
73
81
  - **`personalized_pagerank()`** in `graph/pagerank.py`: NetworkX `personalization=` wrapper with empty-seed fallback to global PR; biases ranking toward query-relevant nodes for the retrieve reranker.
74
82
  - **`.roam/config.toml`** (new): zero-dep TOML loader (stdlib `tomllib` → `tomli` → in-tree subset parser). Tunable retrieve weights (`alpha`/`beta`/`gamma`/`delta`/`epsilon`), `tokens_per_line`, `lexical_baseline`, `first_stage_token_cap`, `default_budget`, `default_k`, `default_rerank`.
75
83
  - **DX corrections from dogfood pass**: `roam --detail <cmd>` is the canonical group-level flag; misleading "use --detail" hints in 7 commands rewritten to point users at `roam --detail <cmd>`. `--top N` aliased on `complexity`/`algo`/`rules` (`--top 0` means unlimited on `rules`). `roam fingerprint` no longer refuses graphs ≥5,000 symbols (new soft-warn threshold 20k, hard cap 100k).
76
- - **147 CLI commands, 106 MCP tools** (`fleet`, `ask`, `taint`, `cga`, `eval-retrieve` are CLI-only in v12.0; `roam_retrieve`, `roam_critique`, and `roam_fleet_plan` are exposed as MCP tools alongside the existing 103-tool surface). 27-tool `core` preset is the default for token-budget-conscious clients.
84
+ - **150 CLI commands, 116 MCP tools** (`fleet`, `ask`, `taint`, `cga`, `eval-retrieve` remain CLI-only; v12 exposes `roam_retrieve`, `roam_critique`, `roam_fleet_plan`, plus 5 v12.1 boolean oracles (`roam_oracle_*`) and `roam_taint_classify` as MCP tools). 33-tool `core` preset is the default for token-budget-conscious clients.
77
85
 
78
86
  ## What's New in v11
79
87
 
@@ -89,7 +97,7 @@ $ roam diff # blast radius of uncommitted changes
89
97
  - `server.json` for official MCP Registry submission.
90
98
 
91
99
  ### v11.1.1 -- Command Quality Audit
92
- - **Full command audit**: all 147 commands reviewed for usefulness, duplicates, and test coverage. ~20 bugs fixed, 21 new test files (700+ tests), every command docstring updated with cross-references to related commands.
100
+ - **Full command audit**: all 150 commands reviewed for usefulness, duplicates, and test coverage. ~20 bugs fixed, 21 new test files (700+ tests), every command docstring updated with cross-references to related commands.
93
101
  - **Kotlin promoted to Tier 1** via new YAML-based declarative extractor architecture. Classes, interfaces, enums, objects, functions, methods, properties, and inheritance fully extracted.
94
102
  - **7 new commands**: `roam congestion`, `roam adrs`, `roam flag-dead`, `roam test-scaffold`, `roam sbom`, `roam triage`, `roam ci-setup`.
95
103
  - **CI templates**: `roam ci-setup` generates pipelines for GitHub Actions, GitLab CI, Azure Pipelines, Jenkins, and Bitbucket.
@@ -104,7 +112,7 @@ $ roam diff # blast radius of uncommitted changes
104
112
  - MCP token overhead for default core context dropped from ~36K to <3K tokens (about 92% reduction).
105
113
 
106
114
  ### Performance and Retrieval
107
- - Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to milliseconds (about 1000x on benchmarked paths).
115
+ - Symbol search moved to SQLite FTS5/BM25: typical search moved from seconds to tens of milliseconds on the indexed cohort (mileage varies by repo size and query selectivity — see `bench/retrieve/` for the methodology).
108
116
  - Incremental indexing shifted from O(N) full-edge rebuild behavior to O(changed) updates.
109
117
  - DB/runtime optimizations (`mmap_size`, safer large-graph guards, batched writes) reduce first-run and reindex friction on larger repos.
110
118
 
@@ -244,7 +252,7 @@ roam health
244
252
 
245
253
  ## Commands
246
254
 
247
- The [5 core commands](#core-commands) shown above cover ~80% of agent workflows. All 147 commands are organized into 7 categories.
255
+ **Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 145 commands are detail surface for specialised workflows (taint, fleet, cga, oracle, eval, …) — they're called by agents on demand, not memorised. This is intentional design; under the hood the canonical surface is **150 commands organised into 7 categories**, but you don't need to know that to start.
248
256
 
249
257
  <details>
250
258
  <summary><strong>Full command reference</strong></summary>
@@ -254,6 +262,8 @@ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows.
254
262
  | Command | Description |
255
263
  |---------|-------------|
256
264
  | `roam index [--force] [--verbose]` | Build or rebuild the codebase index |
265
+ | `roam index-export <bundle.tar.gz> [--sign] [--key K] [--keyless]` | Export the indexed `.roam/index.db` as a signed, integrity-checked tarball. Counter to Cursor's "reuse teammate's index" without a vendor cloud. |
266
+ | `roam index-import <bundle.tar.gz> [--force] [--cosign-bundle B] [--cosign-key K]` | Import a portable index bundle. Verifies manifest sha256 + optional cosign signature; refuses to overwrite without `--force`. |
257
267
  | `roam watch [--interval N] [--debounce N] [--webhook-port P] [--guardian]` | Long-running index daemon: poll/webhook-triggered refreshes plus optional continuous architecture-guardian snapshots and JSONL compliance artifacts |
258
268
  | `roam init` | Guided onboarding: creates `.roam/fitness.yaml`, CI workflow, runs index, shows health |
259
269
  | `roam hooks [--install] [--uninstall]` | Manage git hooks for automated roam index updates and health gates |
@@ -287,7 +297,8 @@ The [5 core commands](#core-commands) shown above cover ~80% of agent workflows.
287
297
  | `roam ask <query> [--list] [--explain] [--recipe NAME]` | One-phrase intent classifier over a 12-recipe registry — composes preflight/retrieve/critique/fleet/understand/diagnose/trace/trends/hotspots/debt/taint/dead/coupling to cover the most common workflows. |
288
298
  | `roam taint [--rules-dir PATH] [--rule NAME] [--ci]` | Graph-reach taint analysis with OpenVEX-correct VEX justifications. YAML rule packs (5 starter rules: Python command-injection / SQLi / path-traversal, JS XSS / SSRF). |
289
299
  | `roam cga emit [--include-taint] [--sign --key]` | Code Graph Attestation — in-toto v1 statement with `roam-code.dev/CodeGraph/v1` predicate, Merkle root + edge bundle digest. `--include-taint` embeds OpenVEX-shaped reachability claims from `roam taint`. `--sign` signs with cosign (graceful skip if absent); `roam cga verify` round-trips both predicate digest and cosign signature. |
290
- | `roam eval-retrieve [--tasks FILE] [--sweep] [--min-recall-at-20 N]` | Recall@K eval harness for `roam retrieve` — measures against a JSONL ground-truth file. CI-gateable. Baseline on this repo: recall@20 = 0.43 across 10 hand-crafted tasks. |
300
+ | `roam eval-retrieve [--tasks FILE] [--sweep] [--min-recall-at-20 N] [--emit-format coderag\|beir]` | Recall@K eval harness for `roam retrieve` — measures against a JSONL ground-truth file. CI-gateable. `--emit-format coderag` writes CodeRAG-Bench-compatible run files for public leaderboard submission. |
301
+ | `roam oracle <name> <subject>` | Boolean oracles for agents — 1-token yes/no answers. Subcommands: `symbol-exists`, `route-exists`, `is-test-only`, `is-reachable-from-entry`, `is-clone-of`. |
291
302
  | `roam search <pattern> [--kind KIND]` | Find symbols by name pattern, PageRank-ranked |
292
303
  | `roam grep <pattern> [-g glob] [-n N]` | Text search annotated with enclosing symbol context |
293
304
  | `roam deps <path> [--full]` | What a file imports and what imports it |
@@ -879,7 +890,7 @@ ROAM_MCP_LITE=0 roam mcp
879
890
  Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`, `roam_complete`, `roam_complexity_report`, `roam_context`, `roam_dead_code`, `roam_deps`, `roam_diagnose`, `roam_diagnose_issue`, `roam_diff`, `roam_expand_toolset`, `roam_explore`, `roam_file_info`, `roam_health`, `roam_impact`, `roam_pr_risk`, `roam_preflight`, `roam_prepare_change`, `roam_review_change`, `roam_search_symbol`, `roam_syntax_check`, `roam_trace`, `roam_understand`, `roam_uses`.
880
891
 
881
892
  <details>
882
- <summary><strong>MCP tool list (all 106)</strong></summary>
893
+ <summary><strong>MCP tool list (all 116)</strong></summary>
883
894
 
884
895
  | Tool | Description |
885
896
  |------|-------------|
@@ -893,6 +904,16 @@ Core preset tools: `roam_affected_tests`, `roam_batch_get`, `roam_batch_search`,
893
904
  | `roam_retrieve` | Graph-aware context for free-form tasks (FTS5 + structural rerank + token budget) |
894
905
  | `roam_critique` | Verify a patch against the graph (clones-not-edited + blast radius) |
895
906
  | `roam_fleet_plan` | Plan a multi-agent fleet — graph-aware partition emits .roam-fleet.json |
907
+ | `roam_oracle_symbol_exists` | Boolean oracle: does any symbol with this name exist? |
908
+ | `roam_oracle_route_exists` | Boolean oracle: does any HTTP route handler match this URL path? |
909
+ | `roam_oracle_is_test_only` | Boolean oracle: are ALL callers of this symbol in test files? |
910
+ | `roam_oracle_is_reachable_from_entry` | Boolean oracle: can BFS reach this symbol from any entry-point? |
911
+ | `roam_oracle_is_clone_of` | Boolean oracle: does this symbol participate in a persisted clone cluster? |
912
+ | `roam_taint_classify` | LLM-augmented taint classification (IDOR/AUTHZ/SQLI/...) via MCP sampling |
913
+ | `roam_taint` | Static taint analysis — graph-reach BFS with OpenVEX-correct findings |
914
+ | `roam_sbom` | CycloneDX 1.7 / SPDX 2.3 SBOM emit with optional AIBOM extension (EU AI Act) |
915
+ | `roam_cga_emit` | Emit a Code Graph Attestation (in-toto v1) with optional cosign signing |
916
+ | `roam_cga_verify` | Verify a CGA statement — re-derives Merkle + edge digest, checks cosign signature |
896
917
  | `roam_trace` | Dependency path between two symbols |
897
918
  | `roam_impact` | Blast radius of changing a symbol |
898
919
  | `roam_file_info` | File skeleton with all definitions |
@@ -1503,8 +1524,8 @@ roam-code/
1503
1524
  ├── action.yml # Reusable GitHub Action
1504
1525
  ├── src/roam/
1505
1526
  │ ├── __init__.py # Version (from pyproject.toml)
1506
- │ ├── cli.py # Click CLI (147 commands)
1507
- │ ├── mcp_server.py # MCP server (106 tools, 10 resources, 5 prompts)
1527
+ │ ├── cli.py # Click CLI (150 commands)
1528
+ │ ├── mcp_server.py # MCP server (116 tools, 10 resources, 5 prompts)
1508
1529
  │ ├── db/
1509
1530
  │ │ ├── connection.py # SQLite (WAL, pragmas, batched IN)
1510
1531
  │ │ ├── schema.py # Tables, indexes, migrations
@@ -1598,7 +1619,7 @@ Optional: Local semantic ONNX stack (`numpy`, `onnxruntime`, `tokenizers`) via `
1598
1619
  ### Shipped
1599
1620
 
1600
1621
  - [x] MCP v2 agent surface: in-process execution, compound operations, presets, schemas, annotations, and compatibility profiles.
1601
- - [x] Full command and MCP inventory parity in docs: 147 CLI commands and 106 MCP tools.
1622
+ - [x] Full command and MCP inventory parity in docs: 150 CLI commands and 116 MCP tools.
1602
1623
  - [x] CI hardening: composite action, changed-only mode, trend-aware gates, sticky PR updater, and SARIF guardrails.
1603
1624
  - [x] Performance foundation: FTS5/BM25 search, O(changed) incremental indexing, DB/index optimizations.
1604
1625
  - [x] Agent governance suite: `vibe-check`, `ai-readiness`, `verify`, `ai-ratio`, `duplicates`, advanced `algo` scoring/SARIF.
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "roam-code"
7
- version = "12.0.0"
7
+ version = "12.2.0"
8
8
  description = "Instant codebase comprehension for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -55,6 +55,29 @@ semantic = [
55
55
  "onnxruntime>=1.16",
56
56
  "tokenizers>=0.15",
57
57
  ]
58
+ leiden = [
59
+ # Strictly better community detection than Louvain (no badly-connected
60
+ # communities). Auto-detected at runtime; falls back to seeded Louvain
61
+ # when these aren't installed.
62
+ "igraph>=0.11",
63
+ "leidenalg>=0.10",
64
+ ]
65
+ graph-fast = [
66
+ # rustworkx is a Rust-backed drop-in for many NetworkX algorithms;
67
+ # 3-100× speedup at >250k nodes per the v12.2 architecture review.
68
+ # Auto-detected via ``ROAM_GRAPH_BACKEND=rustworkx``.
69
+ "rustworkx>=0.14",
70
+ ]
71
+ sbom = [
72
+ # CycloneDX 1.7 SBOM emit (with AIBOM extension) for `roam sbom`.
73
+ # Falls back to in-tree minimal emitter when not installed.
74
+ "cyclonedx-python-lib>=8.0",
75
+ ]
76
+ learned = [
77
+ # LightGBM LambdaMART distillation for `roam retrieve --rerank learned`.
78
+ # Optional — current `--rerank fast` blend stays the default.
79
+ "lightgbm>=4.0",
80
+ ]
58
81
  dev = [
59
82
  "pytest>=7.0",
60
83
  "pytest-xdist>=3.0",
@@ -31,6 +31,11 @@ from typing import Any
31
31
  from roam.security.taint_engine import OPENVEX_JUSTIFICATIONS, OPENVEX_STATUSES
32
32
 
33
33
  PREDICATE_TYPE = "https://roam-code.dev/CodeGraph/v1"
34
+ # v12.2: fused CodeGraph + AIBOM predicate. Owns the "structurally bound
35
+ # AI authorship for tamper-evident codebases" lane that SLSA + SPDX +
36
+ # CycloneDX 1.7 + OpenVEX leave gapped. Reference impl candidate for
37
+ # the in-toto attestation registry.
38
+ PREDICATE_TYPE_AIBOM = "https://roam-code.dev/CodeGraph-AIBOM/v1"
34
39
  STATEMENT_TYPE = "https://in-toto.io/Statement/v1"
35
40
  SCHEMA_VERSION = "1"
36
41
 
@@ -218,6 +223,7 @@ def build_cga_statement(
218
223
  project_root: Path,
219
224
  tool_version: str | None = None,
220
225
  taint_findings: list | None = None,
226
+ include_aibom: bool = False,
221
227
  ) -> dict[str, Any]:
222
228
  """Build the full in-toto v1 Statement wrapping the CGA predicate.
223
229
 
@@ -225,9 +231,15 @@ def build_cga_statement(
225
231
  {
226
232
  "_type": "https://in-toto.io/Statement/v1",
227
233
  "predicateType": "https://roam-code.dev/CodeGraph/v1",
234
+ # → CodeGraph-AIBOM/v1 when include_aibom=True
228
235
  "subject": [{"name": "...", "digest": {...}}],
229
236
  "predicate": {...}
230
237
  }
238
+
239
+ With ``include_aibom=True``, the predicate type promotes to
240
+ ``CodeGraph-AIBOM/v1`` and embeds an ``aibom`` block binding
241
+ AI-authored commits to the indexed symbols they touched. Required
242
+ for EU AI Act Art. 50 disclosure (effective 2026-08-02).
231
243
  """
232
244
  sha = _git_commit_sha(project_root) or "unknown"
233
245
  remote = _git_remote_url(project_root)
@@ -236,16 +248,26 @@ def build_cga_statement(
236
248
  "name": subject_name,
237
249
  "digest": {"git_commit_sha1": sha},
238
250
  }
251
+ predicate = build_cga_predicate(
252
+ conn,
253
+ project_root=project_root,
254
+ tool_version=tool_version,
255
+ taint_findings=taint_findings,
256
+ )
257
+ predicate_type = PREDICATE_TYPE
258
+ if include_aibom:
259
+ try:
260
+ from roam.security.aibom_extension import build_aibom_block
261
+
262
+ predicate["aibom"] = build_aibom_block(project_root, conn)
263
+ predicate_type = PREDICATE_TYPE_AIBOM
264
+ except Exception as exc:
265
+ predicate["aibom_error"] = str(exc)
239
266
  return {
240
267
  "_type": STATEMENT_TYPE,
241
- "predicateType": PREDICATE_TYPE,
268
+ "predicateType": predicate_type,
242
269
  "subject": [subject],
243
- "predicate": build_cga_predicate(
244
- conn,
245
- project_root=project_root,
246
- tool_version=tool_version,
247
- taint_findings=taint_findings,
248
- ),
270
+ "predicate": predicate,
249
271
  }
250
272
 
251
273
 
@@ -270,8 +292,11 @@ def verify_cga_statement(
270
292
  errors: list[str] = []
271
293
  if statement.get("_type") != STATEMENT_TYPE:
272
294
  errors.append(f"_type mismatch: got {statement.get('_type')!r}, expected {STATEMENT_TYPE!r}")
273
- if statement.get("predicateType") != PREDICATE_TYPE:
274
- errors.append(f"predicateType mismatch: got {statement.get('predicateType')!r}, expected {PREDICATE_TYPE!r}")
295
+ accepted_types = (PREDICATE_TYPE, PREDICATE_TYPE_AIBOM)
296
+ if statement.get("predicateType") not in accepted_types:
297
+ errors.append(
298
+ f"predicateType mismatch: got {statement.get('predicateType')!r}, expected one of {accepted_types!r}"
299
+ )
275
300
  predicate = statement.get("predicate") or {}
276
301
  if not isinstance(predicate, dict):
277
302
  return False, errors + ["predicate is not a JSON object"]