roam-code 12.38__tar.gz → 12.40__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 (659) hide show
  1. {roam_code-12.38 → roam_code-12.40}/PKG-INFO +4 -4
  2. {roam_code-12.38 → roam_code-12.40}/README.md +3 -3
  3. {roam_code-12.38 → roam_code-12.40}/pyproject.toml +1 -1
  4. {roam_code-12.38 → roam_code-12.40}/src/roam/cli.py +6 -0
  5. roam_code-12.40/src/roam/commands/cmd_article_12_check.py +381 -0
  6. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_check_rules.py +2 -2
  7. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_coverage_gaps.py +1 -1
  8. roam_code-12.40/src/roam/commands/cmd_permit.py +283 -0
  9. roam_code-12.40/src/roam/commands/cmd_postmortem.py +270 -0
  10. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_report.py +1 -1
  11. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_trends.py +1 -1
  12. {roam_code-12.38 → roam_code-12.40}/src/roam/competitor_site_data.py +2 -2
  13. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp-server-card.json +1 -1
  14. {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/PKG-INFO +4 -4
  15. {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/SOURCES.txt +4 -0
  16. roam_code-12.40/tests/test_pivot_phase0_commands.py +134 -0
  17. {roam_code-12.38 → roam_code-12.40}/LICENSE +0 -0
  18. {roam_code-12.38 → roam_code-12.40}/setup.cfg +0 -0
  19. {roam_code-12.38 → roam_code-12.40}/src/roam/__init__.py +0 -0
  20. {roam_code-12.38 → roam_code-12.40}/src/roam/__main__.py +0 -0
  21. {roam_code-12.38 → roam_code-12.40}/src/roam/analysis/__init__.py +0 -0
  22. {roam_code-12.38 → roam_code-12.40}/src/roam/analysis/effects.py +0 -0
  23. {roam_code-12.38 → roam_code-12.40}/src/roam/analysis/taint.py +0 -0
  24. {roam_code-12.38 → roam_code-12.40}/src/roam/api.py +0 -0
  25. {roam_code-12.38 → roam_code-12.40}/src/roam/ask/__init__.py +0 -0
  26. {roam_code-12.38 → roam_code-12.40}/src/roam/ask/classifier.py +0 -0
  27. {roam_code-12.38 → roam_code-12.40}/src/roam/ask/recipes.py +0 -0
  28. {roam_code-12.38 → roam_code-12.40}/src/roam/ask/runner.py +0 -0
  29. {roam_code-12.38 → roam_code-12.40}/src/roam/ask/workflow.py +0 -0
  30. {roam_code-12.38 → roam_code-12.40}/src/roam/attest/__init__.py +0 -0
  31. {roam_code-12.38 → roam_code-12.40}/src/roam/attest/cga.py +0 -0
  32. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/__init__.py +0 -0
  33. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/base.py +0 -0
  34. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_config.py +0 -0
  35. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_django.py +0 -0
  36. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_protobuf.py +0 -0
  37. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_rest_api.py +0 -0
  38. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_salesforce.py +0 -0
  39. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/bridge_template.py +0 -0
  40. {roam_code-12.38 → roam_code-12.40}/src/roam/bridges/registry.py +0 -0
  41. {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/__init__.py +0 -0
  42. {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/detectors.py +0 -0
  43. {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/fixes.py +0 -0
  44. {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/python_idioms.py +0 -0
  45. {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/smells.py +0 -0
  46. {roam_code-12.38 → roam_code-12.40}/src/roam/catalog/tasks.py +0 -0
  47. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/__init__.py +0 -0
  48. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/audit_trail_helpers.py +0 -0
  49. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/changed_files.py +0 -0
  50. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_adrs.py +0 -0
  51. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_adversarial.py +0 -0
  52. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_affected.py +0 -0
  53. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_affected_tests.py +0 -0
  54. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_agent_context.py +0 -0
  55. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_agent_export.py +0 -0
  56. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_agent_plan.py +0 -0
  57. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ai_ratio.py +0 -0
  58. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ai_readiness.py +0 -0
  59. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_alerts.py +0 -0
  60. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_annotate.py +0 -0
  61. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_api.py +0 -0
  62. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_api_changes.py +0 -0
  63. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_api_drift.py +0 -0
  64. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ask.py +0 -0
  65. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_attest.py +0 -0
  66. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit.py +0 -0
  67. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit_trail_conformance.py +0 -0
  68. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit_trail_export.py +0 -0
  69. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_audit_trail_verify.py +0 -0
  70. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_auth_gaps.py +0 -0
  71. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_bisect.py +0 -0
  72. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_breaking.py +0 -0
  73. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_budget.py +0 -0
  74. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_bus_factor.py +0 -0
  75. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_capsule.py +0 -0
  76. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_cga.py +0 -0
  77. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_changelog.py +0 -0
  78. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ci_setup.py +0 -0
  79. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_clean.py +0 -0
  80. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_clones.py +0 -0
  81. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_closure.py +0 -0
  82. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_clusters.py +0 -0
  83. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_codeowners.py +0 -0
  84. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_complexity.py +0 -0
  85. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_config.py +0 -0
  86. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_congestion.py +0 -0
  87. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_context.py +0 -0
  88. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_conventions.py +0 -0
  89. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_coupling.py +0 -0
  90. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_critique.py +0 -0
  91. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_cut.py +0 -0
  92. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dark_matter.py +0 -0
  93. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dashboard.py +0 -0
  94. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dead.py +0 -0
  95. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_debt.py +0 -0
  96. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_deps.py +0 -0
  97. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_describe.py +0 -0
  98. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dev_profile.py +0 -0
  99. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_diagnose.py +0 -0
  100. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_diff.py +0 -0
  101. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_disambiguate.py +0 -0
  102. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_doc_staleness.py +0 -0
  103. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_docs_coverage.py +0 -0
  104. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_doctor.py +0 -0
  105. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_dogfood.py +0 -0
  106. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_drift.py +0 -0
  107. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_duplicates.py +0 -0
  108. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_effects.py +0 -0
  109. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_endpoints.py +0 -0
  110. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_entry_points.py +0 -0
  111. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_eval_retrieve.py +0 -0
  112. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_exit_codes.py +0 -0
  113. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fan.py +0 -0
  114. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_file.py +0 -0
  115. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fingerprint.py +0 -0
  116. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fitness.py +0 -0
  117. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_flag_dead.py +0 -0
  118. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fleet.py +0 -0
  119. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_fn_coupling.py +0 -0
  120. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_forecast.py +0 -0
  121. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_graph_export.py +0 -0
  122. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_graph_stats.py +0 -0
  123. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_grep.py +0 -0
  124. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_guard.py +0 -0
  125. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_health.py +0 -0
  126. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_help_search.py +0 -0
  127. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_hooks.py +0 -0
  128. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_hotspots.py +0 -0
  129. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_hover.py +0 -0
  130. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_impact.py +0 -0
  131. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_index.py +0 -0
  132. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_index_bundle.py +0 -0
  133. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_index_stats.py +0 -0
  134. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ingest_trace.py +0 -0
  135. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_init.py +0 -0
  136. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_intent.py +0 -0
  137. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_invariants.py +0 -0
  138. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_layers.py +0 -0
  139. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_map.py +0 -0
  140. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_math.py +0 -0
  141. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_mcp_setup.py +0 -0
  142. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_mcp_status.py +0 -0
  143. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_metrics.py +0 -0
  144. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_metrics_push.py +0 -0
  145. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_migration_safety.py +0 -0
  146. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_minimap.py +0 -0
  147. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_missing_index.py +0 -0
  148. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_module.py +0 -0
  149. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_mutate.py +0 -0
  150. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_n1.py +0 -0
  151. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_oracle.py +0 -0
  152. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_orchestrate.py +0 -0
  153. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_orphan_imports.py +0 -0
  154. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_orphan_routes.py +0 -0
  155. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_over_fetch.py +0 -0
  156. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_owner.py +0 -0
  157. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_partition.py +0 -0
  158. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_path_coverage.py +0 -0
  159. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_patterns.py +0 -0
  160. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_plan.py +0 -0
  161. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_plan_refactor.py +0 -0
  162. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_plugins.py +0 -0
  163. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_analyze.py +0 -0
  164. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_comment_render.py +0 -0
  165. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_diff.py +0 -0
  166. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_prep.py +0 -0
  167. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pr_risk.py +0 -0
  168. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pre_commit.py +0 -0
  169. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_preflight.py +0 -0
  170. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_py_modern.py +0 -0
  171. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_py_types.py +0 -0
  172. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_pytest_fixtures.py +0 -0
  173. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_recipes.py +0 -0
  174. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_recommend.py +0 -0
  175. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_relate.py +0 -0
  176. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_reset.py +0 -0
  177. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_retrieve.py +0 -0
  178. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_risk.py +0 -0
  179. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_rules.py +0 -0
  180. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_rules_validate.py +0 -0
  181. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_safe_delete.py +0 -0
  182. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_safe_zones.py +0 -0
  183. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_sbom.py +0 -0
  184. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_schema.py +0 -0
  185. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_search.py +0 -0
  186. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_search_semantic.py +0 -0
  187. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_secrets.py +0 -0
  188. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_semantic_diff.py +0 -0
  189. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_simulate.py +0 -0
  190. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_simulate_departure.py +0 -0
  191. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_sketch.py +0 -0
  192. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_smells.py +0 -0
  193. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_spectral.py +0 -0
  194. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_split.py +0 -0
  195. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_stats.py +0 -0
  196. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_suggest_refactoring.py +0 -0
  197. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_suggest_reviewers.py +0 -0
  198. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_supply_chain.py +0 -0
  199. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_suppress.py +0 -0
  200. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_symbol.py +0 -0
  201. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_syntax_check.py +0 -0
  202. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_taint.py +0 -0
  203. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_telemetry.py +0 -0
  204. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_gaps.py +0 -0
  205. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_impact.py +0 -0
  206. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_pyramid.py +0 -0
  207. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_test_scaffold.py +0 -0
  208. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_testmap.py +0 -0
  209. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_timeline.py +0 -0
  210. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_tour.py +0 -0
  211. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_trace.py +0 -0
  212. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_triage.py +0 -0
  213. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_understand.py +0 -0
  214. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_uses.py +0 -0
  215. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_verify.py +0 -0
  216. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_verify_imports.py +0 -0
  217. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_version.py +0 -0
  218. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vibe_check.py +0 -0
  219. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_visualize.py +0 -0
  220. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vuln_map.py +0 -0
  221. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vuln_reach.py +0 -0
  222. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_vulns.py +0 -0
  223. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_watch.py +0 -0
  224. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_weather.py +0 -0
  225. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_why.py +0 -0
  226. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_why_fail.py +0 -0
  227. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_workflow.py +0 -0
  228. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_ws.py +0 -0
  229. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/cmd_xlang.py +0 -0
  230. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/codeowners_helpers.py +0 -0
  231. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/context_helpers.py +0 -0
  232. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/finding_suppress.py +0 -0
  233. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/gate_presets.py +0 -0
  234. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/git_helpers.py +0 -0
  235. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/graph_helpers.py +0 -0
  236. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/metrics_history.py +0 -0
  237. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/next_steps.py +0 -0
  238. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/__init__.py +0 -0
  239. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/audit_trail.py +0 -0
  240. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/cache.py +0 -0
  241. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/pr_analyze/rules.py +0 -0
  242. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/resolve.py +0 -0
  243. {roam_code-12.38 → roam_code-12.40}/src/roam/commands/suppression.py +0 -0
  244. {roam_code-12.38 → roam_code-12.40}/src/roam/config.py +0 -0
  245. {roam_code-12.38 → roam_code-12.40}/src/roam/coverage_reports.py +0 -0
  246. {roam_code-12.38 → roam_code-12.40}/src/roam/critique/__init__.py +0 -0
  247. {roam_code-12.38 → roam_code-12.40}/src/roam/critique/aggregator.py +0 -0
  248. {roam_code-12.38 → roam_code-12.40}/src/roam/critique/checks.py +0 -0
  249. {roam_code-12.38 → roam_code-12.40}/src/roam/db/__init__.py +0 -0
  250. {roam_code-12.38 → roam_code-12.40}/src/roam/db/connection.py +0 -0
  251. {roam_code-12.38 → roam_code-12.40}/src/roam/db/queries.py +0 -0
  252. {roam_code-12.38 → roam_code-12.40}/src/roam/db/schema.py +0 -0
  253. {roam_code-12.38 → roam_code-12.40}/src/roam/eval/__init__.py +0 -0
  254. {roam_code-12.38 → roam_code-12.40}/src/roam/eval/harness.py +0 -0
  255. {roam_code-12.38 → roam_code-12.40}/src/roam/exit_codes.py +0 -0
  256. {roam_code-12.38 → roam_code-12.40}/src/roam/fleet/__init__.py +0 -0
  257. {roam_code-12.38 → roam_code-12.40}/src/roam/fleet/adapters.py +0 -0
  258. {roam_code-12.38 → roam_code-12.40}/src/roam/fleet/manifest.py +0 -0
  259. {roam_code-12.38 → roam_code-12.40}/src/roam/git_utils.py +0 -0
  260. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/__init__.py +0 -0
  261. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/anomaly.py +0 -0
  262. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/builder.py +0 -0
  263. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/clone_detect.py +0 -0
  264. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/clusters.py +0 -0
  265. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/cycles.py +0 -0
  266. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/dark_matter.py +0 -0
  267. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/diff.py +0 -0
  268. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/fingerprint.py +0 -0
  269. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/layers.py +0 -0
  270. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/pagerank.py +0 -0
  271. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/partition.py +0 -0
  272. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/pathfinding.py +0 -0
  273. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/propagation.py +0 -0
  274. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/simulate.py +0 -0
  275. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/spectral.py +0 -0
  276. {roam_code-12.38 → roam_code-12.40}/src/roam/graph/stats.py +0 -0
  277. {roam_code-12.38 → roam_code-12.40}/src/roam/index/__init__.py +0 -0
  278. {roam_code-12.38 → roam_code-12.40}/src/roam/index/complexity.py +0 -0
  279. {roam_code-12.38 → roam_code-12.40}/src/roam/index/discovery.py +0 -0
  280. {roam_code-12.38 → roam_code-12.40}/src/roam/index/django_post.py +0 -0
  281. {roam_code-12.38 → roam_code-12.40}/src/roam/index/file_roles.py +0 -0
  282. {roam_code-12.38 → roam_code-12.40}/src/roam/index/git_stats.py +0 -0
  283. {roam_code-12.38 → roam_code-12.40}/src/roam/index/gitignore.py +0 -0
  284. {roam_code-12.38 → roam_code-12.40}/src/roam/index/incremental.py +0 -0
  285. {roam_code-12.38 → roam_code-12.40}/src/roam/index/indexer.py +0 -0
  286. {roam_code-12.38 → roam_code-12.40}/src/roam/index/parser.py +0 -0
  287. {roam_code-12.38 → roam_code-12.40}/src/roam/index/pytest_fixtures.py +0 -0
  288. {roam_code-12.38 → roam_code-12.40}/src/roam/index/registry_dispatch.py +0 -0
  289. {roam_code-12.38 → roam_code-12.40}/src/roam/index/relations.py +0 -0
  290. {roam_code-12.38 → roam_code-12.40}/src/roam/index/symbols.py +0 -0
  291. {roam_code-12.38 → roam_code-12.40}/src/roam/index/test_conventions.py +0 -0
  292. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/__init__.py +0 -0
  293. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/apex_lang.py +0 -0
  294. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/aura_lang.py +0 -0
  295. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/base.py +0 -0
  296. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/c_lang.py +0 -0
  297. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/csharp_lang.py +0 -0
  298. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/extractor_schema.py +0 -0
  299. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/extractors/kotlin.yaml +0 -0
  300. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/foxpro_lang.py +0 -0
  301. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/generic_lang.py +0 -0
  302. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/go_lang.py +0 -0
  303. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/hcl_lang.py +0 -0
  304. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/java_lang.py +0 -0
  305. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/javascript_lang.py +0 -0
  306. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/kotlin_lang.py +0 -0
  307. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/php_lang.py +0 -0
  308. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/python_lang.py +0 -0
  309. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/query_engine.py +0 -0
  310. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/registry.py +0 -0
  311. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/ruby_lang.py +0 -0
  312. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/rust_lang.py +0 -0
  313. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/scala_lang.py +0 -0
  314. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/sfxml_lang.py +0 -0
  315. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/sql_lang.py +0 -0
  316. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/swift_lang.py +0 -0
  317. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/typescript_lang.py +0 -0
  318. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/visualforce_lang.py +0 -0
  319. {roam_code-12.38 → roam_code-12.40}/src/roam/languages/yaml_lang.py +0 -0
  320. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/__init__.py +0 -0
  321. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/completions.py +0 -0
  322. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/concurrency.py +0 -0
  323. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/progress.py +0 -0
  324. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/sampling.py +0 -0
  325. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/session.py +0 -0
  326. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_extras/watcher.py +0 -0
  327. {roam_code-12.38 → roam_code-12.40}/src/roam/mcp_server.py +0 -0
  328. {roam_code-12.38 → roam_code-12.40}/src/roam/observability.py +0 -0
  329. {roam_code-12.38 → roam_code-12.40}/src/roam/output/__init__.py +0 -0
  330. {roam_code-12.38 → roam_code-12.40}/src/roam/output/confidence.py +0 -0
  331. {roam_code-12.38 → roam_code-12.40}/src/roam/output/errors.py +0 -0
  332. {roam_code-12.38 → roam_code-12.40}/src/roam/output/file_role_hints.py +0 -0
  333. {roam_code-12.38 → roam_code-12.40}/src/roam/output/formatter.py +0 -0
  334. {roam_code-12.38 → roam_code-12.40}/src/roam/output/framework_filter.py +0 -0
  335. {roam_code-12.38 → roam_code-12.40}/src/roam/output/mermaid.py +0 -0
  336. {roam_code-12.38 → roam_code-12.40}/src/roam/output/project_shape.py +0 -0
  337. {roam_code-12.38 → roam_code-12.40}/src/roam/output/sarif.py +0 -0
  338. {roam_code-12.38 → roam_code-12.40}/src/roam/output/schema_registry.py +0 -0
  339. {roam_code-12.38 → roam_code-12.40}/src/roam/plugins.py +0 -0
  340. {roam_code-12.38 → roam_code-12.40}/src/roam/refactor/__init__.py +0 -0
  341. {roam_code-12.38 → roam_code-12.40}/src/roam/refactor/codegen.py +0 -0
  342. {roam_code-12.38 → roam_code-12.40}/src/roam/refactor/transforms.py +0 -0
  343. {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/__init__.py +0 -0
  344. {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/learned_ranker.py +0 -0
  345. {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/pipeline.py +0 -0
  346. {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/rerank.py +0 -0
  347. {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/seeds.py +0 -0
  348. {roam_code-12.38 → roam_code-12.40}/src/roam/retrieve/semantic.py +0 -0
  349. {roam_code-12.38 → roam_code-12.40}/src/roam/rules/__init__.py +0 -0
  350. {roam_code-12.38 → roam_code-12.40}/src/roam/rules/ast_match.py +0 -0
  351. {roam_code-12.38 → roam_code-12.40}/src/roam/rules/builtin.py +0 -0
  352. {roam_code-12.38 → roam_code-12.40}/src/roam/rules/dataflow.py +0 -0
  353. {roam_code-12.38 → roam_code-12.40}/src/roam/rules/engine.py +0 -0
  354. {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/__init__.py +0 -0
  355. {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/daemon.py +0 -0
  356. {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/graph_backend.py +0 -0
  357. {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/hotspots.py +0 -0
  358. {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/lock_modes.py +0 -0
  359. {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/lockmgr.py +0 -0
  360. {roam_code-12.38 → roam_code-12.40}/src/roam/runtime/trace_ingest.py +0 -0
  361. {roam_code-12.38 → roam_code-12.40}/src/roam/search/__init__.py +0 -0
  362. {roam_code-12.38 → roam_code-12.40}/src/roam/search/framework_packs.py +0 -0
  363. {roam_code-12.38 → roam_code-12.40}/src/roam/search/index_embeddings.py +0 -0
  364. {roam_code-12.38 → roam_code-12.40}/src/roam/search/onnx_embeddings.py +0 -0
  365. {roam_code-12.38 → roam_code-12.40}/src/roam/search/tfidf.py +0 -0
  366. {roam_code-12.38 → roam_code-12.40}/src/roam/security/__init__.py +0 -0
  367. {roam_code-12.38 → roam_code-12.40}/src/roam/security/aibom_extension.py +0 -0
  368. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_classifier.py +0 -0
  369. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_engine.py +0 -0
  370. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/api_error_leak.yaml +0 -0
  371. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/java_fileupload_path_traversal.yaml +0 -0
  372. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_insecure_jwt_decode.yaml +0 -0
  373. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_localstorage_secrets.yaml +0 -0
  374. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_prototype_pollution.yaml +0 -0
  375. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_ssrf.yaml +0 -0
  376. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/js_xss.yaml +0 -0
  377. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_basic.yaml +0 -0
  378. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_deserialization.yaml +0 -0
  379. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_path_traversal.yaml +0 -0
  380. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_socketio_remote_source.yaml +0 -0
  381. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_sqli.yaml +0 -0
  382. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/python_urllib_open_redirect.yaml +0 -0
  383. {roam_code-12.38 → roam_code-12.40}/src/roam/security/taint_rules/vue_v_html.yaml +0 -0
  384. {roam_code-12.38 → roam_code-12.40}/src/roam/security/vuln_reach.py +0 -0
  385. {roam_code-12.38 → roam_code-12.40}/src/roam/security/vuln_store.py +0 -0
  386. {roam_code-12.38 → roam_code-12.40}/src/roam/surface_counts.py +0 -0
  387. {roam_code-12.38 → roam_code-12.40}/src/roam/telemetry.py +0 -0
  388. {roam_code-12.38 → roam_code-12.40}/src/roam/templates/__init__.py +0 -0
  389. {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/Jenkinsfile +0 -0
  390. {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/__init__.py +0 -0
  391. {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/agent-review.yml +0 -0
  392. {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/azure-pipelines.yml +0 -0
  393. {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/bitbucket-pipelines.yml +0 -0
  394. {roam_code-12.38 → roam_code-12.40}/src/roam/templates/ci/gitlab-ci.yml +0 -0
  395. {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/__init__.py +0 -0
  396. {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/aggregator.py +0 -0
  397. {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/api_scanner.py +0 -0
  398. {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/config.py +0 -0
  399. {roam_code-12.38 → roam_code-12.40}/src/roam/workspace/db.py +0 -0
  400. {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/dependency_links.txt +0 -0
  401. {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/entry_points.txt +0 -0
  402. {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/requires.txt +0 -0
  403. {roam_code-12.38 → roam_code-12.40}/src/roam_code.egg-info/top_level.txt +0 -0
  404. {roam_code-12.38 → roam_code-12.40}/tests/test_adrs.py +0 -0
  405. {roam_code-12.38 → roam_code-12.40}/tests/test_adversarial.py +0 -0
  406. {roam_code-12.38 → roam_code-12.40}/tests/test_affected.py +0 -0
  407. {roam_code-12.38 → roam_code-12.40}/tests/test_agent_export.py +0 -0
  408. {roam_code-12.38 → roam_code-12.40}/tests/test_agent_mode.py +0 -0
  409. {roam_code-12.38 → roam_code-12.40}/tests/test_agent_plan_context.py +0 -0
  410. {roam_code-12.38 → roam_code-12.40}/tests/test_ai_ratio.py +0 -0
  411. {roam_code-12.38 → roam_code-12.40}/tests/test_ai_readiness.py +0 -0
  412. {roam_code-12.38 → roam_code-12.40}/tests/test_alerts_cmd.py +0 -0
  413. {roam_code-12.38 → roam_code-12.40}/tests/test_annotations.py +0 -0
  414. {roam_code-12.38 → roam_code-12.40}/tests/test_anomaly.py +0 -0
  415. {roam_code-12.38 → roam_code-12.40}/tests/test_api_changes.py +0 -0
  416. {roam_code-12.38 → roam_code-12.40}/tests/test_api_drift.py +0 -0
  417. {roam_code-12.38 → roam_code-12.40}/tests/test_ask.py +0 -0
  418. {roam_code-12.38 → roam_code-12.40}/tests/test_attest.py +0 -0
  419. {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_aggregate.py +0 -0
  420. {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_conformance.py +0 -0
  421. {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_sequence.py +0 -0
  422. {roam_code-12.38 → roam_code-12.40}/tests/test_audit_trail_verify.py +0 -0
  423. {roam_code-12.38 → roam_code-12.40}/tests/test_auth_gaps.py +0 -0
  424. {roam_code-12.38 → roam_code-12.40}/tests/test_backend_fixes_round2.py +0 -0
  425. {roam_code-12.38 → roam_code-12.40}/tests/test_backend_fixes_round3.py +0 -0
  426. {roam_code-12.38 → roam_code-12.40}/tests/test_basic.py +0 -0
  427. {roam_code-12.38 → roam_code-12.40}/tests/test_batch_mcp.py +0 -0
  428. {roam_code-12.38 → roam_code-12.40}/tests/test_bisect.py +0 -0
  429. {roam_code-12.38 → roam_code-12.40}/tests/test_bridge_django.py +0 -0
  430. {roam_code-12.38 → roam_code-12.40}/tests/test_bridges.py +0 -0
  431. {roam_code-12.38 → roam_code-12.40}/tests/test_bridges_extended.py +0 -0
  432. {roam_code-12.38 → roam_code-12.40}/tests/test_budget.py +0 -0
  433. {roam_code-12.38 → roam_code-12.40}/tests/test_budget_flag.py +0 -0
  434. {roam_code-12.38 → roam_code-12.40}/tests/test_budget_phase2.py +0 -0
  435. {roam_code-12.38 → roam_code-12.40}/tests/test_bus_factor.py +0 -0
  436. {roam_code-12.38 → roam_code-12.40}/tests/test_capsule.py +0 -0
  437. {roam_code-12.38 → roam_code-12.40}/tests/test_cga.py +0 -0
  438. {roam_code-12.38 → roam_code-12.40}/tests/test_check_rules.py +0 -0
  439. {roam_code-12.38 → roam_code-12.40}/tests/test_ci_gate_eval.py +0 -0
  440. {roam_code-12.38 → roam_code-12.40}/tests/test_ci_sarif_guard.py +0 -0
  441. {roam_code-12.38 → roam_code-12.40}/tests/test_ci_setup.py +0 -0
  442. {roam_code-12.38 → roam_code-12.40}/tests/test_clones.py +0 -0
  443. {roam_code-12.38 → roam_code-12.40}/tests/test_closure.py +0 -0
  444. {roam_code-12.38 → roam_code-12.40}/tests/test_codeowners.py +0 -0
  445. {roam_code-12.38 → roam_code-12.40}/tests/test_commands_architecture.py +0 -0
  446. {roam_code-12.38 → roam_code-12.40}/tests/test_commands_exploration.py +0 -0
  447. {roam_code-12.38 → roam_code-12.40}/tests/test_commands_health.py +0 -0
  448. {roam_code-12.38 → roam_code-12.40}/tests/test_commands_refactoring.py +0 -0
  449. {roam_code-12.38 → roam_code-12.40}/tests/test_commands_workflow.py +0 -0
  450. {roam_code-12.38 → roam_code-12.40}/tests/test_competitor_site_data.py +0 -0
  451. {roam_code-12.38 → roam_code-12.40}/tests/test_comprehensive.py +0 -0
  452. {roam_code-12.38 → roam_code-12.40}/tests/test_config.py +0 -0
  453. {roam_code-12.38 → roam_code-12.40}/tests/test_congestion.py +0 -0
  454. {roam_code-12.38 → roam_code-12.40}/tests/test_context_propagation.py +0 -0
  455. {roam_code-12.38 → roam_code-12.40}/tests/test_conventions_cmd.py +0 -0
  456. {roam_code-12.38 → roam_code-12.40}/tests/test_coverage_gaps_cmd.py +0 -0
  457. {roam_code-12.38 → roam_code-12.40}/tests/test_coverage_ingestion.py +0 -0
  458. {roam_code-12.38 → roam_code-12.40}/tests/test_critique.py +0 -0
  459. {roam_code-12.38 → roam_code-12.40}/tests/test_cut.py +0 -0
  460. {roam_code-12.38 → roam_code-12.40}/tests/test_dark_matter.py +0 -0
  461. {roam_code-12.38 → roam_code-12.40}/tests/test_dark_matter_helpers.py +0 -0
  462. {roam_code-12.38 → roam_code-12.40}/tests/test_dashboard.py +0 -0
  463. {roam_code-12.38 → roam_code-12.40}/tests/test_dataflow_dead.py +0 -0
  464. {roam_code-12.38 → roam_code-12.40}/tests/test_dead_aging.py +0 -0
  465. {roam_code-12.38 → roam_code-12.40}/tests/test_defer_loading.py +0 -0
  466. {roam_code-12.38 → roam_code-12.40}/tests/test_demo_gif_asset.py +0 -0
  467. {roam_code-12.38 → roam_code-12.40}/tests/test_describe.py +0 -0
  468. {roam_code-12.38 → roam_code-12.40}/tests/test_detail_flag_hints.py +0 -0
  469. {roam_code-12.38 → roam_code-12.40}/tests/test_detector_precision.py +0 -0
  470. {roam_code-12.38 → roam_code-12.40}/tests/test_deterministic_output.py +0 -0
  471. {roam_code-12.38 → roam_code-12.40}/tests/test_dev_profile.py +0 -0
  472. {roam_code-12.38 → roam_code-12.40}/tests/test_difficulty_scoring.py +0 -0
  473. {roam_code-12.38 → roam_code-12.40}/tests/test_doc_consistency.py +0 -0
  474. {roam_code-12.38 → roam_code-12.40}/tests/test_doc_staleness.py +0 -0
  475. {roam_code-12.38 → roam_code-12.40}/tests/test_docker_assets.py +0 -0
  476. {roam_code-12.38 → roam_code-12.40}/tests/test_docs_coverage.py +0 -0
  477. {roam_code-12.38 → roam_code-12.40}/tests/test_docs_site_quality.py +0 -0
  478. {roam_code-12.38 → roam_code-12.40}/tests/test_doctor.py +0 -0
  479. {roam_code-12.38 → roam_code-12.40}/tests/test_dogfood.py +0 -0
  480. {roam_code-12.38 → roam_code-12.40}/tests/test_drift.py +0 -0
  481. {roam_code-12.38 → roam_code-12.40}/tests/test_drift_by_team.py +0 -0
  482. {roam_code-12.38 → roam_code-12.40}/tests/test_duplicates.py +0 -0
  483. {roam_code-12.38 → roam_code-12.40}/tests/test_effects.py +0 -0
  484. {roam_code-12.38 → roam_code-12.40}/tests/test_effects_propagation.py +0 -0
  485. {roam_code-12.38 → roam_code-12.40}/tests/test_endpoints.py +0 -0
  486. {roam_code-12.38 → roam_code-12.40}/tests/test_entry_points_cmd.py +0 -0
  487. {roam_code-12.38 → roam_code-12.40}/tests/test_eval_retrieve.py +0 -0
  488. {roam_code-12.38 → roam_code-12.40}/tests/test_except_pass_narrow.py +0 -0
  489. {roam_code-12.38 → roam_code-12.40}/tests/test_exclude_patterns.py +0 -0
  490. {roam_code-12.38 → roam_code-12.40}/tests/test_exit_codes.py +0 -0
  491. {roam_code-12.38 → roam_code-12.40}/tests/test_extractor_grammar_drift.py +0 -0
  492. {roam_code-12.38 → roam_code-12.40}/tests/test_fallback_contracts.py +0 -0
  493. {roam_code-12.38 → roam_code-12.40}/tests/test_file_roles.py +0 -0
  494. {roam_code-12.38 → roam_code-12.40}/tests/test_finding_suppress.py +0 -0
  495. {roam_code-12.38 → roam_code-12.40}/tests/test_fingerprint.py +0 -0
  496. {roam_code-12.38 → roam_code-12.40}/tests/test_fixes.py +0 -0
  497. {roam_code-12.38 → roam_code-12.40}/tests/test_flag_dead.py +0 -0
  498. {roam_code-12.38 → roam_code-12.40}/tests/test_fleet.py +0 -0
  499. {roam_code-12.38 → roam_code-12.40}/tests/test_fn_coupling.py +0 -0
  500. {roam_code-12.38 → roam_code-12.40}/tests/test_forecast.py +0 -0
  501. {roam_code-12.38 → roam_code-12.40}/tests/test_formatters.py +0 -0
  502. {roam_code-12.38 → roam_code-12.40}/tests/test_foxpro.py +0 -0
  503. {roam_code-12.38 → roam_code-12.40}/tests/test_framework_detection.py +0 -0
  504. {roam_code-12.38 → roam_code-12.40}/tests/test_gate_presets.py +0 -0
  505. {roam_code-12.38 → roam_code-12.40}/tests/test_git_helpers.py +0 -0
  506. {roam_code-12.38 → roam_code-12.40}/tests/test_git_utils.py +0 -0
  507. {roam_code-12.38 → roam_code-12.40}/tests/test_guard.py +0 -0
  508. {roam_code-12.38 → roam_code-12.40}/tests/test_health_gate.py +0 -0
  509. {roam_code-12.38 → roam_code-12.40}/tests/test_hooks.py +0 -0
  510. {roam_code-12.38 → roam_code-12.40}/tests/test_hotspots.py +0 -0
  511. {roam_code-12.38 → roam_code-12.40}/tests/test_hover.py +0 -0
  512. {roam_code-12.38 → roam_code-12.40}/tests/test_index.py +0 -0
  513. {roam_code-12.38 → roam_code-12.40}/tests/test_index_bundle.py +0 -0
  514. {roam_code-12.38 → roam_code-12.40}/tests/test_init_cmd.py +0 -0
  515. {roam_code-12.38 → roam_code-12.40}/tests/test_install_check.py +0 -0
  516. {roam_code-12.38 → roam_code-12.40}/tests/test_intent.py +0 -0
  517. {roam_code-12.38 → roam_code-12.40}/tests/test_invariants.py +0 -0
  518. {roam_code-12.38 → roam_code-12.40}/tests/test_json_contracts.py +0 -0
  519. {roam_code-12.38 → roam_code-12.40}/tests/test_json_error_envelope.py +0 -0
  520. {roam_code-12.38 → roam_code-12.40}/tests/test_kotlin_swift_extractors.py +0 -0
  521. {roam_code-12.38 → roam_code-12.40}/tests/test_language_corpus.py +0 -0
  522. {roam_code-12.38 → roam_code-12.40}/tests/test_languages.py +0 -0
  523. {roam_code-12.38 → roam_code-12.40}/tests/test_laravel_fp_fixes.py +0 -0
  524. {roam_code-12.38 → roam_code-12.40}/tests/test_library_api.py +0 -0
  525. {roam_code-12.38 → roam_code-12.40}/tests/test_math.py +0 -0
  526. {roam_code-12.38 → roam_code-12.40}/tests/test_math_fp_fixes.py +0 -0
  527. {roam_code-12.38 → roam_code-12.40}/tests/test_math_tips.py +0 -0
  528. {roam_code-12.38 → roam_code-12.40}/tests/test_mcp_extras.py +0 -0
  529. {roam_code-12.38 → roam_code-12.40}/tests/test_mcp_server.py +0 -0
  530. {roam_code-12.38 → roam_code-12.40}/tests/test_mcp_setup.py +0 -0
  531. {roam_code-12.38 → roam_code-12.40}/tests/test_mermaid.py +0 -0
  532. {roam_code-12.38 → roam_code-12.40}/tests/test_metrics_cmd.py +0 -0
  533. {roam_code-12.38 → roam_code-12.40}/tests/test_metrics_push.py +0 -0
  534. {roam_code-12.38 → roam_code-12.40}/tests/test_migration_safety.py +0 -0
  535. {roam_code-12.38 → roam_code-12.40}/tests/test_minimap.py +0 -0
  536. {roam_code-12.38 → roam_code-12.40}/tests/test_missing_index.py +0 -0
  537. {roam_code-12.38 → roam_code-12.40}/tests/test_mutate.py +0 -0
  538. {roam_code-12.38 → roam_code-12.40}/tests/test_n1.py +0 -0
  539. {roam_code-12.38 → roam_code-12.40}/tests/test_next_steps.py +0 -0
  540. {roam_code-12.38 → roam_code-12.40}/tests/test_onboard.py +0 -0
  541. {roam_code-12.38 → roam_code-12.40}/tests/test_oracle.py +0 -0
  542. {roam_code-12.38 → roam_code-12.40}/tests/test_orchestrate.py +0 -0
  543. {roam_code-12.38 → roam_code-12.40}/tests/test_orphan_routes.py +0 -0
  544. {roam_code-12.38 → roam_code-12.40}/tests/test_oss_bench_harness.py +0 -0
  545. {roam_code-12.38 → roam_code-12.40}/tests/test_over_fetch.py +0 -0
  546. {roam_code-12.38 → roam_code-12.40}/tests/test_pagerank_truncation.py +0 -0
  547. {roam_code-12.38 → roam_code-12.40}/tests/test_partition.py +0 -0
  548. {roam_code-12.38 → roam_code-12.40}/tests/test_path_coverage.py +0 -0
  549. {roam_code-12.38 → roam_code-12.40}/tests/test_patterns_cmd.py +0 -0
  550. {roam_code-12.38 → roam_code-12.40}/tests/test_performance.py +0 -0
  551. {roam_code-12.38 → roam_code-12.40}/tests/test_personalized_pagerank.py +0 -0
  552. {roam_code-12.38 → roam_code-12.40}/tests/test_plan.py +0 -0
  553. {roam_code-12.38 → roam_code-12.40}/tests/test_plugin_discovery.py +0 -0
  554. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze.py +0 -0
  555. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_cache.py +0 -0
  556. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_edge_cases.py +0 -0
  557. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_helpers.py +0 -0
  558. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_analyze_v2_signals.py +0 -0
  559. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_comment_render.py +0 -0
  560. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_comment_script.py +0 -0
  561. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_diff.py +0 -0
  562. {roam_code-12.38 → roam_code-12.40}/tests/test_pr_risk_author.py +0 -0
  563. {roam_code-12.38 → roam_code-12.40}/tests/test_progress.py +0 -0
  564. {roam_code-12.38 → roam_code-12.40}/tests/test_progressive_disclosure.py +0 -0
  565. {roam_code-12.38 → roam_code-12.40}/tests/test_properties.py +0 -0
  566. {roam_code-12.38 → roam_code-12.40}/tests/test_pytest_fixtures.py +0 -0
  567. {roam_code-12.38 → roam_code-12.40}/tests/test_python_extractor_v2.py +0 -0
  568. {roam_code-12.38 → roam_code-12.40}/tests/test_python_idioms_e2e.py +0 -0
  569. {roam_code-12.38 → roam_code-12.40}/tests/test_python_pivot.py +0 -0
  570. {roam_code-12.38 → roam_code-12.40}/tests/test_readme_surface_consistency.py +0 -0
  571. {roam_code-12.38 → roam_code-12.40}/tests/test_realworld_feedback.py +0 -0
  572. {roam_code-12.38 → roam_code-12.40}/tests/test_refactoring_intelligence.py +0 -0
  573. {roam_code-12.38 → roam_code-12.40}/tests/test_registry_dispatch.py +0 -0
  574. {roam_code-12.38 → roam_code-12.40}/tests/test_regression_fp_corpus.py +0 -0
  575. {roam_code-12.38 → roam_code-12.40}/tests/test_relate.py +0 -0
  576. {roam_code-12.38 → roam_code-12.40}/tests/test_report.py +0 -0
  577. {roam_code-12.38 → roam_code-12.40}/tests/test_reset_clean.py +0 -0
  578. {roam_code-12.38 → roam_code-12.40}/tests/test_resolve.py +0 -0
  579. {roam_code-12.38 → roam_code-12.40}/tests/test_retrieve.py +0 -0
  580. {roam_code-12.38 → roam_code-12.40}/tests/test_retrieve_cross_repo.py +0 -0
  581. {roam_code-12.38 → roam_code-12.40}/tests/test_retrieve_seeds.py +0 -0
  582. {roam_code-12.38 → roam_code-12.40}/tests/test_risk.py +0 -0
  583. {roam_code-12.38 → roam_code-12.40}/tests/test_ruby.py +0 -0
  584. {roam_code-12.38 → roam_code-12.40}/tests/test_rule_profiles.py +0 -0
  585. {roam_code-12.38 → roam_code-12.40}/tests/test_rules.py +0 -0
  586. {roam_code-12.38 → roam_code-12.40}/tests/test_rules_ast_match.py +0 -0
  587. {roam_code-12.38 → roam_code-12.40}/tests/test_rules_community_pack.py +0 -0
  588. {roam_code-12.38 → roam_code-12.40}/tests/test_rules_dataflow.py +0 -0
  589. {roam_code-12.38 → roam_code-12.40}/tests/test_rules_symbol_requirements.py +0 -0
  590. {roam_code-12.38 → roam_code-12.40}/tests/test_rules_validate.py +0 -0
  591. {roam_code-12.38 → roam_code-12.40}/tests/test_runtime.py +0 -0
  592. {roam_code-12.38 → roam_code-12.40}/tests/test_runtime_score.py +0 -0
  593. {roam_code-12.38 → roam_code-12.40}/tests/test_salesforce.py +0 -0
  594. {roam_code-12.38 → roam_code-12.40}/tests/test_sarif_flag.py +0 -0
  595. {roam_code-12.38 → roam_code-12.40}/tests/test_sbom.py +0 -0
  596. {roam_code-12.38 → roam_code-12.40}/tests/test_scala.py +0 -0
  597. {roam_code-12.38 → roam_code-12.40}/tests/test_schema_versioning.py +0 -0
  598. {roam_code-12.38 → roam_code-12.40}/tests/test_search_explain.py +0 -0
  599. {roam_code-12.38 → roam_code-12.40}/tests/test_secrets.py +0 -0
  600. {roam_code-12.38 → roam_code-12.40}/tests/test_secrets_v2.py +0 -0
  601. {roam_code-12.38 → roam_code-12.40}/tests/test_semantic_diff.py +0 -0
  602. {roam_code-12.38 → roam_code-12.40}/tests/test_semantic_onnx.py +0 -0
  603. {roam_code-12.38 → roam_code-12.40}/tests/test_semantic_search.py +0 -0
  604. {roam_code-12.38 → roam_code-12.40}/tests/test_simulate.py +0 -0
  605. {roam_code-12.38 → roam_code-12.40}/tests/test_simulate_departure.py +0 -0
  606. {roam_code-12.38 → roam_code-12.40}/tests/test_sketch.py +0 -0
  607. {roam_code-12.38 → roam_code-12.40}/tests/test_smells.py +0 -0
  608. {roam_code-12.38 → roam_code-12.40}/tests/test_smoke.py +0 -0
  609. {roam_code-12.38 → roam_code-12.40}/tests/test_sna_metrics.py +0 -0
  610. {roam_code-12.38 → roam_code-12.40}/tests/test_spectral.py +0 -0
  611. {roam_code-12.38 → roam_code-12.40}/tests/test_split_cmd.py +0 -0
  612. {roam_code-12.38 → roam_code-12.40}/tests/test_sql.py +0 -0
  613. {roam_code-12.38 → roam_code-12.40}/tests/test_suggest_reviewers.py +0 -0
  614. {roam_code-12.38 → roam_code-12.40}/tests/test_supply_chain.py +0 -0
  615. {roam_code-12.38 → roam_code-12.40}/tests/test_surface_counts.py +0 -0
  616. {roam_code-12.38 → roam_code-12.40}/tests/test_syntax_check.py +0 -0
  617. {roam_code-12.38 → roam_code-12.40}/tests/test_taint.py +0 -0
  618. {roam_code-12.38 → roam_code-12.40}/tests/test_taint_analysis.py +0 -0
  619. {roam_code-12.38 → roam_code-12.40}/tests/test_taint_classifier.py +0 -0
  620. {roam_code-12.38 → roam_code-12.40}/tests/test_taint_intraprocedural.py +0 -0
  621. {roam_code-12.38 → roam_code-12.40}/tests/test_test_conventions.py +0 -0
  622. {roam_code-12.38 → roam_code-12.40}/tests/test_test_gaps.py +0 -0
  623. {roam_code-12.38 → roam_code-12.40}/tests/test_test_scaffold.py +0 -0
  624. {roam_code-12.38 → roam_code-12.40}/tests/test_testmap.py +0 -0
  625. {roam_code-12.38 → roam_code-12.40}/tests/test_top_flag_consistency.py +0 -0
  626. {roam_code-12.38 → roam_code-12.40}/tests/test_tour_cmd.py +0 -0
  627. {roam_code-12.38 → roam_code-12.40}/tests/test_trends.py +0 -0
  628. {roam_code-12.38 → roam_code-12.40}/tests/test_trends_cohort.py +0 -0
  629. {roam_code-12.38 → roam_code-12.40}/tests/test_triage.py +0 -0
  630. {roam_code-12.38 → roam_code-12.40}/tests/test_uses_cmd.py +0 -0
  631. {roam_code-12.38 → roam_code-12.40}/tests/test_v1215_passes.py +0 -0
  632. {roam_code-12.38 → roam_code-12.40}/tests/test_v1216_passes.py +0 -0
  633. {roam_code-12.38 → roam_code-12.40}/tests/test_v1216_passes_41_50.py +0 -0
  634. {roam_code-12.38 → roam_code-12.40}/tests/test_v1216_passes_51_60.py +0 -0
  635. {roam_code-12.38 → roam_code-12.40}/tests/test_v1217_passes_61_80.py +0 -0
  636. {roam_code-12.38 → roam_code-12.40}/tests/test_v1218_passes_81_90.py +0 -0
  637. {roam_code-12.38 → roam_code-12.40}/tests/test_v1219_passes_91_100.py +0 -0
  638. {roam_code-12.38 → roam_code-12.40}/tests/test_v1220_passes_101_110.py +0 -0
  639. {roam_code-12.38 → roam_code-12.40}/tests/test_v1221_query_timeout.py +0 -0
  640. {roam_code-12.38 → roam_code-12.40}/tests/test_v1221_untested_commands.py +0 -0
  641. {roam_code-12.38 → roam_code-12.40}/tests/test_v12_2.py +0 -0
  642. {roam_code-12.38 → roam_code-12.40}/tests/test_v2_edge_cases.py +0 -0
  643. {roam_code-12.38 → roam_code-12.40}/tests/test_v2_integration.py +0 -0
  644. {roam_code-12.38 → roam_code-12.40}/tests/test_v6_features.py +0 -0
  645. {roam_code-12.38 → roam_code-12.40}/tests/test_v71_features.py +0 -0
  646. {roam_code-12.38 → roam_code-12.40}/tests/test_v7_features.py +0 -0
  647. {roam_code-12.38 → roam_code-12.40}/tests/test_v82_features.py +0 -0
  648. {roam_code-12.38 → roam_code-12.40}/tests/test_verify.py +0 -0
  649. {roam_code-12.38 → roam_code-12.40}/tests/test_verify_imports.py +0 -0
  650. {roam_code-12.38 → roam_code-12.40}/tests/test_vibe_check.py +0 -0
  651. {roam_code-12.38 → roam_code-12.40}/tests/test_visualize.py +0 -0
  652. {roam_code-12.38 → roam_code-12.40}/tests/test_vuln.py +0 -0
  653. {roam_code-12.38 → roam_code-12.40}/tests/test_vulns_cmd.py +0 -0
  654. {roam_code-12.38 → roam_code-12.40}/tests/test_watch.py +0 -0
  655. {roam_code-12.38 → roam_code-12.40}/tests/test_why.py +0 -0
  656. {roam_code-12.38 → roam_code-12.40}/tests/test_workspace.py +0 -0
  657. {roam_code-12.38 → roam_code-12.40}/tests/test_ws_resolve_fixes.py +0 -0
  658. {roam_code-12.38 → roam_code-12.40}/tests/test_xlang.py +0 -0
  659. {roam_code-12.38 → roam_code-12.40}/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.38
3
+ Version: 12.40
4
4
  Summary: Instant codebase comprehension for AI coding agents
5
5
  Author: CosmoHac
6
6
  License-Expression: Apache-2.0
@@ -64,9 +64,9 @@ Dynamic: license-file
64
64
 
65
65
  **Architectural sight for AI coding agents — before they edit.**
66
66
 
67
- A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 182 specialised commands are advanced surface for specialised workflows.
67
+ A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 185 specialised commands are advanced surface for specialised workflows.
68
68
 
69
- *187 commands · 136 MCP tools · 27 languages · 100% local · zero API keys*
69
+ *190 commands · 136 MCP tools · 27 languages · 100% local · zero API keys*
70
70
 
71
71
  [![PyPI version](https://img.shields.io/pypi/v/roam-code?style=flat-square&color=blue)](https://pypi.org/project/roam-code/)
72
72
  [![GitHub stars](https://img.shields.io/github/stars/Cranot/roam-code?style=flat-square)](https://github.com/Cranot/roam-code/stargazers)
@@ -334,7 +334,7 @@ roam health
334
334
 
335
335
  ## Commands
336
336
 
337
- **Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 182 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 **187 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
337
+ **Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 185 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 **190 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
338
338
 
339
339
  <details>
340
340
  <summary><strong>Full command reference</strong></summary>
@@ -4,9 +4,9 @@
4
4
 
5
5
  **Architectural sight for AI coding agents — before they edit.**
6
6
 
7
- A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 182 specialised commands are advanced surface for specialised workflows.
7
+ A local code graph (SQLite + tree-sitter + git history) that gives any agent — Claude Code, Cursor, Aider, Continue, your own — five high-leverage verbs: `understand`, `retrieve`, `context`, `preflight`, `critique`. The other 185 specialised commands are advanced surface for specialised workflows.
8
8
 
9
- *187 commands · 136 MCP tools · 27 languages · 100% local · zero API keys*
9
+ *190 commands · 136 MCP tools · 27 languages · 100% local · zero API keys*
10
10
 
11
11
  [![PyPI version](https://img.shields.io/pypi/v/roam-code?style=flat-square&color=blue)](https://pypi.org/project/roam-code/)
12
12
  [![GitHub stars](https://img.shields.io/github/stars/Cranot/roam-code?style=flat-square)](https://github.com/Cranot/roam-code/stargazers)
@@ -274,7 +274,7 @@ roam health
274
274
 
275
275
  ## Commands
276
276
 
277
- **Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 182 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 **187 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
277
+ **Lead with the 5 verbs.** The [5 core commands](#core-commands) cover ~80% of agent workflows: `understand`, `context`, `retrieve`, `preflight`, `critique`. The remaining 185 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 **190 commands organised into 7 categories** (plus 6 aliases for muscle memory: `algo` → `math`, `weather` → `churn`, `digest` / `snapshot` / `trend` → `trends`, `onboard` → `understand`), but you don't need to know that to start.
278
278
 
279
279
  <details>
280
280
  <summary><strong>Full command reference</strong></summary>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "roam-code"
7
- version = "12.38"
7
+ version = "12.40"
8
8
  description = "Instant codebase comprehension for AI coding agents"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -83,6 +83,9 @@ _COMMANDS = {
83
83
  "fitness": ("roam.commands.cmd_fitness", "fitness"),
84
84
  "patterns": ("roam.commands.cmd_patterns", "patterns"),
85
85
  "preflight": ("roam.commands.cmd_preflight", "preflight"),
86
+ "permit": ("roam.commands.cmd_permit", "permit_cmd"),
87
+ "postmortem": ("roam.commands.cmd_postmortem", "postmortem_cmd"),
88
+ "article-12-check": ("roam.commands.cmd_article_12_check", "article_12_check_cmd"),
86
89
  "guard": ("roam.commands.cmd_guard", "guard"),
87
90
  "init": ("roam.commands.cmd_init", "init"),
88
91
  "config": ("roam.commands.cmd_config", "config"),
@@ -272,6 +275,8 @@ _CATEGORIES = {
272
275
  ],
273
276
  "Daily Workflow": [
274
277
  "preflight",
278
+ "permit",
279
+ "postmortem",
275
280
  "guard",
276
281
  "agent-plan",
277
282
  "agent-context",
@@ -284,6 +289,7 @@ _CATEGORIES = {
284
289
  "audit-trail-verify",
285
290
  "audit-trail-export",
286
291
  "audit-trail-conformance-check",
292
+ "article-12-check",
287
293
  "dogfood",
288
294
  "suppress",
289
295
  "pr-diff",
@@ -0,0 +1,381 @@
1
+ """``roam article-12-check`` — EU AI Act Article 12 readiness assessment.
2
+
3
+ EU AI Act Article 12 takes effect August 2, 2026, and requires high-risk
4
+ AI systems to "technically allow for the automatic recording of events
5
+ (logs) over the lifetime of the system." Penalty for non-compliance: up
6
+ to €15M or 3% of global turnover.
7
+
8
+ Most coding tools are NOT classified as high-risk under Annex III, BUT
9
+ they BECOME high-risk if their telemetry feeds into HR / promotion /
10
+ retention decisions. The non-applicability assessment itself is a
11
+ deliverable that DPOs and compliance officers need to file.
12
+
13
+ This command runs a checklist over the indexed repo and emits a
14
+ 1-page assessment report (Markdown by default; ``--pdf`` if reportlab
15
+ is installed). Each item references the specific Article (12, 18, 19)
16
+ or Annex (III) it maps to.
17
+
18
+ Phase 0.4 of the v2 monetization plan: stand-alone OSS funnel artifact
19
+ that captures Article-12-curious leads before they pick another
20
+ vendor. The pull quote is:
21
+
22
+ "becomes the vendor my DPO calls when Article 12 does apply."
23
+
24
+ Usage:
25
+
26
+ roam article-12-check # markdown to stdout
27
+ roam article-12-check --output report.md # write markdown
28
+ roam article-12-check --pdf out.pdf # write PDF (needs reportlab)
29
+ roam --json article-12-check # structured envelope
30
+
31
+ The assessment is deliberately conservative: items that don't apply
32
+ to a typical codebase get a "N/A — not classified as high-risk" tag
33
+ instead of a "FAIL" so the readiness report doesn't false-alarm
34
+ compliance teams.
35
+ """
36
+
37
+ from __future__ import annotations
38
+
39
+ import re
40
+ from datetime import datetime, timezone
41
+ from pathlib import Path
42
+
43
+ import click
44
+
45
+ from roam.commands.git_helpers import git_origin_url
46
+ from roam.commands.resolve import ensure_index
47
+ from roam.exit_codes import EXIT_SUCCESS
48
+ from roam.output.formatter import json_envelope, to_json
49
+
50
+ # ---------------------------------------------------------------------------
51
+ # Checklist items — each mapped to an Article / Annex
52
+ # ---------------------------------------------------------------------------
53
+
54
+
55
+ def _check_logs_directory_exists(project_root: Path) -> dict:
56
+ """Item 1 — Article 12: events must be recorded automatically."""
57
+ candidates = [".roam", ".roam/audit-trail", "logs", ".github/audit"]
58
+ found = [c for c in candidates if (project_root / c).exists()]
59
+ return {
60
+ "item": "Audit trail directory exists",
61
+ "article": "12 (event logging)",
62
+ "passed": bool(found),
63
+ "evidence": f"found: {', '.join(found)}" if found else "no .roam/ or logs/ directory found",
64
+ "fix": "Run `roam audit-trail-export` to bootstrap an audit trail under .roam/audit-trail.jsonl",
65
+ }
66
+
67
+
68
+ def _check_audit_trail_has_records(project_root: Path) -> dict:
69
+ """Item 2 — Article 12: trail must accumulate over the lifetime of the system."""
70
+ trail_path = project_root / ".roam" / "audit-trail.jsonl"
71
+ record_count = 0
72
+ if trail_path.exists():
73
+ try:
74
+ record_count = sum(1 for line in trail_path.open(encoding="utf-8") if line.strip())
75
+ except OSError:
76
+ record_count = 0
77
+ return {
78
+ "item": "Audit trail has at least 1 record",
79
+ "article": "12 (event logging)",
80
+ "passed": record_count > 0,
81
+ "evidence": f"{record_count} record(s) in {trail_path}"
82
+ if record_count
83
+ else "audit-trail.jsonl missing or empty",
84
+ "fix": "Pipe `roam pr-analyze --emit-audit-record` (default) on every PR; first record bootstraps the chain",
85
+ }
86
+
87
+
88
+ def _check_retention_documented(project_root: Path) -> dict:
89
+ """Item 3 — Article 19: minimum 6-month log retention by deployers."""
90
+ candidates = [
91
+ "docs/retention.md",
92
+ "docs/audit-retention.md",
93
+ "RETENTION.md",
94
+ ".roam/retention.yaml",
95
+ "AGENTS.md",
96
+ "CLAUDE.md",
97
+ ]
98
+ keywords = ("retention", "6 month", "180 day", "Article 19")
99
+ matches = []
100
+ for c in candidates:
101
+ p = project_root / c
102
+ if not p.exists():
103
+ continue
104
+ try:
105
+ text = p.read_text(encoding="utf-8", errors="replace").lower()
106
+ except OSError:
107
+ continue
108
+ if any(k in text for k in keywords):
109
+ matches.append(c)
110
+ return {
111
+ "item": "Log-retention policy documented (≥6 months per Article 19)",
112
+ "article": "19 (deployer obligations)",
113
+ "passed": bool(matches),
114
+ "evidence": f"keyword found in: {', '.join(matches)}"
115
+ if matches
116
+ else "no retention keyword in standard locations",
117
+ "fix": "Add a `## Retention` section to AGENTS.md or docs/retention.md stating 6-month minimum",
118
+ }
119
+
120
+
121
+ def _check_technical_documentation(project_root: Path) -> dict:
122
+ """Item 4 — Article 18: technical documentation retained 10 years."""
123
+ candidates = ["README.md", "ARCHITECTURE.md", "docs/", "AGENTS.md", "CLAUDE.md"]
124
+ found = [c for c in candidates if (project_root / c).exists()]
125
+ return {
126
+ "item": "Technical documentation present (Article 18: 10-year retention)",
127
+ "article": "18 (provider obligations)",
128
+ "passed": len(found) >= 2,
129
+ "evidence": f"found: {', '.join(found)}",
130
+ "fix": "Add ARCHITECTURE.md or expand AGENTS.md with system overview, data flows, and contacts",
131
+ }
132
+
133
+
134
+ def _check_attestation_artifacts(project_root: Path) -> dict:
135
+ """Item 5 — bonus: in-toto / sigstore attestations for AI-generated changes."""
136
+ candidates = [".roam/attestations", ".roam/cga", "attestations/"]
137
+ found = [c for c in candidates if (project_root / c).exists()]
138
+ return {
139
+ "item": "Cryptographic attestation surface exists (in-toto / sigstore)",
140
+ "article": "12 (event integrity)",
141
+ "passed": bool(found),
142
+ "evidence": f"found: {', '.join(found)}" if found else "no attestation artifacts",
143
+ "fix": "Run `roam attest cga --sign` to bootstrap signed CodeGraph attestations",
144
+ }
145
+
146
+
147
+ def _classify_high_risk_likelihood(project_root: Path) -> dict:
148
+ """Item 6 — heuristic: does the codebase look like an AI-tool that influences HR decisions?"""
149
+ risk_keywords = re.compile(
150
+ r"\b(?:promotion|retention|hr_decision|performance_review|workforce|hiring|firing|"
151
+ r"employee_score|developer_rating|promote|demote|terminate)\b",
152
+ re.IGNORECASE,
153
+ )
154
+ hits = 0
155
+ sample = 0
156
+ for path in project_root.rglob("*.py"):
157
+ if "test" in str(path).lower():
158
+ continue
159
+ try:
160
+ text = path.read_text(encoding="utf-8", errors="replace")
161
+ except OSError:
162
+ continue
163
+ sample += 1
164
+ if risk_keywords.search(text):
165
+ hits += 1
166
+ if sample > 200:
167
+ break
168
+ is_high_risk = hits > 0
169
+ return {
170
+ "item": "High-risk classification likelihood (Annex III)",
171
+ "article": "Annex III (high-risk system definitions)",
172
+ "passed": not is_high_risk,
173
+ "evidence": (
174
+ f"NOT high-risk — no HR/employment keywords matched across {sample} files scanned"
175
+ if not is_high_risk
176
+ else f"REVIEW — {hits} file(s) reference HR/employment workflows; consult counsel"
177
+ ),
178
+ "fix": (
179
+ "Document the non-applicability in compliance/eu-ai-act-assessment.md"
180
+ if not is_high_risk
181
+ else "Engage DPO immediately; this codebase MAY be high-risk under Annex III"
182
+ ),
183
+ }
184
+
185
+
186
+ _CHECKS = [
187
+ _check_logs_directory_exists,
188
+ _check_audit_trail_has_records,
189
+ _check_retention_documented,
190
+ _check_technical_documentation,
191
+ _check_attestation_artifacts,
192
+ _classify_high_risk_likelihood,
193
+ ]
194
+
195
+
196
+ # ---------------------------------------------------------------------------
197
+ # Report rendering
198
+ # ---------------------------------------------------------------------------
199
+
200
+
201
+ def _render_markdown_report(results: list[dict], project_root: Path) -> str:
202
+ passed = sum(1 for r in results if r["passed"])
203
+ total = len(results)
204
+ timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M UTC")
205
+ repo = git_origin_url() or str(project_root)
206
+ lines: list[str] = [
207
+ "# EU AI Act — Article 12 Readiness Assessment",
208
+ "",
209
+ f"**Generated**: {timestamp}",
210
+ f"**Repository**: {repo}",
211
+ f"**Score**: {passed} / {total} items passing",
212
+ "",
213
+ "## Background",
214
+ "",
215
+ "EU AI Act Article 12 takes effect **August 2, 2026** for high-risk AI",
216
+ "systems (Annex III). It requires automatic event logging built into",
217
+ "the system. Penalties for non-compliance: **€15M or 3% of global",
218
+ "annual turnover**, whichever is higher. Article 19 requires deployers",
219
+ "to retain logs for at least 6 months. Article 18 requires providers",
220
+ "to retain technical documentation for 10 years.",
221
+ "",
222
+ "Most coding tools are NOT classified as high-risk under Annex III.",
223
+ "However, they BECOME high-risk if telemetry feeds into HR /",
224
+ "promotion / retention decisions. **Even the non-applicability",
225
+ "assessment is a deliverable** that DPOs need on file.",
226
+ "",
227
+ "## Checklist",
228
+ "",
229
+ ]
230
+ for r in results:
231
+ mark = "✅ PASS" if r["passed"] else "⚠️ REVIEW"
232
+ lines.append(f"### {mark} — {r['item']}")
233
+ lines.append(f"_Article {r['article']}_")
234
+ lines.append("")
235
+ lines.append(f"**Evidence**: {r['evidence']}")
236
+ lines.append("")
237
+ if not r["passed"]:
238
+ lines.append(f"**Fix**: {r['fix']}")
239
+ lines.append("")
240
+ lines.append("")
241
+
242
+ lines.extend(
243
+ [
244
+ "---",
245
+ "",
246
+ "## Next steps",
247
+ "",
248
+ "1. Address any ⚠️ REVIEW items above.",
249
+ "2. If you suspect this codebase IS high-risk under Annex III,",
250
+ " consult counsel and your DPO immediately.",
251
+ "3. Run `roam audit-trail-export --since 2025-01-01` to capture",
252
+ " historical PR-analyze records into the chain.",
253
+ "4. Run `roam audit-trail-conformance-check` for a deeper",
254
+ " per-record audit.",
255
+ "",
256
+ "## Disclaimer",
257
+ "",
258
+ "This report is a tool-level readiness assessment generated by",
259
+ "`roam article-12-check`. It is NOT legal advice and does NOT",
260
+ "constitute a conformity assessment under the EU AI Act. For a",
261
+ "binding determination, consult qualified counsel and a notified",
262
+ "body where required.",
263
+ "",
264
+ "_Powered by [roam-code](https://github.com/Cranot/roam-code) — Apache 2.0_",
265
+ "",
266
+ ]
267
+ )
268
+ return "\n".join(lines)
269
+
270
+
271
+ def _render_pdf_report(markdown_text: str, output_path: Path) -> bool:
272
+ """Best-effort PDF emission via reportlab (optional)."""
273
+ try:
274
+ from reportlab.lib.pagesizes import A4
275
+ from reportlab.lib.styles import getSampleStyleSheet
276
+ from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer
277
+ except ImportError:
278
+ return False
279
+ doc = SimpleDocTemplate(str(output_path), pagesize=A4)
280
+ styles = getSampleStyleSheet()
281
+ flowables = []
282
+ for line in markdown_text.split("\n"):
283
+ if not line.strip():
284
+ flowables.append(Spacer(1, 6))
285
+ continue
286
+ if line.startswith("# "):
287
+ flowables.append(Paragraph(line[2:], styles["Heading1"]))
288
+ elif line.startswith("## "):
289
+ flowables.append(Paragraph(line[3:], styles["Heading2"]))
290
+ elif line.startswith("### "):
291
+ flowables.append(Paragraph(line[4:], styles["Heading3"]))
292
+ else:
293
+ flowables.append(Paragraph(line, styles["BodyText"]))
294
+ doc.build(flowables)
295
+ return True
296
+
297
+
298
+ @click.command(name="article-12-check")
299
+ @click.option(
300
+ "--output",
301
+ "output_path",
302
+ type=click.Path(),
303
+ default=None,
304
+ help="Write the markdown report to PATH (default: stdout).",
305
+ )
306
+ @click.option(
307
+ "--pdf",
308
+ "pdf_path",
309
+ type=click.Path(),
310
+ default=None,
311
+ help="Also write a PDF to PATH (requires reportlab; pip install reportlab).",
312
+ )
313
+ @click.pass_context
314
+ def article_12_check_cmd(ctx, output_path: str | None, pdf_path: str | None):
315
+ """EU AI Act Article 12 readiness assessment for the indexed repo.
316
+
317
+ Runs a 6-item checklist (audit trail, retention policy, technical
318
+ docs, attestation surface, high-risk classification heuristic) and
319
+ emits a 1-page markdown report. Optional PDF via reportlab.
320
+
321
+ \b
322
+ Examples:
323
+ roam article-12-check # markdown to stdout
324
+ roam article-12-check --output report.md
325
+ roam article-12-check --pdf assessment.pdf
326
+ roam --json article-12-check > envelope.json
327
+
328
+ Phase 0.4 of the v2 monetization plan — captures Article-12-curious
329
+ leads before they pick another vendor.
330
+ """
331
+ json_mode = ctx.obj.get("json") if ctx.obj else False
332
+ ensure_index()
333
+
334
+ project_root = Path.cwd()
335
+ results = [check(project_root) for check in _CHECKS]
336
+ passed = sum(1 for r in results if r["passed"])
337
+ total = len(results)
338
+
339
+ markdown_text = _render_markdown_report(results, project_root)
340
+
341
+ if output_path:
342
+ Path(output_path).write_text(markdown_text, encoding="utf-8")
343
+
344
+ pdf_written = False
345
+ if pdf_path:
346
+ pdf_written = _render_pdf_report(markdown_text, Path(pdf_path))
347
+
348
+ if json_mode:
349
+ click.echo(
350
+ to_json(
351
+ json_envelope(
352
+ "article-12-check",
353
+ summary={
354
+ "verdict": f"{passed}/{total} items passing",
355
+ "passed": passed,
356
+ "total": total,
357
+ "high_risk_classification": next(
358
+ (r["evidence"] for r in results if "high-risk" in r["item"].lower()),
359
+ "unknown",
360
+ ),
361
+ "output_path": output_path,
362
+ "pdf_path": pdf_path if pdf_written else None,
363
+ "pdf_skipped_reason": ("reportlab not installed" if (pdf_path and not pdf_written) else None),
364
+ },
365
+ items=results,
366
+ )
367
+ )
368
+ )
369
+ ctx.exit(EXIT_SUCCESS)
370
+ return
371
+
372
+ if output_path:
373
+ click.echo(f"VERDICT: {passed}/{total} items passing — written to {output_path}")
374
+ if pdf_path and pdf_written:
375
+ click.echo(f" PDF: {pdf_path}")
376
+ elif pdf_path and not pdf_written:
377
+ click.echo(" PDF skipped: reportlab not installed (pip install reportlab)", err=True)
378
+ else:
379
+ click.echo(markdown_text)
380
+
381
+ ctx.exit(EXIT_SUCCESS)
@@ -429,8 +429,8 @@ def check_rules(ctx, rule_filter, severity_filter, config_path, profile_name, do
429
429
  try:
430
430
  profile_overrides = resolve_profile(effective_profile)
431
431
  except ValueError as e:
432
- click.echo("Error: {}".format(e))
433
- raise SystemExit(1)
432
+ click.echo(f"Error: {e}")
433
+ raise SystemExit(1) from None
434
434
  # Profile overrides are the base; user overrides (from rules: section) layer on top
435
435
  merged = {ov.get("id"): ov for ov in profile_overrides}
436
436
  for ov in user_overrides:
@@ -287,7 +287,7 @@ def coverage_gaps(
287
287
  )
288
288
  else:
289
289
  click.echo(msg)
290
- raise SystemExit(1)
290
+ raise SystemExit(1) from None
291
291
 
292
292
  # --- Resolve preset / config gate rules ---
293
293
  preset_used = None