codevira 2.1.1__tar.gz → 3.0.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 (286) hide show
  1. {codevira-2.1.1 → codevira-3.0.0}/CHANGELOG.md +791 -1
  2. codevira-3.0.0/PKG-INFO +522 -0
  3. codevira-3.0.0/README.md +473 -0
  4. codevira-3.0.0/codevira.egg-info/PKG-INFO +522 -0
  5. {codevira-2.1.1 → codevira-3.0.0}/codevira.egg-info/SOURCES.txt +36 -31
  6. {codevira-2.1.1 → codevira-3.0.0}/codevira.egg-info/requires.txt +7 -3
  7. codevira-3.0.0/docs/architecture.md +264 -0
  8. codevira-3.0.0/docs/audit-2026-05-22.md +274 -0
  9. {codevira-2.1.1 → codevira-3.0.0}/docs/foolproof-product-charter.md +3 -2
  10. {codevira-2.1.1 → codevira-3.0.0}/docs/how-i-built-persistent-memory-for-ai-agents.md +10 -0
  11. {codevira-2.1.1 → codevira-3.0.0}/docs/linkedin-article-ai-agent-memory.md +9 -0
  12. {codevira-2.1.1 → codevira-3.0.0}/docs/medium-your-ai-coding-agent-has-amnesia.md +10 -0
  13. codevira-3.0.0/docs/morning-handoff-2026-05-22.md +337 -0
  14. codevira-3.0.0/docs/plans/v2.1.2.md +1342 -0
  15. codevira-3.0.0/docs/plans/v2.1.3.md +361 -0
  16. codevira-3.0.0/docs/plans/v2.2.0.md +960 -0
  17. codevira-3.0.0/docs/plans/v3.0.0.md +256 -0
  18. {codevira-2.1.1 → codevira-3.0.0}/docs/qa-playbook.md +14 -0
  19. {codevira-2.1.1 → codevira-3.0.0}/docs/roadmap.md +17 -4
  20. codevira-3.0.0/docs/surface-cuts-2026-05-22.md +348 -0
  21. codevira-3.0.0/docs/troubleshooting/antigravity.md +131 -0
  22. {codevira-2.1.1 → codevira-3.0.0}/indexer/chunker.py +4 -0
  23. {codevira-2.1.1 → codevira-3.0.0}/indexer/fix_history.py +57 -19
  24. {codevira-2.1.1 → codevira-3.0.0}/indexer/global_db.py +78 -21
  25. {codevira-2.1.1 → codevira-3.0.0}/indexer/graph_generator.py +95 -36
  26. {codevira-2.1.1 → codevira-3.0.0}/indexer/index_codebase.py +51 -94
  27. {codevira-2.1.1 → codevira-3.0.0}/indexer/outcome_tracker.py +115 -43
  28. {codevira-2.1.1 → codevira-3.0.0}/indexer/sqlite_graph.py +109 -222
  29. {codevira-2.1.1 → codevira-3.0.0}/indexer/treesitter_parser.py +178 -87
  30. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/__init__.py +1 -1
  31. codevira-3.0.0/mcp_server/_mcp_registry.py +145 -0
  32. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/_prompts.py +47 -0
  33. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/_repair_init.py +46 -22
  34. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/_safe_crash.py +0 -1
  35. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/auto_init.py +45 -14
  36. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/cli.py +712 -712
  37. codevira-3.0.0/mcp_server/cli_export.py +344 -0
  38. codevira-3.0.0/mcp_server/cli_graph.py +447 -0
  39. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/cli_hooks_admin.py +80 -7
  40. codevira-3.0.0/mcp_server/cli_init.py +296 -0
  41. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/cli_replay.py +73 -24
  42. codevira-3.0.0/mcp_server/cli_sync.py +109 -0
  43. codevira-3.0.0/mcp_server/cli_uninstall.py +478 -0
  44. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/hooks/post_tool_use.sh +8 -0
  45. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/hooks/pre_tool_use.sh +8 -0
  46. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/hooks/session_start.sh +8 -0
  47. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/hooks/stop.sh +8 -0
  48. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/hooks/user_prompt_submit.sh +9 -0
  49. codevira-3.0.0/mcp_server/data/rules/coding-standards-generic.md +60 -0
  50. codevira-3.0.0/mcp_server/data/rules/coding-standards-go.md +63 -0
  51. codevira-3.0.0/mcp_server/data/rules/coding-standards-typescript.md +56 -0
  52. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/decision_replay.py +125 -75
  53. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/doctor.py +287 -99
  54. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/__init__.py +21 -15
  55. codevira-3.0.0/mcp_server/engine/policies/__init__.py +45 -0
  56. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/policies/_signature_detect.py +0 -1
  57. codevira-3.0.0/mcp_server/engine/policies/post_edit_refresh.py +91 -0
  58. codevira-3.0.0/mcp_server/engine/policies/relevance_inject.py +458 -0
  59. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/runner.py +17 -10
  60. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/signals.py +120 -185
  61. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/token_meter.py +15 -6
  62. codevira-3.0.0/mcp_server/global_sync.py +96 -0
  63. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/http_server.py +119 -47
  64. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/ide_inject.py +130 -48
  65. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/log_retention.py +30 -9
  66. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/migrate.py +21 -5
  67. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/paths.py +65 -24
  68. codevira-3.0.0/mcp_server/prompts.py +77 -0
  69. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/roadmap_drift.py +1 -1
  70. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/server.py +627 -614
  71. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/setup_wizard.py +274 -137
  72. codevira-3.0.0/mcp_server/storage/__init__.py +43 -0
  73. codevira-3.0.0/mcp_server/storage/agents_md_generator.py +360 -0
  74. codevira-3.0.0/mcp_server/storage/atomic.py +268 -0
  75. codevira-3.0.0/mcp_server/storage/decisions_store.py +546 -0
  76. codevira-3.0.0/mcp_server/storage/digest.py +134 -0
  77. codevira-3.0.0/mcp_server/storage/fts5_index.py +430 -0
  78. codevira-3.0.0/mcp_server/storage/jsonl_store.py +390 -0
  79. codevira-3.0.0/mcp_server/storage/manifest.py +199 -0
  80. codevira-3.0.0/mcp_server/storage/outcomes_writer.py +295 -0
  81. codevira-3.0.0/mcp_server/storage/paths.py +160 -0
  82. codevira-3.0.0/mcp_server/storage/sessions_store.py +123 -0
  83. codevira-3.0.0/mcp_server/storage/token_estimator.py +106 -0
  84. codevira-3.0.0/mcp_server/tools/changesets.py +50 -0
  85. codevira-3.0.0/mcp_server/tools/check_conflict.py +286 -0
  86. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/tools/code_reader.py +24 -18
  87. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/tools/graph.py +153 -388
  88. codevira-3.0.0/mcp_server/tools/learning.py +678 -0
  89. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/tools/playbook.py +53 -11
  90. codevira-3.0.0/mcp_server/tools/roadmap.py +930 -0
  91. codevira-3.0.0/mcp_server/tools/search.py +296 -0
  92. {codevira-2.1.1 → codevira-3.0.0}/pyproject.toml +35 -13
  93. {codevira-2.1.1 → codevira-3.0.0}/tests/test_auto_init.py +119 -52
  94. {codevira-2.1.1 → codevira-3.0.0}/tests/test_call_edge_fk_safety.py +0 -2
  95. codevira-3.0.0/tests/test_check_conflict.py +293 -0
  96. codevira-3.0.0/tests/test_cli_graph.py +162 -0
  97. {codevira-2.1.1 → codevira-3.0.0}/tests/test_cli_replay.py +136 -47
  98. codevira-3.0.0/tests/test_cli_uninstall.py +475 -0
  99. {codevira-2.1.1 → codevira-3.0.0}/tests/test_cli_version.py +0 -1
  100. {codevira-2.1.1 → codevira-3.0.0}/tests/test_crash_logger.py +1 -3
  101. {codevira-2.1.1 → codevira-3.0.0}/tests/test_doctor.py +71 -34
  102. {codevira-2.1.1 → codevira-3.0.0}/tests/test_fk_safety_extended.py +0 -1
  103. {codevira-2.1.1 → codevira-3.0.0}/tests/test_fork_safety.py +0 -3
  104. {codevira-2.1.1 → codevira-3.0.0}/tests/test_gitignore.py +173 -80
  105. {codevira-2.1.1 → codevira-3.0.0}/tests/test_global_db.py +96 -19
  106. codevira-3.0.0/tests/test_global_sync.py +152 -0
  107. {codevira-2.1.1 → codevira-3.0.0}/tests/test_graph_generator.py +39 -36
  108. {codevira-2.1.1 → codevira-3.0.0}/tests/test_http_server.py +167 -119
  109. {codevira-2.1.1 → codevira-3.0.0}/tests/test_ide_inject.py +260 -30
  110. {codevira-2.1.1 → codevira-3.0.0}/tests/test_index_codebase.py +51 -43
  111. {codevira-2.1.1 → codevira-3.0.0}/tests/test_launchd.py +1 -2
  112. {codevira-2.1.1 → codevira-3.0.0}/tests/test_log_retention.py +0 -2
  113. {codevira-2.1.1 → codevira-3.0.0}/tests/test_migrate.py +54 -37
  114. {codevira-2.1.1 → codevira-3.0.0}/tests/test_outcome_tracker.py +1 -2
  115. {codevira-2.1.1 → codevira-3.0.0}/tests/test_paths.py +237 -28
  116. codevira-3.0.0/tests/test_prompts.py +88 -0
  117. {codevira-2.1.1 → codevira-3.0.0}/tests/test_record_decision.py +39 -34
  118. {codevira-2.1.1 → codevira-3.0.0}/tests/test_repair_init.py +0 -2
  119. {codevira-2.1.1 → codevira-3.0.0}/tests/test_roadmap_drift.py +0 -2
  120. codevira-3.0.0/tests/test_server.py +921 -0
  121. {codevira-2.1.1 → codevira-3.0.0}/tests/test_setup_wizard.py +298 -261
  122. {codevira-2.1.1 → codevira-3.0.0}/tests/test_sqlite_graph.py +530 -344
  123. {codevira-2.1.1 → codevira-3.0.0}/tests/test_sqlite_util.py +0 -1
  124. {codevira-2.1.1 → codevira-3.0.0}/tests/test_tools_code_reader.py +93 -26
  125. codevira-3.0.0/tests/test_tools_graph.py +667 -0
  126. codevira-3.0.0/tests/test_tools_learning.py +676 -0
  127. {codevira-2.1.1 → codevira-3.0.0}/tests/test_tools_playbook.py +0 -1
  128. {codevira-2.1.1 → codevira-3.0.0}/tests/test_tools_roadmap.py +128 -53
  129. {codevira-2.1.1 → codevira-3.0.0}/tests/test_treesitter_parser.py +0 -3
  130. {codevira-2.1.1 → codevira-3.0.0}/tests/test_watcher_circuit.py +0 -1
  131. codevira-2.1.1/PKG-INFO +0 -765
  132. codevira-2.1.1/README.md +0 -718
  133. codevira-2.1.1/codevira.egg-info/PKG-INFO +0 -765
  134. codevira-2.1.1/indexer/rule_learner.py +0 -186
  135. codevira-2.1.1/mcp_server/agents_md.py +0 -436
  136. codevira-2.1.1/mcp_server/cli_agents.py +0 -220
  137. codevira-2.1.1/mcp_server/cli_budget.py +0 -213
  138. codevira-2.1.1/mcp_server/cli_configure.py +0 -977
  139. codevira-2.1.1/mcp_server/cli_insights.py +0 -337
  140. codevira-2.1.1/mcp_server/data/templates/agents_md.tmpl +0 -3
  141. codevira-2.1.1/mcp_server/data/templates/canonical_block.md +0 -81
  142. codevira-2.1.1/mcp_server/data/templates/claude_md.tmpl +0 -3
  143. codevira-2.1.1/mcp_server/data/templates/copilot_instructions.tmpl +0 -3
  144. codevira-2.1.1/mcp_server/data/templates/cursor_rules.mdc.tmpl +0 -8
  145. codevira-2.1.1/mcp_server/data/templates/gemini_md.tmpl +0 -3
  146. codevira-2.1.1/mcp_server/data/templates/windsurfrules.tmpl +0 -3
  147. codevira-2.1.1/mcp_server/engine/intent_classifier.py +0 -214
  148. codevira-2.1.1/mcp_server/engine/policies/__init__.py +0 -44
  149. codevira-2.1.1/mcp_server/engine/policies/ai_promotion.py +0 -337
  150. codevira-2.1.1/mcp_server/engine/policies/cross_session.py +0 -363
  151. codevira-2.1.1/mcp_server/engine/policies/intent_inference.py +0 -421
  152. codevira-2.1.1/mcp_server/engine/policies/live_style.py +0 -445
  153. codevira-2.1.1/mcp_server/engine/policies/scope_contract.py +0 -362
  154. codevira-2.1.1/mcp_server/engine/promotion_score.py +0 -208
  155. codevira-2.1.1/mcp_server/engine/scope_contract.py +0 -201
  156. codevira-2.1.1/mcp_server/global_sync.py +0 -187
  157. codevira-2.1.1/mcp_server/prompts.py +0 -136
  158. codevira-2.1.1/mcp_server/tools/_decision_embeddings.py +0 -314
  159. codevira-2.1.1/mcp_server/tools/changesets.py +0 -225
  160. codevira-2.1.1/mcp_server/tools/learning.py +0 -591
  161. codevira-2.1.1/mcp_server/tools/roadmap.py +0 -606
  162. codevira-2.1.1/mcp_server/tools/search.py +0 -507
  163. codevira-2.1.1/tests/test_cli.py +0 -1423
  164. codevira-2.1.1/tests/test_cli_agents.py +0 -375
  165. codevira-2.1.1/tests/test_cli_configure.py +0 -1075
  166. codevira-2.1.1/tests/test_cli_insights.py +0 -159
  167. codevira-2.1.1/tests/test_decision_embeddings.py +0 -218
  168. codevira-2.1.1/tests/test_global_sync.py +0 -325
  169. codevira-2.1.1/tests/test_prompts.py +0 -101
  170. codevira-2.1.1/tests/test_retire_rule.py +0 -271
  171. codevira-2.1.1/tests/test_rule_learner.py +0 -411
  172. codevira-2.1.1/tests/test_server.py +0 -1006
  173. codevira-2.1.1/tests/test_tools_changesets.py +0 -424
  174. codevira-2.1.1/tests/test_tools_graph.py +0 -926
  175. codevira-2.1.1/tests/test_tools_learning.py +0 -847
  176. codevira-2.1.1/tests/test_tools_search.py +0 -489
  177. {codevira-2.1.1 → codevira-3.0.0}/LICENSE +0 -0
  178. {codevira-2.1.1 → codevira-3.0.0}/MANIFEST.in +0 -0
  179. {codevira-2.1.1 → codevira-3.0.0}/agents/builder.md +0 -0
  180. {codevira-2.1.1 → codevira-3.0.0}/agents/developer.md +0 -0
  181. {codevira-2.1.1 → codevira-3.0.0}/agents/documenter.md +0 -0
  182. {codevira-2.1.1 → codevira-3.0.0}/agents/orchestrator.md +0 -0
  183. {codevira-2.1.1 → codevira-3.0.0}/agents/planner.md +0 -0
  184. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/01-code-review.md +0 -0
  185. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/02-adversarial-fix-review.md +0 -0
  186. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/03-cross-module-impact.md +0 -0
  187. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/06-doc-drift.md +0 -0
  188. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/07-security-audit.md +0 -0
  189. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/12-llm-redteam.md +0 -0
  190. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/13-multi-ide-schema.md +0 -0
  191. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/22-competitor-benchmark.md +0 -0
  192. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/README.md +0 -0
  193. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/tier2-scripts.md +0 -0
  194. {codevira-2.1.1 → codevira-3.0.0}/agents/qa/tier3-manual.md +0 -0
  195. {codevira-2.1.1 → codevira-3.0.0}/agents/reviewer.md +0 -0
  196. {codevira-2.1.1 → codevira-3.0.0}/agents/tester.md +0 -0
  197. {codevira-2.1.1 → codevira-3.0.0}/codevira.egg-info/dependency_links.txt +0 -0
  198. {codevira-2.1.1 → codevira-3.0.0}/codevira.egg-info/entry_points.txt +0 -0
  199. {codevira-2.1.1 → codevira-3.0.0}/codevira.egg-info/top_level.txt +0 -0
  200. {codevira-2.1.1 → codevira-3.0.0}/config.example.yaml +0 -0
  201. {codevira-2.1.1 → codevira-3.0.0}/docs/alpha-tester-invites.md +0 -0
  202. {codevira-2.1.1 → codevira-3.0.0}/docs/demo/README.md +0 -0
  203. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/00-engine.md +0 -0
  204. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/01-decision-lock.md +0 -0
  205. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/02-anti-regression.md +0 -0
  206. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/03-scope-contract.md +0 -0
  207. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/04-blast-radius.md +0 -0
  208. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/05-cross-session.md +0 -0
  209. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/06-token-budget.md +0 -0
  210. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/07-live-style.md +0 -0
  211. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/08-decision-replay.md +0 -0
  212. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/09-intent-inference.md +0 -0
  213. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/10-ai-promotion.md +0 -0
  214. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/README.md +0 -0
  215. {codevira-2.1.1 → codevira-3.0.0}/docs/heroes/pillar-1-setup.md +0 -0
  216. {codevira-2.1.1 → codevira-3.0.0}/docs/hn-launch-day.md +0 -0
  217. {codevira-2.1.1 → codevira-3.0.0}/docs/internal/competitive-landscape.md +0 -0
  218. {codevira-2.1.1 → codevira-3.0.0}/docs/linkedin-post-ai-agent-memory.md +0 -0
  219. {codevira-2.1.1 → codevira-3.0.0}/docs/local-pypi-https.md +0 -0
  220. {codevira-2.1.1 → codevira-3.0.0}/docs/release-process.md +0 -0
  221. {codevira-2.1.1 → codevira-3.0.0}/docs/v2-completion-plan.md +0 -0
  222. {codevira-2.1.1 → codevira-3.0.0}/docs/v2-execution-log.md +0 -0
  223. {codevira-2.1.1 → codevira-3.0.0}/docs/v2-master-plan.md +0 -0
  224. {codevira-2.1.1 → codevira-3.0.0}/docs/vs-other-memory-tools.md +0 -0
  225. {codevira-2.1.1 → codevira-3.0.0}/graph/_schema.yaml +0 -0
  226. {codevira-2.1.1 → codevira-3.0.0}/indexer/__init__.py +0 -0
  227. {codevira-2.1.1 → codevira-3.0.0}/indexer/_dedupe_migration.py +0 -0
  228. {codevira-2.1.1 → codevira-3.0.0}/indexer/_fork_safety.py +0 -0
  229. {codevira-2.1.1 → codevira-3.0.0}/indexer/_sqlite_util.py +0 -0
  230. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/__main__.py +0 -0
  231. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/_ghost_check.py +0 -0
  232. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/_project_inventory.py +0 -0
  233. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/cli_projects.py +0 -0
  234. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/crash_logger.py +0 -0
  235. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/__init__.py +0 -0
  236. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/agents/builder.md +0 -0
  237. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/agents/developer.md +0 -0
  238. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/agents/documenter.md +0 -0
  239. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/agents/orchestrator.md +0 -0
  240. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/agents/planner.md +0 -0
  241. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/agents/reviewer.md +0 -0
  242. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/agents/tester.md +0 -0
  243. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/config.example.yaml +0 -0
  244. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/coding-standards.md +0 -0
  245. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/engineering-excellence.md +0 -0
  246. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/git-cicd-governance.md +0 -0
  247. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/git_commits.md +0 -0
  248. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/incremental-updates.md +0 -0
  249. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/master_rule.md +0 -0
  250. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/multi-language.md +0 -0
  251. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/persistence.md +0 -0
  252. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/resilience-observability.md +0 -0
  253. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/smoke-testing.md +0 -0
  254. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/data/rules/testing-standards.md +0 -0
  255. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/detect.py +0 -0
  256. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/demo_policy.py +0 -0
  257. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/events.py +0 -0
  258. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/policies/anti_regression.py +0 -0
  259. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/policies/blast_radius.py +0 -0
  260. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/policies/decision_lock.py +0 -0
  261. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/policies/token_budget.py +0 -0
  262. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/policy.py +0 -0
  263. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/wiring/__init__.py +0 -0
  264. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/wiring/claude_code_hooks.py +0 -0
  265. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/engine/wiring/mcp_dispatch.py +0 -0
  266. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/gitignore.py +0 -0
  267. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/launchd.py +0 -0
  268. {codevira-2.1.1 → codevira-3.0.0}/mcp_server/tools/__init__.py +0 -0
  269. {codevira-2.1.1 → codevira-3.0.0}/rules/coding-standards.md +0 -0
  270. {codevira-2.1.1 → codevira-3.0.0}/rules/engineering-excellence.md +0 -0
  271. {codevira-2.1.1 → codevira-3.0.0}/rules/git-cicd-governance.md +0 -0
  272. {codevira-2.1.1 → codevira-3.0.0}/rules/git_commits.md +0 -0
  273. {codevira-2.1.1 → codevira-3.0.0}/rules/incremental-updates.md +0 -0
  274. {codevira-2.1.1 → codevira-3.0.0}/rules/master_rule.md +0 -0
  275. {codevira-2.1.1 → codevira-3.0.0}/rules/persistence.md +0 -0
  276. {codevira-2.1.1 → codevira-3.0.0}/rules/resilience-observability.md +0 -0
  277. {codevira-2.1.1 → codevira-3.0.0}/rules/smoke-testing.md +0 -0
  278. {codevira-2.1.1 → codevira-3.0.0}/rules/testing-standards.md +0 -0
  279. {codevira-2.1.1 → codevira-3.0.0}/setup.cfg +0 -0
  280. {codevira-2.1.1 → codevira-3.0.0}/tests/test__prompts.py +0 -0
  281. {codevira-2.1.1 → codevira-3.0.0}/tests/test_chunker.py +0 -0
  282. {codevira-2.1.1 → codevira-3.0.0}/tests/test_cli_projects.py +0 -0
  283. {codevira-2.1.1 → codevira-3.0.0}/tests/test_dedupe_migration.py +0 -0
  284. {codevira-2.1.1 → codevira-3.0.0}/tests/test_detect.py +0 -0
  285. {codevira-2.1.1 → codevira-3.0.0}/tests/test_ghost_check.py +0 -0
  286. {codevira-2.1.1 → codevira-3.0.0}/tests/test_hook_resilience.py +0 -0
@@ -9,7 +9,797 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
9
9
 
10
10
  ---
11
11
 
12
- ## [Unreleased]
12
+ ## [3.0.0] — 2026-05-27 — Lean, audited, opinionated
13
+
14
+ ### Hardened (RC audit — rounds 2 + 3, pre-publish)
15
+
16
+ > Three rounds of audit ran against the v3.0.0 release candidate
17
+ > before publishing. Round 1 was the surface-cut + dead-code sweep
18
+ > already recorded in the 3.0.0 entry below. Rounds 2 and 3 were
19
+ > "what could silently break in production?" — and surfaced a
20
+ > family of concurrent-write bugs in the storage layer that the
21
+ > structured unit tests didn't catch.
22
+
23
+ - **NEW `mcp_server/storage/atomic.py`** — single canonical source
24
+ for crash-safe file writes + Posix/Windows file locks. Every
25
+ storage / tool / cli module that touches the on-disk product
26
+ state now goes through this helper. Public API:
27
+ `atomic_write_text(path, content, *, mode=None)`,
28
+ `atomic_write_bytes(path, content, *, mode=None)`, and
29
+ `file_lock(path, *, exclusive=True)` (context manager — Posix
30
+ `fcntl.flock` + Windows sentinel-file fallback). Replaces 5
31
+ hand-rolled copies that had drifted (manifest, digest,
32
+ agents_md_generator, setup_wizard, jsonl_store). 11 unit tests
33
+ pin the contract (basic write, utf-8, overwrite, mkdir, mode
34
+ bits, no-leaked-tmp, 50-thread concurrency, binary, in-process
35
+ serialization, auto-anchor, exception release, Windows-sentinel
36
+ codepath via monkey-patched `sys.platform`).
37
+
38
+ - **Concurrent-write race fixes (rounds 2 + 3).** Two distinct
39
+ race shapes were caught under 50-thread stress:
40
+ - *Atomic-rename race* (round 2). `manifest.yaml`, `digest.jsonl`,
41
+ and `AGENTS.md` writers used a fixed `<path>.tmp` suffix; two
42
+ threads' `os.replace()` calls raced on the rename target,
43
+ producing `FileNotFoundError: <path>.tmp` warnings. The
44
+ decisions themselves still landed safely (`jsonl_store.append`
45
+ uses fcntl-locked I/O); only the CACHE files lost data. Fixed
46
+ by per-write unique tmp via `tempfile.mkstemp` (and now
47
+ consolidated through `storage/atomic`).
48
+ - *Lost-update race* (round 2 caught manifest; round 3 caught
49
+ roadmap). Read-modify-write paths (`manifest.incremental_add`,
50
+ `roadmap._save_roadmap`) had no lock — 50 concurrent updates
51
+ landed as ~37 because the last save() won. Fixed by
52
+ `atomic.file_lock` around the whole read-modify-write. Three
53
+ new regression tests in `tests/storage/test_concurrent_writes.py`
54
+ pin the invariants: zero rename warnings under 50-thread
55
+ record_decision, manifest counts match JSONL, roadmap phases
56
+ all land. P9 invariant test (corrupt manifest → decision
57
+ still persists in JSONL) added too.
58
+
59
+ - **Cross-process safety proved** (`tests/storage/test_cross_process_writes.py`).
60
+ Round-2 fixes were thread-safe but not yet proven process-safe —
61
+ two `codevira` MCP server processes (Claude Desktop + Cursor
62
+ running together) racing on the same project's roadmap could
63
+ still lose updates if the `fcntl.flock` contract didn't survive
64
+ process boundaries. Two new tests spawn 20 subprocesses via
65
+ `multiprocessing.spawn` and assert: 20 concurrent
66
+ `decisions_store.record` → 20 unique IDs; 20 concurrent
67
+ `roadmap.add_phase` → all 20 phases land in roadmap.yaml.
68
+
69
+ - **Engine policy storage-correctness audit.** Each of the 6 active
70
+ engine policies (`anti_regression`, `blast_radius`,
71
+ `decision_lock`, `post_edit_refresh`, `relevance_inject`,
72
+ `token_budget`) was read line-by-line to confirm it reads from
73
+ the v3.0.0 storage layer, not the legacy SQLiteGraph paths.
74
+ One drift found: `signals.graph` round-2 fix added v3.0.0
75
+ `.codevira-cache/graph.sqlite` as the priority-1 resolution
76
+ tier — pre-fix it only checked v1.5 / v1.6 paths, structurally
77
+ silencing `BlastRadiusVeto` and the `DecisionLock` no-rationale
78
+ branch on every v3.0.0 project. Similarly `signals.decisions`
79
+ was rewired to read JSONL (was reading a SQL table that no
80
+ longer exists in v3.0.0).
81
+
82
+ - **MCP tools/list inputSchema audit.** All 23 surfaced MCP tools
83
+ validated for schema consistency (every required field in
84
+ properties, every tool has a description, every schema is
85
+ `type: object`). Zero issues.
86
+
87
+ - **NEW `scripts/chaos_smoke.py`** — adversarial probe of the
88
+ storage layer with 8 attack categories / 29 sub-tests (null
89
+ bytes, 1 MB decision text, path traversal in `file_path`,
90
+ control chars, SIGKILL during fcntl.flock, manually-corrupted
91
+ JSONL/YAML/AGENTS.md, 200-thread mixed-op storm, 20-thread
92
+ lock contention, symlink traversal via
93
+ `AGENTS.md → /etc/passwd`, 7 malformed JSON-RPC payloads to
94
+ `codevira serve`, read-only `.codevira/` dir). Result on
95
+ current commit: 29 PASS / 0 FAIL. Notable findings (not bugs,
96
+ design choices worth surfacing):
97
+ - All adversarial decision inputs are accepted (no validation
98
+ today; trust-the-agent design). v3.1 candidate for sanitization.
99
+ - Symlink safety is automatic: `atomic.os.replace` replaces the
100
+ symlink itself, not the target, so an attacker who plants
101
+ `AGENTS.md → /etc/passwd` can't escape the project root.
102
+ - fcntl.flock survives SIGKILL of the holder (kernel reaps
103
+ fd-bound locks).
104
+
105
+ - **`check_conflict` asymmetric-overlap detector for contradictions
106
+ against `do_not_revert` decisions.** The original v2.2.0 implementation
107
+ used pure symmetric Jaccard similarity with a 0.60 threshold — which
108
+ misses the common contradiction shape where a terse new decision
109
+ shares 3 of its 4 content tokens with a longer protected decision
110
+ (Jaccard = 3/9 = 0.333, below threshold; overlap coefficient =
111
+ 3/min(4,8) = 0.75, above threshold). Caught by the AgentStore
112
+ system test (`scripts/system_test_agentstore.py::A9`).
113
+
114
+ Fix adds an asymmetric overlap-coefficient path that fires ONLY
115
+ for candidates with `do_not_revert=True` AND with at least 3 shared
116
+ tokens AND with symmetric Jaccard below 0.60 (the
117
+ re-affirmation filter — re-recording a protected decision verbatim
118
+ still hits the duplicate path, not the new asymmetric path).
119
+ Duplicate detection itself (against any decision) stays symmetric +
120
+ conservative (Jaccard ≥ 0.60) — the change is conflict-specific.
121
+
122
+ Response shape adds `match_shape` (`"duplicate"` |
123
+ `"asymmetric-conflict"`), `jaccard`, `overlap_coefficient`,
124
+ `shared_tokens` per match entry + a top-level `thresholds` dict.
125
+ Existing `threshold_used` field preserved for v2.x callers.
126
+ 17 new unit tests in `tests/test_check_conflict.py` pin both
127
+ regimes + the re-affirmation filter.
128
+
129
+ - **Repointed 11 more unguarded writes at `storage.atomic`** —
130
+ the round-3 write-site sweep found `auto_init` (config.yaml +
131
+ metadata.json), `cli_init` (config.yaml + enforcement.yaml +
132
+ .gitignore), `http_server` (bearer token, +0o600 mode),
133
+ `cli_uninstall` (settings.json + AGENTS.md, 3 sites),
134
+ `cli_hooks_admin` (settings.json — was fixed-suffix tmp race),
135
+ `cli.py` (legacy `cmd_configure` + git hook write), `cli_export`
136
+ (JSON + SQL exports — both had fixed-suffix tmp races),
137
+ `cli_replay`, `log_retention`, `migrate`, and
138
+ `indexer/graph_generator` (roadmap stub). All now crash-safe via
139
+ the shared helper.
140
+
141
+ - **Doctor dogfooded against a real project + a fresh init.**
142
+ Fresh `codevira init` followed by `codevira doctor` = 13 pass /
143
+ 1 warn (pre-existing ghost dirs from earlier testing) / 0 fail.
144
+
145
+ ### Added (2026-05-26 dogfood batch)
146
+
147
+ - **`codevira graph`** — render the project's decision memory as a
148
+ single self-contained, interactive HTML file (nodes = decisions,
149
+ edges = supersedes lineage) with a client-side query/filter box and
150
+ details panel. Zero runtime dependencies, no server, works offline;
151
+ reads the canonical `.codevira/decisions.jsonl`. Inlined JSON escapes
152
+ `<` so decision text can't break out of the data island. Output
153
+ defaults to `.codevira-cache/memory-graph.html`. (D000016)
154
+ - **`summary_only` on `list_decisions`** — parity with
155
+ `search_decisions`: returns the tiny `{id, summary, do_not_revert}`
156
+ shape and takes precedence over `full`. (D000015)
157
+ - **`CODEVIRA_TOOL_PROFILE=lean`** — opt-in environment variable that
158
+ trims the advertised MCP `tools/list` from 24 to 11 daily-driver
159
+ tools (~46%, ~1.9K fewer tokens per session). Default advertises all
160
+ tools; hidden tools still work when called explicitly. (D000018)
161
+
162
+ ### Fixed (2026-05-26 dogfood batch)
163
+
164
+ - **`ensure_dirs()` refuses a forbidden project root** ($HOME / system
165
+ dirs) on the v3.0.0 JSONL write path — the WRITE-side counterpart of
166
+ the guard `get_data_dir()` already applied. Closes a trap where a
167
+ *global* MCP config (e.g. Claude Desktop, no cwd, no
168
+ `CODEVIRA_PROJECT_DIR`) resolved the root to `/` and silently created
169
+ `/.codevira` or `$HOME/.codevira`. Raises a WHAT+WHY+FIX error naming
170
+ `CODEVIRA_PROJECT_DIR`; read paths stay graceful. (D000012)
171
+
172
+ ### Changed (2026-05-26 dogfood batch)
173
+
174
+ - Trimmed the longest MCP tool description (`record_decision`) to cut
175
+ per-session token cost while preserving its `do_not_revert` +
176
+ `supersede`/`set_decision_flag` guidance. (D000018)
177
+
178
+ ### Known limitations (shipping in 3.0.0; tracked for a later release)
179
+
180
+ - **Graph spec vs implementation drift.** `paths.graph_cache_path()`
181
+ documents the v3.0.0 spec location as
182
+ `<project>/.codevira-cache/graph.sqlite`, but `indexer/` and
183
+ `tools/graph.py` still write to / read from
184
+ `<data_dir>/graph/graph.db` (the legacy v1.6 centralized
185
+ location). Runtime behavior is correct — everyone agrees on the
186
+ centralized location and `signals._load_graph()` finds it via
187
+ the fallback chain. The spec-truthfulness gap should be
188
+ reconciled in v3.1 with a migration step for existing installs.
189
+
190
+ - **Decision input sanitization is deliberately absent.** Null
191
+ bytes, 1 MB text, path traversal in `file_path`, control
192
+ characters, and empty strings are accepted today. The chaos
193
+ harness surfaced this; a v3.1 hardening pass could add
194
+ per-field validation without breaking the trust-the-agent
195
+ default.
196
+
197
+ - **Cross-process flock tested on macOS only.** The
198
+ `multiprocessing.spawn` context is the same on Linux CI, but
199
+ the cross-process test has not been exercised on Windows
200
+ (where the helper uses the sentinel-file fallback instead of
201
+ fcntl).
202
+
203
+ - **`relevance_inject` can surface weakly-related decisions on
204
+ short prompts.** The current SessionStart / UserPromptSubmit
205
+ injection scores tag + file + FTS5-BM25; with the v3.0 default
206
+ `min_score=0.10`, the top FTS5 hit alone (~0.10) is enough to
207
+ clear the gate on prompts with no tag or file overlap. Tightening
208
+ the gate naively breaks the core cross-tool wedge
209
+ (`tests/e2e/test_cross_tool_universality.py`) — FTS-only recall
210
+ IS the keyword-search path for tagless / file-less queries from
211
+ Cursor / Windsurf / Antigravity. A proper fix needs a
212
+ precision/recall benchmark with a corpus of real prompts +
213
+ decisions and a multi-prompt e2e test added BEFORE the threshold
214
+ change. Deferred to v3.0.1.
215
+
216
+ ---
217
+
218
+ ### Initial 3.0.0 RC milestone (2026-05-22)
219
+
220
+ > **Major version bump.** This is the biggest API contraction since
221
+ > v2.0 shipped: 21 MCP tools deleted, 8 CLI subcommands deleted,
222
+ > per-IDE nudge file matrix collapsed to AGENTS.md only, IDE
223
+ > detection hardened from "directory exists" to "binary on PATH +
224
+ > valid config file." The cuts are subtractive — any v2.x user who
225
+ > upgrades will lose surface they MAY have been using. SemVer
226
+ > requires the major bump.
227
+ >
228
+ > The driver: a 2026-05-22 surface-cut audit (see
229
+ > `docs/audit-2026-05-22.md`) traced 5 categories of user
230
+ > complaints to overgrown surface, false-positive IDE detections,
231
+ > and "junk left behind" after uninstall. v3.0.0 fixes all five
232
+ > categories. See `docs/surface-cuts-2026-05-22.md` for the
233
+ > per-item kill list.
234
+ >
235
+ > v3.0.0 includes everything in the unreleased v2.2.0+ work plus
236
+ > two additional pieces:
237
+ > - Full dead-code sweep across the whole repo (~3,800 lines
238
+ > removed) after the surface cuts surfaced obviously-dead
239
+ > internal helpers
240
+ > - IDE auto-detection hardened: strong signals only, ``--force``
241
+ > escape hatch, no more silent-filter on `--ide` for
242
+ > undetected IDEs
243
+
244
+ ### Added
245
+
246
+ - **`codevira uninstall` command (Phase 5).** Reverses every system
247
+ write made by `codevira init` / `codevira setup`: drops the MCP
248
+ entry from `~/.claude.json`, deletes `~/.claude/hooks/codevira-*.sh`,
249
+ strips codevira-tagged registrations from `~/.claude/settings.json`,
250
+ removes per-project `.codevira/` + `.codevira-cache/` dirs, and
251
+ strips the codevira marker block from each project's `AGENTS.md`
252
+ (preserves user content outside the markers byte-for-byte). Optional
253
+ `--keep-data` skips per-user `~/.codevira/`. Closes the audit's
254
+ "uninstalling left junk" complaint — `pipx uninstall codevira` used
255
+ to leave ~15 system touch points behind.
256
+
257
+ - **`codevira setup --force`.** Escape hatch for the rare case where
258
+ codevira's IDE detector misses an install (portable binary not on
259
+ PATH, non-standard config location). Without ``--force``, passing
260
+ `--ide cursor` on a machine where Cursor isn't auto-detected raises
261
+ a clear error pointing at the flag. The v2.x silent-filter behavior
262
+ (which made ``setup --ide cursor`` exit 0 with no output and no
263
+ config on Cursor-less machines) is gone.
264
+
265
+ - **Legacy per-IDE nudge back-compat sweep** in `codevira uninstall`:
266
+ for upgraders from v2.1.x, also strips codevira marker blocks from
267
+ `CLAUDE.md`, `GEMINI.md`, `.cursor/rules/codevira.mdc`,
268
+ `.windsurfrules`, `.github/copilot-instructions.md`.
269
+
270
+ - **`record_decision` MCP tool now forwards `tags` and `force`** —
271
+ these were silently dropped by the dispatch layer in v2.x; now
272
+ agents' tag intent actually persists when loop-calling the endpoint.
273
+
274
+ ### Changed
275
+
276
+ - **IDE auto-detection hardened (mcp_server/ide_inject.py).** Each
277
+ detector now requires a STRONG signal: either the IDE's binary on
278
+ PATH, or a verified config file (not just a parent dir). v2.x had
279
+ three WEAK detectors (Claude Desktop, Antigravity, Continue.dev)
280
+ that fired on the presence of an empty directory — false positives
281
+ that caused codevira to write MCP config for IDEs the user never
282
+ installed. v3.0.0 cross-checks.
283
+
284
+ | IDE | v2.x signal | v3.0.0 signal |
285
+ |-----------------|--------------------------------|--------------------------------------------------|
286
+ | Claude Code | `.claude/ OR claude on PATH` | `claude on PATH` |
287
+ | Claude Desktop | parent dir of config exists | config FILE exists AND parses as JSON |
288
+ | Cursor | `~/.cursor/ OR cursor on PATH` | `~/.cursor/ AND (mcp.json OR cursor on PATH)` |
289
+ | Windsurf | `~/.windsurf/ OR ~/.codeium/…` | actual mcp_config.json exists in either location |
290
+ | Antigravity | `~/.gemini/ exists` | `~/.gemini/antigravity/mcp_config.json exists` |
291
+
292
+ - **`setup_wizard.detect_targets`** raises a clear ``ValueError`` on
293
+ `--ide <name>` for known IDEs that weren't auto-detected (use
294
+ `--force` to override). v2.x silently filtered the request, which
295
+ produced the worst possible UX: command exit 0 with no output.
296
+
297
+ - **Per-IDE nudge files collapsed to AGENTS.md only.** The setup
298
+ wizard now writes exactly one nudge file (`AGENTS.md` via the new
299
+ `mcp_server.storage.agents_md_generator`) regardless of which IDEs
300
+ are detected. Per-IDE duplicates (`CLAUDE.md` / `GEMINI.md` /
301
+ `.cursor/rules/codevira.mdc` / `.windsurfrules` /
302
+ `.github/copilot-instructions.md`) were pure surface bloat — every
303
+ modern AI tool reads AGENTS.md natively.
304
+
305
+ - **`codevira doctor`'s `nudge_files` check** rewritten to verify
306
+ AGENTS.md only; fix command updated to `codevira sync`.
307
+
308
+ - **`mcp_server.global_sync`** gutted from a 187-line bidirectional
309
+ preference + rule sync to a ~90-LOC project-registry helper. New
310
+ primary entry: ``register_current_project()``. v2.x
311
+ ``import_global_to_project`` kept as a back-compat alias.
312
+
313
+ - **MCP prompt library** pruned from 5 templates to 1
314
+ (``onboard_session``). The 4 deleted templates referenced MCP tools
315
+ that the audit deleted (analyze_changes, find_hotspots,
316
+ get_learned_rules, get_preferences, get_project_maturity,
317
+ list_open_changesets, export_graph, list_nodes, search_codebase).
318
+
319
+ ### Removed
320
+
321
+ **MCP tools (46 → 24, –48%):**
322
+
323
+ - Batch 1 — Changesets:
324
+ `start_changeset`, `update_changeset_progress`, `complete_changeset`,
325
+ `list_open_changesets` (entire feature; ~zero real users).
326
+ - Batch 2 — Preferences + learned rules:
327
+ `get_preferences`, `get_learned_rules`, `retire_rule` (auto-extracted
328
+ signals were noise more than signal).
329
+ - Batch 4a — Vestigial graph helpers:
330
+ `update_node`, `list_nodes`, `add_node`, `export_graph`,
331
+ `get_graph_diff`, `get_decision_confidence`, `get_project_maturity`,
332
+ `analyze_changes`, `find_hotspots`.
333
+ - Batch 6 — Redundant / FOLD candidates:
334
+ `record_decisions` (batch — loop single-record instead),
335
+ `write_session_logs` (batch — same),
336
+ `mark_decision_protected` (use
337
+ `supersede_decision(..., do_not_revert=True)` for the same flip +
338
+ audit trail),
339
+ `refresh_index` (chromadb-era; `refresh_graph` is the still-active
340
+ code-graph refresh tool),
341
+ `get_full_roadmap` (duplicate of `get_roadmap` with a flag).
342
+
343
+ **CLI subcommands (23 → 15, –35%, batch 4b):**
344
+
345
+ - `heal`, `budget`, `agents`, `hooks`, `register`, `configure`,
346
+ `report`, `calibrate`, `insights`. Folded into `init` / `setup` /
347
+ `doctor` where they had real successors; deleted outright where
348
+ they had ~zero real usage.
349
+
350
+ **Engine policies (10 → 6, –40%, batch 3):**
351
+
352
+ - `LiveStyleEnforcement`, `AIPromotionScore`, `ProactiveIntentInference`,
353
+ `ProactiveScopeContractLock`. Default policy set:
354
+ `BlastRadiusVeto`, `DecisionLock`, `RelevanceInject`,
355
+ `TokenBudgetPersist`, `AntiRegression`, `PostEditGraphRefresh`.
356
+
357
+ **Per-project nudge files (6 → 1, –83%, batch 5):**
358
+
359
+ - `mcp_server/agents_md.py` (the legacy per-IDE nudge writer) + 7
360
+ templates (`claude_md.tmpl`, `cursor_rules.mdc.tmpl`,
361
+ `windsurfrules.tmpl`, `gemini_md.tmpl`,
362
+ `copilot_instructions.tmpl`, `agents_md.tmpl`,
363
+ `canonical_block.md`). The v3.0.0 `storage/agents_md_generator.py`
364
+ generates AGENTS.md content directly from `decisions.jsonl`.
365
+
366
+ **Dead-code sweep (after audit deletions):**
367
+
368
+ - `indexer/rule_learner.py` (~250 LOC; consumed only by deleted MCP
369
+ tools).
370
+ - 7 dead functions in `mcp_server/tools/graph.py` (~408 LOC).
371
+ - 7 dead methods in `indexer/sqlite_graph.py` (preferences +
372
+ learned_rules + project_maturity tables stay in the schema for
373
+ back-compat but are never written or read).
374
+ - `mcp_server/tools/learning.py::get_project_maturity` +
375
+ `_compute_maturity_score` / `_maturity_level` / `_maturity_hint`.
376
+ - `mcp_server/engine/signals.py::SignalContext.preferences`
377
+ (was broken — imported a non-existent symbol; v2.x would have
378
+ crashed on first call from any consuming policy).
379
+ - `mcp_server/engine/signals.py::SignalContext.outcomes` +
380
+ `.learned_rules` (no-op stubs after batch 3).
381
+ - 15 dead test classes across the test suite (matched to deleted
382
+ features).
383
+
384
+ **IDE detector entries:**
385
+
386
+ - `continue.dev` and `aider` no longer in the detector output. Neither
387
+ had a codevira-configurable integration path; their entries existed
388
+ only as advisory listings (pure noise).
389
+
390
+ ### Counts (v2.1.x → v3.0.0)
391
+
392
+ | Surface | v2.1.x | v3.0.0 | Δ |
393
+ |---------------------------------|--------------|------------|--------|
394
+ | MCP tools | 46 | 24 | -48% |
395
+ | CLI subcommands | 23 | 15 | -35% |
396
+ | Engine policies | 10 | 6 | -40% |
397
+ | Per-project nudge files | 6 | 1 | -83% |
398
+ | Templates shipped in the wheel | 7 | 0 | n/a |
399
+ | MCP prompt library | 5 | 1 | -80% |
400
+ | Pipx install size | ~450 MB | ~83 MB | -82% |
401
+ | MCP server startup | 1–3 s | <100 ms | -97% |
402
+ | Tests (passing) | 2354 | 1870 + 72 | rebased |
403
+
404
+ ### Migration notes
405
+
406
+ Most deletions have a clear successor in this file's `### Removed`
407
+ sections. Two with non-obvious mappings:
408
+
409
+ - **From `mark_decision_protected(id, True)`** →
410
+ `supersede_decision(old_id=id, new_decision=<text>, reason=<why>,
411
+ do_not_revert=True)`. The supersede path gives you the audit trail
412
+ (why you flipped the flag) that the standalone tool didn't.
413
+ - **From `record_decisions(decisions=[...])`** → for d in decisions:
414
+ `record_decision(**d)`. The audit found agents called single-record
415
+ in practice anyway, so this is the actually-used pattern.
416
+
417
+ The `codevira uninstall` command picks up any legacy artifacts on
418
+ disk from earlier versions (per-IDE nudge files, etc.) so users
419
+ upgrading don't need to hand-clean.
420
+
421
+ For IDE detection changes: if you previously relied on codevira
422
+ configuring Claude Desktop / Antigravity / Cursor based on the
423
+ presence of a directory, you may now need to either:
424
+ (a) actually install the IDE so the binary is on PATH (or so the
425
+ relevant config file exists), OR
426
+ (b) re-run `codevira setup --ide <name> --force` to override the
427
+ detector and configure anyway.
428
+
429
+ The strict mode is the right default. The audit found false-positive
430
+ configurations (codevira injected into IDEs the user never installed)
431
+ were a real churn driver — silently writing config for absent apps
432
+ makes users distrust the tool.
433
+
434
+ ---
435
+
436
+ ## [2.2.0] — 2026-05-20 — Lean (in-repo, no chromadb, token-optimized)
437
+
438
+ > The biggest architectural change since v2.0. Decisions move from
439
+ > SQLite into git-tracked JSONL in your repo. ChromaDB / sentence-
440
+ > transformers / torch removed entirely; tree-sitter-language-pack
441
+ > (351 MB) replaced by 4 individual grammar packages (TS / JS / Go /
442
+ > Rust) totaling ~5 MB. Pipx install drops from ~450 MB (v2.1.2 with
443
+ > the full grammar stack) to ~85 MB; MCP server starts in <100ms;
444
+ > per-project disk drops from 40-80 MB to ~1-2 MB. See
445
+ > `docs/plans/v2.2.0.md` for the full plan.
446
+
447
+ ### Changed (architecture)
448
+
449
+ - **Decision storage moved to `<repo>/.codevira/decisions.jsonl`** —
450
+ human-readable, git-committed, team-shareable. Visible in `git diff`
451
+ as one-decision-per-line. Replaces v2.1.x's `~/.codevira/projects/
452
+ <key>/graph/graph.db` SQLite blob for decisions (the code graph
453
+ stays in SQLite cache).
454
+ - **Sessions / preferences / learned_rules / changesets / outcomes /
455
+ roadmap also move to `.codevira/*.jsonl`**. The `.codevira-cache/`
456
+ dir (gitignored) holds the FTS5 index + code-graph SQLite + hash
457
+ cache (rebuildable by `codevira sync` / `codevira index`).
458
+ - **AGENTS.md auto-generated** with hard **5 KB cap**. Marker-bounded
459
+ (`<!-- codevira:begin -->` / `<!-- codevira:end -->`) so user-edited
460
+ content outside is preserved byte-for-byte. Every `record_decision`
461
+ regenerates it synchronously. Other AI tools (Copilot, Codex,
462
+ Cursor, Gemini, Factory, Amp, Windsurf, Zed, RooCode, Jules) read
463
+ AGENTS.md natively — codevira's decisions are now portable.
464
+
465
+ ### Removed (dropped from the runtime)
466
+
467
+ - **ChromaDB + sentence-transformers + torch deleted entirely.**
468
+ ~150 MB of dependencies gone. Pipx install ≤100 MB (gated by the
469
+ cold-install smoke G2.5). MCP server startup <100ms (was 1-3s due
470
+ to torch warmup).
471
+ - **tree-sitter-language-pack (351 MB, 17 grammars) replaced** with
472
+ individual grammar packages: `tree-sitter-typescript`,
473
+ `tree-sitter-javascript`, `tree-sitter-go`, `tree-sitter-rust`
474
+ (~5 MB total). Long-tail languages (Java, C, C++, Ruby, PHP,
475
+ Kotlin, Swift, Solidity, etc.) remain available via the opt-in
476
+ extra `pip install 'codevira[all-languages]'` which re-adds the
477
+ legacy pack. This is the single biggest contributor to the v2.2.0
478
+ size cut.
479
+ - **`search_codebase` MCP tool removed.** AI agents grep + Read files
480
+ natively in 2026; semantic code search was the source of 90%+ of
481
+ v2.1.x disk usage and every major bug (issue #10 Antigravity dlopen,
482
+ 64 GB HNSW corruption, write amplification). Calling the tool now
483
+ returns a friendly explanation pointing at grep/Read.
484
+ - **`codevira calibrate` CLI command removed.** No more semantic
485
+ thresholds (FTS5 has no learnable thresholds; uses BM25 BM25 ranking).
486
+ - **`prewarm_embedding_model()` removed.** No model to warm.
487
+ - **`mcp_server/cli_calibrate.py`, `mcp_server/tools/_decision_embeddings.py`,
488
+ `mcp_server/engine/policies/cross_session.py`** — all deleted.
489
+ ~1,500 LOC of v2.1.x code gone.
490
+
491
+ ### Added
492
+
493
+ - **`mcp_server/storage/`** new package:
494
+ - `jsonl_store.py` — atomic append, file lock, monotonic IDs,
495
+ UTF-8/emoji/CJK roundtrip
496
+ - `fts5_index.py` — SQLite FTS5 BM25 keyword search, <50ms on
497
+ 1000-decision corpus
498
+ - `manifest.py` — tag/file → id index in YAML
499
+ - `digest.py` — slim per-decision records with outcome-weighted
500
+ scoring
501
+ - `token_estimator.py` — char-based proxy (4 chars/token); optional
502
+ tiktoken via `CODEVIRA_TOKEN_PRECISION=exact`
503
+ - `agents_md_generator.py` — 5 KB-capped AGENTS.md regen with
504
+ marker preservation
505
+ - `decisions_store.py`, `sessions_store.py` — high-level facades
506
+ - `paths.py` — single source of truth for `.codevira/` paths
507
+ - **`mcp_server/engine/policies/relevance_inject.py`** — replaces
508
+ `cross_session.py`. Token-bounded injection:
509
+ - **Off-topic prompt → 0 tokens** (no `additionalContext` at all)
510
+ - **On-topic prompt → ≤600 tokens, ≤3 decisions**
511
+ - Scoring: tag (0.4) + file (0.4) + FTS5 (0.2) × outcome_weight
512
+ - Cache-stable output (sorted IDs, no timestamps,
513
+ `<codevira-context cache_key="...">` wrapper)
514
+ - Config via `.codevira/config.yaml` or `CODEVIRA_INJECT_*` env vars
515
+ - **`codevira sync`** CLI command — regenerate manifest + digest +
516
+ FTS5 + AGENTS.md from `decisions.jsonl`. Manual / recovery path
517
+ (every record_decision triggers regen synchronously).
518
+
519
+ ### Backwards compatibility
520
+
521
+ - **No migration from v2.1.x.** Per the v2.2.0 plan: clean break.
522
+ Users `codevira init` on each project to scaffold `.codevira/`.
523
+ v2.1.x continues to exist on PyPI for users who don't upgrade.
524
+ Optional `codevira archive-legacy` preserves v2.1.x decisions as a
525
+ read-only reference.
526
+ - **Decision IDs change from int (`1`, `2`) to string (`D000001`,
527
+ `D000002`).** Tools that round-trip IDs as opaque values continue
528
+ to work. Code that hardcodes int IDs needs updating.
529
+ - **`check_conflict` MCP tool semantics shifted from semantic to
530
+ Jaccard text similarity** (FTS5 candidate pool + Jaccard token-set).
531
+ Threshold tuned conservatively (0.60).
532
+
533
+ ### Tests
534
+
535
+ - 141 new tests across `tests/storage/` and `tests/engine/test_relevance_inject.py`
536
+ - Existing integration suite (`tests/integration/test_mcp_roundtrip.py`)
537
+ passes 13/14 against new backend (the 14th is a chromadb-availability
538
+ test, skipped permanently now)
539
+
540
+ ### Removed — legacy v2.1.x compatibility paths (no carryover users)
541
+
542
+ Once the v2.1.x user base dropped to zero (per maintainer's
543
+ 2026-05-22 directive: "no users; go fresh"), the defensive
544
+ SQLiteGraph fallback branches added during Phase B's incremental
545
+ migration became dead weight. Removed:
546
+
547
+ - **`build_timeline(conn=...)` SQL backend** — `build_timeline()` is
548
+ now JSONL-only; the `conn` parameter is gone. Resource handler,
549
+ CLI replay, and tests all read from `.codevira/{decisions,
550
+ outcomes, sessions}.jsonl` exclusively. Public API simplified.
551
+ - **`SignalContext.search_decisions` graph.db fallback** — JSONL FTS5
552
+ is the only backend; the legacy `graph.search_decisions()` branch
553
+ is gone. Returns `[]` cleanly when `.codevira/` isn't initialised.
554
+ - **`treesitter_parser._load_parser_for` legacy pack fallback** —
555
+ unsupported languages now raise ValueError immediately with an
556
+ actionable message. The `[all-languages]` opt-in extra is gone.
557
+ v2.3.0 may re-introduce specific long-tail grammars as individual
558
+ deps if real demand emerges.
559
+ - **Ported tests** that exercised the SQL path (test_decision_replay,
560
+ test_qa_round_week10/13, test_v2_release_candidate, test_cli_replay)
561
+ to use the JSONL planter helper (`decisions_store.record` +
562
+ `jsonl_store.append(outcomes_path, ...)`). Test count unchanged at
563
+ 2,514 passes.
564
+
565
+ ### Fixed — cross-tool wedge gaps (post-Phase-G completeness)
566
+
567
+ The cross-tool universality e2e tests surfaced several read paths
568
+ that Phase B's "tool surface repointed at JSONL" pass missed. All
569
+ fixed in the same release:
570
+
571
+ - **`SignalContext.search_decisions`** now reads via
572
+ `decisions_store.search()` (FTS5 over JSONL) when `.codevira/` is
573
+ initialized. The legacy `SQLiteGraph.search_decisions()` is kept
574
+ as a fallback for v2.1.x projects.
575
+ - **`codevira replay` CLI + `codevira://decisions` MCP resource**
576
+ now read from `.codevira/decisions.jsonl` + `.codevira/outcomes.jsonl`
577
+ + `.codevira/sessions.jsonl`. Both surface decisions recorded via
578
+ `record_decision` immediately, with outcome counts aggregated from
579
+ `outcomes.jsonl` (kept/modified/reverted). SQLiteGraph fallback
580
+ preserved for v2.1.x.
581
+ - **FTS5 index now indexes `file_path`** (BM25 weight 0.8) so search
582
+ queries like `"retries"` match decisions whose only reference to
583
+ the term is in the file path. Existing FTS5 caches without the new
584
+ column are detected and auto-dropped + rebuilt on the next search.
585
+ - **FTS5 `_sanitize_fts_query` now OR-joins terms** with stopword +
586
+ short-token stripping. The previous implicit-AND turned every
587
+ multi-word prompt into an over-strict phrase query — e.g. asking
588
+ "What did we decide about bcrypt for password hashing?" missed the
589
+ decision "use bcrypt over argon2" because "password" and "hashing"
590
+ aren't in the stored text. The off-topic 0-token gate
591
+ (`relevance_min_score=0.10`) still suppresses irrelevant matches.
592
+ - **`decisions_store.record` and `record_many` now append
593
+ `digest.jsonl` incrementally**. Previously digest was only
594
+ regenerated via `codevira sync` / `rebuild_indexes()`, so the
595
+ relevance-inject policy showed `(decision summary unavailable —
596
+ try codevira sync)` for decisions recorded since the last sync.
597
+
598
+ ## [2.1.2] — 2026-05-19 — Trust recovery + QoL
599
+
600
+ Trust-recovery release based on **four independent field-test reports** that
601
+ converged on "trust" as the gap (not capability). Full plan:
602
+ [docs/plans/v2.1.2.md](docs/plans/v2.1.2.md).
603
+
604
+ ### Added — Smart similarity threshold (Item 1)
605
+
606
+ - `search_decisions` now applies a per-project, self-calibrating similarity
607
+ threshold before RRF fusion. Gibberish queries (`"zzzzzz xqzv9"`,
608
+ `"how to make a cake"`, `""`) return zero results with
609
+ `retrieval: "semantic-no-results-above-threshold"` instead of the
610
+ v2.1.1 regression where they surfaced the "least bad" matches.
611
+ - New `codevira calibrate` CLI command for manual threshold re-fit.
612
+ Auto-recalibration runs in a daemon thread every ~10 decisions added.
613
+ - Per-project `<data_dir>/calibration.json` (search threshold + hook
614
+ threshold + positive-sample count + ISO timestamp).
615
+ - Cross-session hook injection (`CrossSessionConsistency`) applies the
616
+ stricter `hook` threshold (search − 0.10). Commit-message-shaped
617
+ prompts (`feat(api):` / `fix:` / etc.) skipped entirely.
618
+
619
+ ### Added — Honest cleanup (Item 3)
620
+
621
+ - `codevira reset --vectors / --graph / --all` — destructive operations
622
+ split out of `codevira heal` (whose name implied fix-in-place).
623
+ - Auto-export of decisions + outcomes + preferences + learned_rules to
624
+ `<data_dir>/exports/<ts>-pre-<target>.json` BEFORE any wipe of `graph/`.
625
+ Pass `--no-backup` to skip.
626
+ - Typed confirmation: user must type `reset` / `graph` / `vectors` /
627
+ `all` (not just `y`) to proceed. `--yes` skips for scripts.
628
+ - `codevira heal --vectors / --graph / --all` deprecation cycle:
629
+ forwards to `cmd_reset` with a one-time warning. Removal planned v2.2.
630
+ - New `codevira export decisions [--format json|sql] [--out PATH]`
631
+ standalone backup command. Closes Report 1 §7 gap.
632
+ - New `confirm_typed(...)` helper in `_prompts.py`.
633
+
634
+ ### Added — Proactive correctness
635
+
636
+ - **Item 20**: `check_conflict(decision_text, file_path?)` MCP tool detects
637
+ duplicates and conflicts vs `do_not_revert=True` decisions. Uses Item 1's
638
+ calibrated threshold. `record_decision` runs it automatically pre-write
639
+ and surfaces `_conflict_warning` in the response (suppressible with
640
+ `force=True`).
641
+ - **Item 26**: `supersede_decision(old_id, new_decision, reason)` retires
642
+ a prior decision with auditable history. Schema auto-migrates with
643
+ `is_superseded INTEGER + superseded_by INTEGER`. `list_decisions` filters
644
+ superseded rows by default; `include_superseded=True` opts back in.
645
+
646
+ ### Added — Enumeration + filtering
647
+
648
+ - **Item 11**: `list_decisions(limit, since_date, file_pattern,
649
+ protected_only, session_id, tags, include_superseded, full)` MCP tool.
650
+ Closes Report 3 "remembers but can't list" gap.
651
+ - **Item 27 (partial)**: `tags=[...]` on `record_decision`; `list_tags()`
652
+ MCP tool; tag filter on `list_decisions`. `decision_tags` table
653
+ auto-migrated.
654
+ - **Item 25**: `since="YYYY-MM-DD"` (or ISO 8601) filter on
655
+ `search_decisions`, `get_history`, `get_session_context`. SQL-layer
656
+ for BM25, post-filter for semantic results.
657
+
658
+ ### Added — Batch APIs (Items 23 + 24)
659
+
660
+ - `record_decisions([...])` and `write_session_logs([...])` cut
661
+ memory-dump sessions from ~26 separate round trips to 1. Returns
662
+ `{count, recorded:[ids], errors:[{idx, error}]}` with per-item
663
+ partial-failure surfacing.
664
+
665
+ ### Added — Trust + correctness fixes
666
+
667
+ - **Item 2**: `get_node` / `get_impact` / `query_graph` / `update_node`
668
+ return `not_indexed: True` + null counts instead of misleading 0 for
669
+ un-indexed paths.
670
+ - **Item 4**: New `PostEditGraphRefresh` policy refreshes graph nodes in
671
+ a daemon thread after Edit/Write/MultiEdit so subsequent
672
+ `get_node` / `get_impact` calls see fresh data.
673
+ - **Item 9**: `global_db.get_rules()` strict-language match by default
674
+ (was `language = ? OR language IS NULL`). Prevents Go-project rules
675
+ with NULL language from leaking into Python projects. Pass
676
+ `strict_language=False` for legacy behavior.
677
+ - **Item 17**: Rule extractor noise filter — stopword filter + minimum
678
+ content-density gate + substring suppression in `_find_common_phrases`.
679
+ Pre-code projects (0 indexed source files) skip
680
+ `_infer_decision_pattern_rules` entirely.
681
+ - **Item 18**: `add_phase()` silently replaces the bootstrap
682
+ "Getting Started" placeholder when called with the SAME number (and
683
+ the placeholder is pristine — status=pending, no changesets, default
684
+ description).
685
+ - **Item 19**: Regression test for `file_path` serialization round-trip
686
+ through `get_session_context`'s `recent_decisions`.
687
+ - **Item 22**: `write_session_log` / `log_session` auto-suffix
688
+ `session_id` on content collision (was: silent `INSERT OR REPLACE`).
689
+ Same id + same summary remains idempotent; different summary returns
690
+ the new suffixed id with `collision_resolved: True`.
691
+ - **Item 33**: Hook commit-message pre-filter suppresses injection on
692
+ prompts matching `^(feat|fix|chore|docs|refactor|test|style|perf|build|ci|revert)(\(.*\))?:`.
693
+
694
+ ### Added — Roadmap workflow
695
+
696
+ - **Item 10**: `complete_phase(backfill=True, completed_at='YYYY-MM-DD')`
697
+ for retroactive phase completion (current / upcoming / synthetic
698
+ cases).
699
+ - **Item 12**: `complete_phase(git_ref="...")` links a commit sha or PR
700
+ reference to the completion entry.
701
+ - **Item 29**: `bulk_import_phases([...])` for adopting codevira on a
702
+ project that already shipped N phases in git. Idempotent.
703
+
704
+ ### Added — QoL
705
+
706
+ - **Item 5**: `do_not_revert` int→bool coercion at SQLite read boundary
707
+ (`search_decisions`, missing-rows fetch path). API contract now
708
+ matches schema.
709
+ - **Item 6**: Smart truncation in `top_signals.rules` (word-boundary +
710
+ path-aware, 160-char limit).
711
+ - **Item 7**: `summary` derived from first 80 chars of decision text
712
+ instead of `"ad-hoc record_decision"` placeholder.
713
+ - **Item 8**: `get_session_context` returns `confidence_note` instead of
714
+ `confidence=null` on fresh projects.
715
+ - **Item 28**: `summary_only=True` mode on `search_decisions` returns
716
+ id + summary + score + do_not_revert only — ~70% smaller payload for
717
+ AI triage queries.
718
+ - **Item 30**: `record_decision` input-coerced echo — when
719
+ `do_not_revert` is passed as a non-bool (int 1, string "true"),
720
+ response carries `_input_coerced_warning`.
721
+ - **Item 31**: Bundled non-Python playbooks (TypeScript / Go / generic)
722
+ in `mcp_server/data/rules/coding-standards-<lang>.md`. Auto-selected
723
+ by detected project language. Closes Report 1 §3.5.
724
+ - **Items 13 + 14**: `clean --orphans` catches bare global.db rows (no
725
+ data dir + path missing on disk). `clean --ghosts` catches truly-
726
+ empty data dirs (<10 KB, status='stale').
727
+
728
+ ### Added — Plan + governance (Item 16)
729
+
730
+ - `docs/plans/v2.1.2.md` mirrors the master plan (33 items + 4 deferred
731
+ v2.2-class items). Establishes release-planning discipline: every
732
+ vX.Y.Z release with 3+ items gets its own `docs/plans/` doc.
733
+ - `ROADMAP.md` v2.1.2 section.
734
+ - `CONTRIBUTING.md` Release planning + Documentation discipline.
735
+
736
+ ### Fixed
737
+
738
+ - **Item 21**: Multi-language `get_signature` / `get_code` confirmed
739
+ working in v2.1.1 (15+ languages via tree-sitter-language-pack). No
740
+ new code needed; doc fix only.
741
+ - **Item 32**: All 42 pre-existing mypy errors cleared via real fixes
742
+ (type narrowing, missing imports, `Counter` / `dict[str, Any]`
743
+ annotations, AST isinstance gating) and targeted
744
+ `# type: ignore[code]` for invariant pre-existing patterns. mypy is
745
+ now a hard pre-commit gate.
746
+
747
+ ### Late additions (caught by post-tag smoke testing)
748
+
749
+ These three patches landed AFTER the initial v2.1.2 release commit but
750
+ BEFORE shipping the wheel. They're all part of the v2.1.2 line:
751
+
752
+ - **bulk_import_phases placeholder fix**: importing `phase=1` on a
753
+ fresh project was silently SKIPPING phase 1 because the bootstrap
754
+ "Getting Started" placeholder occupies that number. Adopters
755
+ migrating multi-phase git history (Report 3 #5 — the exact use case
756
+ Item 29 exists for) would hit this. Fixed by applying Item 18's
757
+ placeholder-recognition logic to bulk_import too.
758
+ - **calibrate doc range fix**: `codevira calibrate --help` said
759
+ "Clamped to [0.20, 0.55]" but actual code clamps to [0.35, 0.80]
760
+ (the empirically-tuned values from Item 1 after measuring
761
+ all-MiniLM-L6-v2's distance distribution on real query/decision
762
+ pairs). Doc string corrected.
763
+ - **Issue #10 — Antigravity sandbox + torch dlopen**: graceful
764
+ degradation across 3 tiers. (1) Removed `prewarm_embedding_model()`
765
+ from MCP server startup — torch loads lazily on first
766
+ `search_codebase` / `search_decisions` call. MCP `initialize` and
767
+ `tools/list` complete instantly without touching torch. All
768
+ non-search tools work in Antigravity. (2) `_decisions_collection_or_none()`
769
+ traps `OSError` (macOS dlopen errors arrive as OSError, not
770
+ ImportError) and surfaces `_semantic_warning` in `search_decisions`
771
+ responses with a clear explanation + issue link.
772
+ (3) `docs/troubleshooting/antigravity.md` documents the root cause
773
+ and four user-side workarounds. Closes
774
+ [#10](https://github.com/sachinshelke/codevira/issues/10).
775
+
776
+ ### Tests
777
+
778
+ - 2401/2401 unit tests pass + 4/4 e2e cross-tool universality.
779
+ - Replaced: `test_log_session_replaces_on_duplicate` → idempotent +
780
+ auto-suffix variants (Item 22).
781
+ - Renamed: `test_8_evaluation_under_5ms_p95` → `_50ms_p95` (semantic
782
+ gate is inherently slower than BM25-only).
783
+ - Updated: all `test_default_heroes_*` / `test_*_default_policies_*`
784
+ acceptance tests to expect `post_edit_graph_refresh` in the default
785
+ set; `test_dispatch_complete_phase` (×2) + `test_dispatch_get_history`
786
+ for new kwarg defaults.
787
+ - New positive tests: `test_get_node_not_indexed`,
788
+ `test_get_impact_not_indexed`,
789
+ `test_gibberish_query_returns_zero_above_threshold`,
790
+ `test_session_context_recent_decisions_preserve_file_path`,
791
+ `test_add_phase_replaces_pristine_placeholder`,
792
+ `test_log_session_idempotent_on_same_content`,
793
+ `test_log_session_auto_suffixes_on_different_content`,
794
+ `test_language_filter_strict_excludes_null_language`,
795
+ `test_language_filter_loose_includes_null_language`.
796
+
797
+ ### Deferred to v2.1.3 / v2.2
798
+
799
+ - Full README rewrite with animated 60-second demo GIF (Item 15) — pair
800
+ with v2.2 launch / benchmark publishing once benchmark suite ships.
801
+ - Bundled `coding-standards-<lang>.md` for Rust / Java / etc. — extend
802
+ the per-language playbook system as adopters request.
13
803
 
14
804
  ## [2.1.1] — 2026-05-17 — Hybrid decision search
15
805