codevira 2.1.2__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 (284) hide show
  1. {codevira-2.1.2 → codevira-3.0.0}/CHANGELOG.md +585 -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.2 → codevira-3.0.0}/codevira.egg-info/SOURCES.txt +28 -32
  6. {codevira-2.1.2 → 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.2 → codevira-3.0.0}/docs/foolproof-product-charter.md +3 -2
  10. {codevira-2.1.2 → codevira-3.0.0}/docs/how-i-built-persistent-memory-for-ai-agents.md +10 -0
  11. {codevira-2.1.2 → codevira-3.0.0}/docs/linkedin-article-ai-agent-memory.md +9 -0
  12. {codevira-2.1.2 → 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.3.md +361 -0
  15. codevira-3.0.0/docs/plans/v2.2.0.md +960 -0
  16. codevira-3.0.0/docs/plans/v3.0.0.md +256 -0
  17. {codevira-2.1.2 → codevira-3.0.0}/docs/qa-playbook.md +14 -0
  18. {codevira-2.1.2 → codevira-3.0.0}/docs/roadmap.md +17 -4
  19. codevira-3.0.0/docs/surface-cuts-2026-05-22.md +348 -0
  20. {codevira-2.1.2 → codevira-3.0.0}/indexer/fix_history.py +57 -19
  21. {codevira-2.1.2 → codevira-3.0.0}/indexer/graph_generator.py +95 -36
  22. {codevira-2.1.2 → codevira-3.0.0}/indexer/index_codebase.py +51 -94
  23. {codevira-2.1.2 → codevira-3.0.0}/indexer/outcome_tracker.py +115 -43
  24. {codevira-2.1.2 → codevira-3.0.0}/indexer/sqlite_graph.py +13 -204
  25. {codevira-2.1.2 → codevira-3.0.0}/indexer/treesitter_parser.py +61 -23
  26. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/__init__.py +1 -1
  27. codevira-3.0.0/mcp_server/_mcp_registry.py +145 -0
  28. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_repair_init.py +46 -22
  29. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_safe_crash.py +0 -1
  30. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/auto_init.py +45 -14
  31. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli.py +353 -851
  32. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_export.py +34 -8
  33. codevira-3.0.0/mcp_server/cli_graph.py +447 -0
  34. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_hooks_admin.py +80 -7
  35. codevira-3.0.0/mcp_server/cli_init.py +296 -0
  36. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_replay.py +73 -24
  37. codevira-3.0.0/mcp_server/cli_sync.py +109 -0
  38. codevira-3.0.0/mcp_server/cli_uninstall.py +478 -0
  39. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/post_tool_use.sh +8 -0
  40. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/pre_tool_use.sh +8 -0
  41. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/session_start.sh +8 -0
  42. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/stop.sh +8 -0
  43. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/user_prompt_submit.sh +9 -0
  44. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/decision_replay.py +125 -75
  45. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/doctor.py +287 -99
  46. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/__init__.py +11 -14
  47. codevira-3.0.0/mcp_server/engine/policies/__init__.py +45 -0
  48. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/_signature_detect.py +0 -1
  49. codevira-3.0.0/mcp_server/engine/policies/relevance_inject.py +458 -0
  50. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/signals.py +120 -185
  51. codevira-3.0.0/mcp_server/global_sync.py +96 -0
  52. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/http_server.py +119 -47
  53. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/ide_inject.py +130 -48
  54. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/log_retention.py +30 -9
  55. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/migrate.py +21 -5
  56. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/paths.py +65 -24
  57. codevira-3.0.0/mcp_server/prompts.py +77 -0
  58. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/roadmap_drift.py +1 -1
  59. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/server.py +294 -730
  60. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/setup_wizard.py +274 -137
  61. codevira-3.0.0/mcp_server/storage/__init__.py +43 -0
  62. codevira-3.0.0/mcp_server/storage/agents_md_generator.py +360 -0
  63. codevira-3.0.0/mcp_server/storage/atomic.py +268 -0
  64. codevira-3.0.0/mcp_server/storage/decisions_store.py +546 -0
  65. codevira-3.0.0/mcp_server/storage/digest.py +134 -0
  66. codevira-3.0.0/mcp_server/storage/fts5_index.py +430 -0
  67. codevira-3.0.0/mcp_server/storage/jsonl_store.py +390 -0
  68. codevira-3.0.0/mcp_server/storage/manifest.py +199 -0
  69. codevira-3.0.0/mcp_server/storage/outcomes_writer.py +295 -0
  70. codevira-3.0.0/mcp_server/storage/paths.py +160 -0
  71. codevira-3.0.0/mcp_server/storage/sessions_store.py +123 -0
  72. codevira-3.0.0/mcp_server/storage/token_estimator.py +106 -0
  73. codevira-3.0.0/mcp_server/tools/changesets.py +50 -0
  74. codevira-3.0.0/mcp_server/tools/check_conflict.py +286 -0
  75. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/graph.py +9 -421
  76. codevira-3.0.0/mcp_server/tools/learning.py +678 -0
  77. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/roadmap.py +396 -347
  78. codevira-3.0.0/mcp_server/tools/search.py +296 -0
  79. {codevira-2.1.2 → codevira-3.0.0}/pyproject.toml +25 -13
  80. {codevira-2.1.2 → codevira-3.0.0}/tests/test_auto_init.py +119 -52
  81. {codevira-2.1.2 → codevira-3.0.0}/tests/test_call_edge_fk_safety.py +0 -2
  82. codevira-3.0.0/tests/test_check_conflict.py +293 -0
  83. codevira-3.0.0/tests/test_cli_graph.py +162 -0
  84. {codevira-2.1.2 → codevira-3.0.0}/tests/test_cli_replay.py +136 -47
  85. codevira-3.0.0/tests/test_cli_uninstall.py +475 -0
  86. {codevira-2.1.2 → codevira-3.0.0}/tests/test_cli_version.py +0 -1
  87. {codevira-2.1.2 → codevira-3.0.0}/tests/test_crash_logger.py +1 -3
  88. {codevira-2.1.2 → codevira-3.0.0}/tests/test_doctor.py +71 -34
  89. {codevira-2.1.2 → codevira-3.0.0}/tests/test_fk_safety_extended.py +0 -1
  90. {codevira-2.1.2 → codevira-3.0.0}/tests/test_fork_safety.py +0 -3
  91. {codevira-2.1.2 → codevira-3.0.0}/tests/test_gitignore.py +173 -80
  92. codevira-3.0.0/tests/test_global_sync.py +152 -0
  93. {codevira-2.1.2 → codevira-3.0.0}/tests/test_graph_generator.py +39 -36
  94. {codevira-2.1.2 → codevira-3.0.0}/tests/test_http_server.py +167 -119
  95. {codevira-2.1.2 → codevira-3.0.0}/tests/test_ide_inject.py +260 -30
  96. {codevira-2.1.2 → codevira-3.0.0}/tests/test_index_codebase.py +51 -43
  97. {codevira-2.1.2 → codevira-3.0.0}/tests/test_launchd.py +1 -2
  98. {codevira-2.1.2 → codevira-3.0.0}/tests/test_log_retention.py +0 -2
  99. {codevira-2.1.2 → codevira-3.0.0}/tests/test_migrate.py +54 -37
  100. {codevira-2.1.2 → codevira-3.0.0}/tests/test_outcome_tracker.py +1 -2
  101. {codevira-2.1.2 → codevira-3.0.0}/tests/test_paths.py +237 -28
  102. codevira-3.0.0/tests/test_prompts.py +88 -0
  103. {codevira-2.1.2 → codevira-3.0.0}/tests/test_record_decision.py +39 -34
  104. {codevira-2.1.2 → codevira-3.0.0}/tests/test_repair_init.py +0 -2
  105. {codevira-2.1.2 → codevira-3.0.0}/tests/test_roadmap_drift.py +0 -2
  106. {codevira-2.1.2 → codevira-3.0.0}/tests/test_server.py +81 -413
  107. {codevira-2.1.2 → codevira-3.0.0}/tests/test_setup_wizard.py +298 -261
  108. {codevira-2.1.2 → codevira-3.0.0}/tests/test_sqlite_graph.py +13 -176
  109. {codevira-2.1.2 → codevira-3.0.0}/tests/test_sqlite_util.py +0 -1
  110. {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_code_reader.py +93 -26
  111. {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_graph.py +55 -496
  112. {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_learning.py +104 -483
  113. {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_playbook.py +0 -1
  114. {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_roadmap.py +0 -2
  115. {codevira-2.1.2 → codevira-3.0.0}/tests/test_treesitter_parser.py +0 -3
  116. {codevira-2.1.2 → codevira-3.0.0}/tests/test_watcher_circuit.py +0 -1
  117. codevira-2.1.2/PKG-INFO +0 -809
  118. codevira-2.1.2/README.md +0 -762
  119. codevira-2.1.2/codevira.egg-info/PKG-INFO +0 -809
  120. codevira-2.1.2/indexer/rule_learner.py +0 -336
  121. codevira-2.1.2/mcp_server/agents_md.py +0 -442
  122. codevira-2.1.2/mcp_server/cli_agents.py +0 -232
  123. codevira-2.1.2/mcp_server/cli_budget.py +0 -213
  124. codevira-2.1.2/mcp_server/cli_calibrate.py +0 -140
  125. codevira-2.1.2/mcp_server/cli_configure.py +0 -977
  126. codevira-2.1.2/mcp_server/cli_insights.py +0 -337
  127. codevira-2.1.2/mcp_server/data/templates/agents_md.tmpl +0 -3
  128. codevira-2.1.2/mcp_server/data/templates/canonical_block.md +0 -81
  129. codevira-2.1.2/mcp_server/data/templates/claude_md.tmpl +0 -3
  130. codevira-2.1.2/mcp_server/data/templates/copilot_instructions.tmpl +0 -3
  131. codevira-2.1.2/mcp_server/data/templates/cursor_rules.mdc.tmpl +0 -8
  132. codevira-2.1.2/mcp_server/data/templates/gemini_md.tmpl +0 -3
  133. codevira-2.1.2/mcp_server/data/templates/windsurfrules.tmpl +0 -3
  134. codevira-2.1.2/mcp_server/engine/intent_classifier.py +0 -214
  135. codevira-2.1.2/mcp_server/engine/policies/__init__.py +0 -44
  136. codevira-2.1.2/mcp_server/engine/policies/ai_promotion.py +0 -337
  137. codevira-2.1.2/mcp_server/engine/policies/cross_session.py +0 -591
  138. codevira-2.1.2/mcp_server/engine/policies/intent_inference.py +0 -421
  139. codevira-2.1.2/mcp_server/engine/policies/live_style.py +0 -445
  140. codevira-2.1.2/mcp_server/engine/policies/scope_contract.py +0 -362
  141. codevira-2.1.2/mcp_server/engine/promotion_score.py +0 -208
  142. codevira-2.1.2/mcp_server/engine/scope_contract.py +0 -201
  143. codevira-2.1.2/mcp_server/global_sync.py +0 -187
  144. codevira-2.1.2/mcp_server/prompts.py +0 -145
  145. codevira-2.1.2/mcp_server/tools/_decision_embeddings.py +0 -694
  146. codevira-2.1.2/mcp_server/tools/changesets.py +0 -225
  147. codevira-2.1.2/mcp_server/tools/check_conflict.py +0 -175
  148. codevira-2.1.2/mcp_server/tools/learning.py +0 -984
  149. codevira-2.1.2/mcp_server/tools/search.py +0 -897
  150. codevira-2.1.2/tests/test_cli.py +0 -1423
  151. codevira-2.1.2/tests/test_cli_agents.py +0 -375
  152. codevira-2.1.2/tests/test_cli_configure.py +0 -1075
  153. codevira-2.1.2/tests/test_cli_insights.py +0 -159
  154. codevira-2.1.2/tests/test_decision_embeddings.py +0 -253
  155. codevira-2.1.2/tests/test_global_sync.py +0 -325
  156. codevira-2.1.2/tests/test_prompts.py +0 -101
  157. codevira-2.1.2/tests/test_retire_rule.py +0 -271
  158. codevira-2.1.2/tests/test_rule_learner.py +0 -411
  159. codevira-2.1.2/tests/test_tools_changesets.py +0 -424
  160. codevira-2.1.2/tests/test_tools_search.py +0 -489
  161. {codevira-2.1.2 → codevira-3.0.0}/LICENSE +0 -0
  162. {codevira-2.1.2 → codevira-3.0.0}/MANIFEST.in +0 -0
  163. {codevira-2.1.2 → codevira-3.0.0}/agents/builder.md +0 -0
  164. {codevira-2.1.2 → codevira-3.0.0}/agents/developer.md +0 -0
  165. {codevira-2.1.2 → codevira-3.0.0}/agents/documenter.md +0 -0
  166. {codevira-2.1.2 → codevira-3.0.0}/agents/orchestrator.md +0 -0
  167. {codevira-2.1.2 → codevira-3.0.0}/agents/planner.md +0 -0
  168. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/01-code-review.md +0 -0
  169. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/02-adversarial-fix-review.md +0 -0
  170. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/03-cross-module-impact.md +0 -0
  171. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/06-doc-drift.md +0 -0
  172. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/07-security-audit.md +0 -0
  173. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/12-llm-redteam.md +0 -0
  174. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/13-multi-ide-schema.md +0 -0
  175. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/22-competitor-benchmark.md +0 -0
  176. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/README.md +0 -0
  177. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/tier2-scripts.md +0 -0
  178. {codevira-2.1.2 → codevira-3.0.0}/agents/qa/tier3-manual.md +0 -0
  179. {codevira-2.1.2 → codevira-3.0.0}/agents/reviewer.md +0 -0
  180. {codevira-2.1.2 → codevira-3.0.0}/agents/tester.md +0 -0
  181. {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/dependency_links.txt +0 -0
  182. {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/entry_points.txt +0 -0
  183. {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/top_level.txt +0 -0
  184. {codevira-2.1.2 → codevira-3.0.0}/config.example.yaml +0 -0
  185. {codevira-2.1.2 → codevira-3.0.0}/docs/alpha-tester-invites.md +0 -0
  186. {codevira-2.1.2 → codevira-3.0.0}/docs/demo/README.md +0 -0
  187. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/00-engine.md +0 -0
  188. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/01-decision-lock.md +0 -0
  189. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/02-anti-regression.md +0 -0
  190. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/03-scope-contract.md +0 -0
  191. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/04-blast-radius.md +0 -0
  192. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/05-cross-session.md +0 -0
  193. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/06-token-budget.md +0 -0
  194. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/07-live-style.md +0 -0
  195. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/08-decision-replay.md +0 -0
  196. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/09-intent-inference.md +0 -0
  197. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/10-ai-promotion.md +0 -0
  198. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/README.md +0 -0
  199. {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/pillar-1-setup.md +0 -0
  200. {codevira-2.1.2 → codevira-3.0.0}/docs/hn-launch-day.md +0 -0
  201. {codevira-2.1.2 → codevira-3.0.0}/docs/internal/competitive-landscape.md +0 -0
  202. {codevira-2.1.2 → codevira-3.0.0}/docs/linkedin-post-ai-agent-memory.md +0 -0
  203. {codevira-2.1.2 → codevira-3.0.0}/docs/local-pypi-https.md +0 -0
  204. {codevira-2.1.2 → codevira-3.0.0}/docs/plans/v2.1.2.md +0 -0
  205. {codevira-2.1.2 → codevira-3.0.0}/docs/release-process.md +0 -0
  206. {codevira-2.1.2 → codevira-3.0.0}/docs/troubleshooting/antigravity.md +0 -0
  207. {codevira-2.1.2 → codevira-3.0.0}/docs/v2-completion-plan.md +0 -0
  208. {codevira-2.1.2 → codevira-3.0.0}/docs/v2-execution-log.md +0 -0
  209. {codevira-2.1.2 → codevira-3.0.0}/docs/v2-master-plan.md +0 -0
  210. {codevira-2.1.2 → codevira-3.0.0}/docs/vs-other-memory-tools.md +0 -0
  211. {codevira-2.1.2 → codevira-3.0.0}/graph/_schema.yaml +0 -0
  212. {codevira-2.1.2 → codevira-3.0.0}/indexer/__init__.py +0 -0
  213. {codevira-2.1.2 → codevira-3.0.0}/indexer/_dedupe_migration.py +0 -0
  214. {codevira-2.1.2 → codevira-3.0.0}/indexer/_fork_safety.py +0 -0
  215. {codevira-2.1.2 → codevira-3.0.0}/indexer/_sqlite_util.py +0 -0
  216. {codevira-2.1.2 → codevira-3.0.0}/indexer/chunker.py +0 -0
  217. {codevira-2.1.2 → codevira-3.0.0}/indexer/global_db.py +0 -0
  218. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/__main__.py +0 -0
  219. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_ghost_check.py +0 -0
  220. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_project_inventory.py +0 -0
  221. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_prompts.py +0 -0
  222. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_projects.py +0 -0
  223. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/crash_logger.py +0 -0
  224. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/__init__.py +0 -0
  225. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/builder.md +0 -0
  226. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/developer.md +0 -0
  227. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/documenter.md +0 -0
  228. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/orchestrator.md +0 -0
  229. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/planner.md +0 -0
  230. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/reviewer.md +0 -0
  231. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/tester.md +0 -0
  232. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/config.example.yaml +0 -0
  233. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards-generic.md +0 -0
  234. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards-go.md +0 -0
  235. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards-typescript.md +0 -0
  236. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards.md +0 -0
  237. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/engineering-excellence.md +0 -0
  238. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/git-cicd-governance.md +0 -0
  239. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/git_commits.md +0 -0
  240. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/incremental-updates.md +0 -0
  241. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/master_rule.md +0 -0
  242. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/multi-language.md +0 -0
  243. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/persistence.md +0 -0
  244. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/resilience-observability.md +0 -0
  245. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/smoke-testing.md +0 -0
  246. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/testing-standards.md +0 -0
  247. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/detect.py +0 -0
  248. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/demo_policy.py +0 -0
  249. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/events.py +0 -0
  250. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/anti_regression.py +0 -0
  251. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/blast_radius.py +0 -0
  252. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/decision_lock.py +0 -0
  253. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/post_edit_refresh.py +0 -0
  254. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/token_budget.py +0 -0
  255. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policy.py +0 -0
  256. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/runner.py +0 -0
  257. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/token_meter.py +0 -0
  258. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/wiring/__init__.py +0 -0
  259. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/wiring/claude_code_hooks.py +0 -0
  260. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/wiring/mcp_dispatch.py +0 -0
  261. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/gitignore.py +0 -0
  262. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/launchd.py +0 -0
  263. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/__init__.py +0 -0
  264. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/code_reader.py +0 -0
  265. {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/playbook.py +0 -0
  266. {codevira-2.1.2 → codevira-3.0.0}/rules/coding-standards.md +0 -0
  267. {codevira-2.1.2 → codevira-3.0.0}/rules/engineering-excellence.md +0 -0
  268. {codevira-2.1.2 → codevira-3.0.0}/rules/git-cicd-governance.md +0 -0
  269. {codevira-2.1.2 → codevira-3.0.0}/rules/git_commits.md +0 -0
  270. {codevira-2.1.2 → codevira-3.0.0}/rules/incremental-updates.md +0 -0
  271. {codevira-2.1.2 → codevira-3.0.0}/rules/master_rule.md +0 -0
  272. {codevira-2.1.2 → codevira-3.0.0}/rules/persistence.md +0 -0
  273. {codevira-2.1.2 → codevira-3.0.0}/rules/resilience-observability.md +0 -0
  274. {codevira-2.1.2 → codevira-3.0.0}/rules/smoke-testing.md +0 -0
  275. {codevira-2.1.2 → codevira-3.0.0}/rules/testing-standards.md +0 -0
  276. {codevira-2.1.2 → codevira-3.0.0}/setup.cfg +0 -0
  277. {codevira-2.1.2 → codevira-3.0.0}/tests/test__prompts.py +0 -0
  278. {codevira-2.1.2 → codevira-3.0.0}/tests/test_chunker.py +0 -0
  279. {codevira-2.1.2 → codevira-3.0.0}/tests/test_cli_projects.py +0 -0
  280. {codevira-2.1.2 → codevira-3.0.0}/tests/test_dedupe_migration.py +0 -0
  281. {codevira-2.1.2 → codevira-3.0.0}/tests/test_detect.py +0 -0
  282. {codevira-2.1.2 → codevira-3.0.0}/tests/test_ghost_check.py +0 -0
  283. {codevira-2.1.2 → codevira-3.0.0}/tests/test_global_db.py +0 -0
  284. {codevira-2.1.2 → codevira-3.0.0}/tests/test_hook_resilience.py +0 -0
@@ -9,7 +9,591 @@ 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.
13
597
 
14
598
  ## [2.1.2] — 2026-05-19 — Trust recovery + QoL
15
599