codevira 1.7.1__tar.gz → 2.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 (236) hide show
  1. {codevira-1.7.1 → codevira-2.0.0}/CHANGELOG.md +512 -0
  2. {codevira-1.7.1/codevira.egg-info → codevira-2.0.0}/PKG-INFO +206 -34
  3. {codevira-1.7.1 → codevira-2.0.0}/README.md +203 -31
  4. codevira-2.0.0/agents/qa/01-code-review.md +57 -0
  5. codevira-2.0.0/agents/qa/02-adversarial-fix-review.md +57 -0
  6. codevira-2.0.0/agents/qa/03-cross-module-impact.md +57 -0
  7. codevira-2.0.0/agents/qa/06-doc-drift.md +47 -0
  8. codevira-2.0.0/agents/qa/07-security-audit.md +73 -0
  9. codevira-2.0.0/agents/qa/12-llm-redteam.md +53 -0
  10. codevira-2.0.0/agents/qa/13-multi-ide-schema.md +62 -0
  11. codevira-2.0.0/agents/qa/22-competitor-benchmark.md +70 -0
  12. codevira-2.0.0/agents/qa/README.md +73 -0
  13. codevira-2.0.0/agents/qa/tier2-scripts.md +242 -0
  14. codevira-2.0.0/agents/qa/tier3-manual.md +167 -0
  15. {codevira-1.7.1 → codevira-2.0.0/codevira.egg-info}/PKG-INFO +206 -34
  16. codevira-2.0.0/codevira.egg-info/SOURCES.txt +229 -0
  17. codevira-2.0.0/docs/alpha-tester-invites.md +124 -0
  18. codevira-2.0.0/docs/demo/README.md +69 -0
  19. codevira-2.0.0/docs/heroes/00-engine.md +388 -0
  20. codevira-2.0.0/docs/heroes/01-decision-lock.md +271 -0
  21. codevira-2.0.0/docs/heroes/02-anti-regression.md +269 -0
  22. codevira-2.0.0/docs/heroes/03-scope-contract.md +272 -0
  23. codevira-2.0.0/docs/heroes/04-blast-radius.md +298 -0
  24. codevira-2.0.0/docs/heroes/05-cross-session.md +300 -0
  25. codevira-2.0.0/docs/heroes/06-token-budget.md +292 -0
  26. codevira-2.0.0/docs/heroes/07-live-style.md +272 -0
  27. codevira-2.0.0/docs/heroes/08-decision-replay.md +295 -0
  28. codevira-2.0.0/docs/heroes/09-intent-inference.md +257 -0
  29. codevira-2.0.0/docs/heroes/10-ai-promotion.md +331 -0
  30. codevira-2.0.0/docs/heroes/README.md +51 -0
  31. codevira-2.0.0/docs/heroes/pillar-1-setup.md +392 -0
  32. codevira-2.0.0/docs/hn-launch-day.md +224 -0
  33. codevira-2.0.0/docs/local-pypi-https.md +184 -0
  34. codevira-2.0.0/docs/qa-playbook.md +400 -0
  35. codevira-2.0.0/docs/v2-completion-plan.md +211 -0
  36. codevira-2.0.0/docs/v2-execution-log.md +2582 -0
  37. codevira-2.0.0/docs/v2-master-plan.md +251 -0
  38. codevira-2.0.0/docs/vs-other-memory-tools.md +110 -0
  39. codevira-2.0.0/indexer/__init__.py +7 -0
  40. codevira-2.0.0/indexer/_dedupe_migration.py +101 -0
  41. codevira-2.0.0/indexer/_fork_safety.py +69 -0
  42. codevira-2.0.0/indexer/_sqlite_util.py +84 -0
  43. codevira-2.0.0/indexer/fix_history.py +626 -0
  44. {codevira-1.7.1 → codevira-2.0.0}/indexer/global_db.py +54 -4
  45. {codevira-1.7.1 → codevira-2.0.0}/indexer/index_codebase.py +349 -58
  46. {codevira-1.7.1 → codevira-2.0.0}/indexer/outcome_tracker.py +89 -4
  47. {codevira-1.7.1 → codevira-2.0.0}/indexer/sqlite_graph.py +296 -22
  48. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/__init__.py +1 -1
  49. codevira-2.0.0/mcp_server/_ghost_check.py +88 -0
  50. codevira-2.0.0/mcp_server/_project_inventory.py +276 -0
  51. codevira-2.0.0/mcp_server/_prompts.py +82 -0
  52. codevira-2.0.0/mcp_server/_repair_init.py +126 -0
  53. codevira-2.0.0/mcp_server/_safe_crash.py +58 -0
  54. codevira-2.0.0/mcp_server/agents_md.py +436 -0
  55. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/auto_init.py +69 -6
  56. codevira-2.0.0/mcp_server/cli.py +1923 -0
  57. codevira-2.0.0/mcp_server/cli_agents.py +220 -0
  58. codevira-2.0.0/mcp_server/cli_budget.py +213 -0
  59. codevira-2.0.0/mcp_server/cli_configure.py +855 -0
  60. codevira-2.0.0/mcp_server/cli_hooks_admin.py +184 -0
  61. codevira-2.0.0/mcp_server/cli_insights.py +337 -0
  62. codevira-2.0.0/mcp_server/cli_projects.py +139 -0
  63. codevira-2.0.0/mcp_server/cli_replay.py +136 -0
  64. codevira-2.0.0/mcp_server/data/__pycache__/__init__.cpython-313.pyc +0 -0
  65. codevira-2.0.0/mcp_server/data/hooks/post_tool_use.sh +37 -0
  66. codevira-2.0.0/mcp_server/data/hooks/pre_tool_use.sh +57 -0
  67. codevira-2.0.0/mcp_server/data/hooks/session_start.sh +41 -0
  68. codevira-2.0.0/mcp_server/data/hooks/stop.sh +40 -0
  69. codevira-2.0.0/mcp_server/data/hooks/user_prompt_submit.sh +42 -0
  70. codevira-2.0.0/mcp_server/data/templates/agents_md.tmpl +3 -0
  71. codevira-2.0.0/mcp_server/data/templates/canonical_block.md +81 -0
  72. codevira-2.0.0/mcp_server/data/templates/claude_md.tmpl +3 -0
  73. codevira-2.0.0/mcp_server/data/templates/copilot_instructions.tmpl +3 -0
  74. codevira-2.0.0/mcp_server/data/templates/cursor_rules.mdc.tmpl +8 -0
  75. codevira-2.0.0/mcp_server/data/templates/gemini_md.tmpl +3 -0
  76. codevira-2.0.0/mcp_server/data/templates/windsurfrules.tmpl +3 -0
  77. codevira-2.0.0/mcp_server/decision_replay.py +424 -0
  78. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/detect.py +76 -3
  79. codevira-2.0.0/mcp_server/doctor.py +771 -0
  80. codevira-2.0.0/mcp_server/engine/__init__.py +85 -0
  81. codevira-2.0.0/mcp_server/engine/demo_policy.py +62 -0
  82. codevira-2.0.0/mcp_server/engine/events.py +125 -0
  83. codevira-2.0.0/mcp_server/engine/intent_classifier.py +214 -0
  84. codevira-2.0.0/mcp_server/engine/policies/__init__.py +44 -0
  85. codevira-2.0.0/mcp_server/engine/policies/_signature_detect.py +314 -0
  86. codevira-2.0.0/mcp_server/engine/policies/ai_promotion.py +337 -0
  87. codevira-2.0.0/mcp_server/engine/policies/anti_regression.py +190 -0
  88. codevira-2.0.0/mcp_server/engine/policies/blast_radius.py +262 -0
  89. codevira-2.0.0/mcp_server/engine/policies/cross_session.py +363 -0
  90. codevira-2.0.0/mcp_server/engine/policies/decision_lock.py +255 -0
  91. codevira-2.0.0/mcp_server/engine/policies/intent_inference.py +421 -0
  92. codevira-2.0.0/mcp_server/engine/policies/live_style.py +445 -0
  93. codevira-2.0.0/mcp_server/engine/policies/scope_contract.py +362 -0
  94. codevira-2.0.0/mcp_server/engine/policies/token_budget.py +100 -0
  95. codevira-2.0.0/mcp_server/engine/policy.py +160 -0
  96. codevira-2.0.0/mcp_server/engine/promotion_score.py +208 -0
  97. codevira-2.0.0/mcp_server/engine/runner.py +263 -0
  98. codevira-2.0.0/mcp_server/engine/scope_contract.py +201 -0
  99. codevira-2.0.0/mcp_server/engine/signals.py +436 -0
  100. codevira-2.0.0/mcp_server/engine/token_meter.py +337 -0
  101. codevira-2.0.0/mcp_server/engine/wiring/__init__.py +16 -0
  102. codevira-2.0.0/mcp_server/engine/wiring/claude_code_hooks.py +368 -0
  103. codevira-2.0.0/mcp_server/engine/wiring/mcp_dispatch.py +186 -0
  104. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/http_server.py +26 -0
  105. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/ide_inject.py +223 -7
  106. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/paths.py +98 -4
  107. codevira-2.0.0/mcp_server/roadmap_drift.py +249 -0
  108. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/server.py +307 -11
  109. codevira-2.0.0/mcp_server/setup_wizard.py +893 -0
  110. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/graph.py +162 -6
  111. codevira-2.0.0/mcp_server/tools/learning.py +575 -0
  112. codevira-2.0.0/mcp_server/tools/playbook.py +205 -0
  113. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/search.py +120 -5
  114. {codevira-1.7.1 → codevira-2.0.0}/pyproject.toml +3 -3
  115. codevira-2.0.0/tests/test__prompts.py +138 -0
  116. {codevira-1.7.1 → codevira-2.0.0}/tests/test_auto_init.py +75 -3
  117. codevira-2.0.0/tests/test_call_edge_fk_safety.py +162 -0
  118. {codevira-1.7.1 → codevira-2.0.0}/tests/test_chunker.py +18 -7
  119. {codevira-1.7.1 → codevira-2.0.0}/tests/test_cli.py +305 -0
  120. codevira-2.0.0/tests/test_cli_agents.py +375 -0
  121. codevira-2.0.0/tests/test_cli_configure.py +1075 -0
  122. codevira-2.0.0/tests/test_cli_insights.py +159 -0
  123. codevira-2.0.0/tests/test_cli_projects.py +224 -0
  124. codevira-2.0.0/tests/test_cli_replay.py +234 -0
  125. codevira-2.0.0/tests/test_cli_version.py +51 -0
  126. codevira-2.0.0/tests/test_dedupe_migration.py +249 -0
  127. {codevira-1.7.1 → codevira-2.0.0}/tests/test_detect.py +78 -11
  128. codevira-2.0.0/tests/test_doctor.py +424 -0
  129. codevira-2.0.0/tests/test_fk_safety_extended.py +178 -0
  130. codevira-2.0.0/tests/test_fork_safety.py +206 -0
  131. codevira-2.0.0/tests/test_ghost_check.py +116 -0
  132. codevira-2.0.0/tests/test_hook_resilience.py +283 -0
  133. {codevira-1.7.1 → codevira-2.0.0}/tests/test_http_server.py +11 -4
  134. {codevira-1.7.1 → codevira-2.0.0}/tests/test_ide_inject.py +232 -8
  135. {codevira-1.7.1 → codevira-2.0.0}/tests/test_index_codebase.py +454 -0
  136. {codevira-1.7.1 → codevira-2.0.0}/tests/test_outcome_tracker.py +51 -0
  137. {codevira-1.7.1 → codevira-2.0.0}/tests/test_paths.py +119 -0
  138. codevira-2.0.0/tests/test_record_decision.py +274 -0
  139. codevira-2.0.0/tests/test_repair_init.py +191 -0
  140. codevira-2.0.0/tests/test_retire_rule.py +271 -0
  141. codevira-2.0.0/tests/test_roadmap_drift.py +385 -0
  142. {codevira-1.7.1 → codevira-2.0.0}/tests/test_server.py +134 -9
  143. codevira-2.0.0/tests/test_setup_wizard.py +836 -0
  144. {codevira-1.7.1 → codevira-2.0.0}/tests/test_sqlite_graph.py +362 -0
  145. codevira-2.0.0/tests/test_sqlite_util.py +115 -0
  146. {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_learning.py +307 -3
  147. {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_playbook.py +23 -10
  148. {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_search.py +20 -6
  149. codevira-2.0.0/tests/test_watcher_circuit.py +124 -0
  150. codevira-1.7.1/codevira.egg-info/SOURCES.txt +0 -117
  151. codevira-1.7.1/indexer/__init__.py +0 -1
  152. codevira-1.7.1/mcp_server/cli.py +0 -964
  153. codevira-1.7.1/mcp_server/tools/learning.py +0 -244
  154. codevira-1.7.1/mcp_server/tools/playbook.py +0 -89
  155. {codevira-1.7.1 → codevira-2.0.0}/LICENSE +0 -0
  156. {codevira-1.7.1 → codevira-2.0.0}/MANIFEST.in +0 -0
  157. {codevira-1.7.1 → codevira-2.0.0}/agents/builder.md +0 -0
  158. {codevira-1.7.1 → codevira-2.0.0}/agents/developer.md +0 -0
  159. {codevira-1.7.1 → codevira-2.0.0}/agents/documenter.md +0 -0
  160. {codevira-1.7.1 → codevira-2.0.0}/agents/orchestrator.md +0 -0
  161. {codevira-1.7.1 → codevira-2.0.0}/agents/planner.md +0 -0
  162. {codevira-1.7.1 → codevira-2.0.0}/agents/reviewer.md +0 -0
  163. {codevira-1.7.1 → codevira-2.0.0}/agents/tester.md +0 -0
  164. {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/dependency_links.txt +0 -0
  165. {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/entry_points.txt +0 -0
  166. {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/requires.txt +0 -0
  167. {codevira-1.7.1 → codevira-2.0.0}/codevira.egg-info/top_level.txt +0 -0
  168. {codevira-1.7.1 → codevira-2.0.0}/config.example.yaml +0 -0
  169. {codevira-1.7.1 → codevira-2.0.0}/docs/how-i-built-persistent-memory-for-ai-agents.md +0 -0
  170. {codevira-1.7.1 → codevira-2.0.0}/docs/linkedin-article-ai-agent-memory.md +0 -0
  171. {codevira-1.7.1 → codevira-2.0.0}/docs/linkedin-post-ai-agent-memory.md +0 -0
  172. {codevira-1.7.1 → codevira-2.0.0}/docs/medium-your-ai-coding-agent-has-amnesia.md +0 -0
  173. {codevira-1.7.1 → codevira-2.0.0}/docs/roadmap.md +0 -0
  174. {codevira-1.7.1 → codevira-2.0.0}/graph/_schema.yaml +0 -0
  175. {codevira-1.7.1 → codevira-2.0.0}/indexer/chunker.py +0 -0
  176. {codevira-1.7.1 → codevira-2.0.0}/indexer/graph_generator.py +0 -0
  177. {codevira-1.7.1 → codevira-2.0.0}/indexer/rule_learner.py +0 -0
  178. {codevira-1.7.1 → codevira-2.0.0}/indexer/treesitter_parser.py +0 -0
  179. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/__main__.py +0 -0
  180. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/crash_logger.py +0 -0
  181. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/__init__.py +0 -0
  182. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/builder.md +0 -0
  183. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/developer.md +0 -0
  184. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/documenter.md +0 -0
  185. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/orchestrator.md +0 -0
  186. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/planner.md +0 -0
  187. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/reviewer.md +0 -0
  188. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/agents/tester.md +0 -0
  189. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/config.example.yaml +0 -0
  190. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/coding-standards.md +0 -0
  191. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/engineering-excellence.md +0 -0
  192. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/git-cicd-governance.md +0 -0
  193. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/git_commits.md +0 -0
  194. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/incremental-updates.md +0 -0
  195. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/master_rule.md +0 -0
  196. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/multi-language.md +0 -0
  197. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/persistence.md +0 -0
  198. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/resilience-observability.md +0 -0
  199. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/smoke-testing.md +0 -0
  200. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/data/rules/testing-standards.md +0 -0
  201. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/gitignore.py +0 -0
  202. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/global_sync.py +0 -0
  203. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/launchd.py +0 -0
  204. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/log_retention.py +0 -0
  205. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/migrate.py +0 -0
  206. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/prompts.py +0 -0
  207. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/__init__.py +0 -0
  208. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/changesets.py +0 -0
  209. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/code_reader.py +0 -0
  210. {codevira-1.7.1 → codevira-2.0.0}/mcp_server/tools/roadmap.py +0 -0
  211. {codevira-1.7.1 → codevira-2.0.0}/rules/coding-standards.md +0 -0
  212. {codevira-1.7.1 → codevira-2.0.0}/rules/engineering-excellence.md +0 -0
  213. {codevira-1.7.1 → codevira-2.0.0}/rules/git-cicd-governance.md +0 -0
  214. {codevira-1.7.1 → codevira-2.0.0}/rules/git_commits.md +0 -0
  215. {codevira-1.7.1 → codevira-2.0.0}/rules/incremental-updates.md +0 -0
  216. {codevira-1.7.1 → codevira-2.0.0}/rules/master_rule.md +0 -0
  217. {codevira-1.7.1 → codevira-2.0.0}/rules/persistence.md +0 -0
  218. {codevira-1.7.1 → codevira-2.0.0}/rules/resilience-observability.md +0 -0
  219. {codevira-1.7.1 → codevira-2.0.0}/rules/smoke-testing.md +0 -0
  220. {codevira-1.7.1 → codevira-2.0.0}/rules/testing-standards.md +0 -0
  221. {codevira-1.7.1 → codevira-2.0.0}/setup.cfg +0 -0
  222. {codevira-1.7.1 → codevira-2.0.0}/tests/test_crash_logger.py +0 -0
  223. {codevira-1.7.1 → codevira-2.0.0}/tests/test_gitignore.py +0 -0
  224. {codevira-1.7.1 → codevira-2.0.0}/tests/test_global_db.py +0 -0
  225. {codevira-1.7.1 → codevira-2.0.0}/tests/test_global_sync.py +0 -0
  226. {codevira-1.7.1 → codevira-2.0.0}/tests/test_graph_generator.py +0 -0
  227. {codevira-1.7.1 → codevira-2.0.0}/tests/test_launchd.py +0 -0
  228. {codevira-1.7.1 → codevira-2.0.0}/tests/test_log_retention.py +0 -0
  229. {codevira-1.7.1 → codevira-2.0.0}/tests/test_migrate.py +0 -0
  230. {codevira-1.7.1 → codevira-2.0.0}/tests/test_prompts.py +0 -0
  231. {codevira-1.7.1 → codevira-2.0.0}/tests/test_rule_learner.py +0 -0
  232. {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_changesets.py +0 -0
  233. {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_code_reader.py +0 -0
  234. {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_graph.py +0 -0
  235. {codevira-1.7.1 → codevira-2.0.0}/tests/test_tools_roadmap.py +0 -0
  236. {codevira-1.7.1 → codevira-2.0.0}/tests/test_treesitter_parser.py +0 -0
@@ -11,6 +11,518 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
11
11
 
12
12
  ## [Unreleased]
13
13
 
14
+ ### Planned for v2.1
15
+
16
+ See [ROADMAP.md](ROADMAP.md#-v21--honest-known-limitations-from-the-rc5-audit-2026-05-13).
17
+
18
+ - **Multi-language `get_signature` / `get_code`** — wire tree-sitter (already
19
+ used for graph indexing) into these tools so non-Python projects stop
20
+ getting "Python-only by design".
21
+ - **`record_decisions_batch` API** — compress 50× ~800 B per-call overhead
22
+ into one round-trip.
23
+ - **CLI naming clarity** — pick a canonical hierarchy among `init` / `setup` /
24
+ `register` / `configure`; add a `codevira inspect` umbrella; deprecate one
25
+ of `--project-dir` (global) / `--project PATH` (per-subcommand) on a
26
+ v2.1 → v2.2 cycle.
27
+
28
+ ---
29
+
30
+ ## [2.0.0] — 2026-05-14 — First public 2.0 release
31
+
32
+ The 2.0 release moves codevira from "memory layer for one developer in one IDE" to
33
+ "active guardian for every AI coding tool you use, on every project, on your local
34
+ machine." Five internal iterations (rc1..rc5 in dev tags) plus a same-day public
35
+ release-candidate cycle (`2.0.0rc1`) of dogfood + audit + product-credibility
36
+ work consolidate into 2.0.0. **Full changelog: [RELEASE_NOTES.md](RELEASE_NOTES.md).**
37
+
38
+ ### Added
39
+
40
+ - **All 10 hero policies** — active guardian engine intercepts every AI tool
41
+ call (Edit, Write, prompt submit, session start) and routes through
42
+ registered policies (Decision Lock, Anti-Regression, Scope Contract,
43
+ Blast-Radius Veto, Cross-Session Consistency, Token Budget, Live Style
44
+ Enforcement, Decision Replay, Proactive Intent Inference, AI Promotion
45
+ Score).
46
+ - **`codevira setup`** — one-prompt installer that detects every AI tool
47
+ on the machine (Claude Code, Cursor, Windsurf, Antigravity, OpenAI Codex,
48
+ GitHub Copilot, Continue.dev, Aider) and configures all of them at once.
49
+ - **`codevira projects`** — canonical inventory with `tracked / ghost /
50
+ orphan / stale` classification (`--json` for scripting; `--ghosts-only`
51
+ pairs with `clean --ghosts`).
52
+ - **`codevira hooks list / uninstall`** — admin commands for Claude Code
53
+ lifecycle hooks; surgical install + clean removal.
54
+ - **`codevira clean --ghosts`** — surgical removal of incomplete project
55
+ data dirs without touching tracked projects.
56
+ - **`codevira init --single-language`** — opt-out flag for the new
57
+ index-everything default.
58
+ - **`codevira engine` subcommand** — internal hook dispatcher; surfaces in
59
+ `--help` so the lifecycle hooks can call it.
60
+ - **4 new doctor checks** — `claude_mcp_visibility`, `codeindex_freshness`,
61
+ `semantic_search_health`, `ghost_projects` (total 14 per run).
62
+ - **Per-project config opt-out for cross-session injection** —
63
+ `.codevira/config.yaml: project: { cross_session_mode: off }` disables
64
+ the per-prompt context block without touching env vars.
65
+
66
+ ### Changed
67
+
68
+ - **`codevira init` default** — indexes every common source/config/docs
69
+ extension (~75 total: `.py`, `.ts`, `.go`, `.yaml`, `.toml`, `.md`,
70
+ `.html`, `.sql`, `.proto`, …) instead of narrowing to one language.
71
+ - **`codevira agents` default** — renders nudge files for **detected** IDEs
72
+ only; `--ide=all` opt-in for the legacy "render for every supported IDE"
73
+ behavior.
74
+ - **`codevira doctor`** — now genuinely read-only; snapshots the projects
75
+ dir at entry and removes any new dirs at exit.
76
+ - **`search_codebase`** — graceful structural fallback (filename + symbol
77
+ substring) when the semantic index is unavailable, with the correct
78
+ `fix_command` instead of a misleading "reinstall codevira" hint.
79
+ - **`get_node` / `get_impact` / `query_graph`** — three-case error
80
+ differentiation: "no graph DB" / "graph empty" / "file not in populated
81
+ graph", each with its own `fix_command`.
82
+ - **`get_decision_confidence`** — exposes `decisions_in_db_total` and
83
+ `decisions_eligible_for_outcomes` plus a four-state interpretation so
84
+ users understand WHY their `total_decisions` may be zero. Outcome
85
+ tracker also classifies file-less decisions via mention-extraction.
86
+ - **Playbooks** — project-scoped first
87
+ (`<data_dir>/playbooks/` or `<project>/.codevira/playbooks/`); bundled
88
+ Python defaults are skipped with a clear warning when project language
89
+ ≠ Python.
90
+ - **`register_project`** uses `ON CONFLICT … COALESCE(excluded.git_remote,
91
+ projects.git_remote)` — subsequent registrations can't silently clear
92
+ the `git_remote` column.
93
+ - **Auto-init self-heal** runs SYNCHRONOUSLY in the calling thread of every
94
+ CLI invocation — daemon thread death no longer leaves ghost data dirs.
95
+ - **Default install** includes ChromaDB + sentence-transformers (no
96
+ `[search]` extra needed for semantic search).
97
+ - **README "92% reduction" claim** qualified with honest scope, per-prompt
98
+ cost, and amortization curve.
99
+ - **`register` deprecation** now names the removal version (v2.1).
100
+
101
+ ### Fixed
102
+
103
+ - macOS Apple Silicon **fork-safety segfault on first `codevira index`**
104
+ (auto-applied at indexer import).
105
+ - **Setup interactive prompt** silent-fail on unexpected input — replaced
106
+ with a shared `_prompts.confirm` helper that retries, flushes stdout,
107
+ and handles `KeyboardInterrupt` cleanly.
108
+ - Three **`status --global` UI typos** that always rendered 0/0/0
109
+ regardless of actual `global.db` state.
110
+ - Four **FK race conditions** in the watcher pipeline.
111
+ - **Python `None` leaked into argparse choices** for `agents --ide` and
112
+ `budget` positional.
113
+ - Several **silent argument clamps** in `replay --since`, `insights --since`,
114
+ and `insights --top` now print visible warnings.
115
+
116
+ ### Tests
117
+
118
+ - 2395 / 2395 passing (deterministic).
119
+ - ~1091 net new tests since v1.8.0 (mostly from the v2.0 hero policies +
120
+ audit-driven regression coverage).
121
+
122
+ ### Note on internal v1.8.1 + 2.0.0rc1
123
+
124
+ A v1.8.1 production hotfix existed in dev tags but was never published to
125
+ PyPI; its fixes are folded into 2.0.0. A `2.0.0rc1` was briefly published
126
+ on PyPI (2026-05-14) as a same-day public release candidate; the code is
127
+ identical to 2.0.0. Anyone who installed `codevira==2.0.0rc1` can
128
+ `pipx install --upgrade codevira` to move to 2.0.0 final.
129
+
130
+ ---
131
+
132
+ ## [Original v1.9 plan, deferred]
133
+
134
+ - **Interactive checkbox UI for `codevira configure`**. The current
135
+ prompt asks users to type comma-separated indices ("1,3,5") into a
136
+ numbered list — fine for 3–5 items, awkward for 15+. v1.9 will add
137
+ arrow-key navigation + space-to-toggle multi-select, matching the
138
+ UX of `npm create vite`, `gh repo create`, etc.
139
+
140
+ **Design (opt-in dependency):**
141
+ - Default install (`pip install codevira`) keeps the current numbered
142
+ prompt — zero new dependencies, zero new failure modes.
143
+ - `pip install codevira[ui]` pulls `questionary` (~3 MB). When
144
+ importable AND `sys.stdin.isatty()` AND `os.environ.get("TERM")
145
+ != "dumb"`, `prompt_multi_select` switches to the checkbox UI.
146
+ - `--dirs` and `--extensions` flags continue to work for both paths
147
+ (CI / scripts / non-interactive use).
148
+
149
+ **Why deferred from v1.8.1:** v1.8.1 is a pure crash hotfix; mixing
150
+ in a UX feature would slow the release and complicate testing. The
151
+ numbered prompt has shipped since v1.8.0 and works fine — this is
152
+ polish, not a fix.
153
+
154
+ **Implementation notes for whoever picks this up:**
155
+ - Site: `mcp_server/cli_configure.py:prompt_multi_select` (line ~176)
156
+ - Add `[ui]` extra in `pyproject.toml` with `questionary>=2.0`
157
+ - TTY detection already exists (`NonInteractiveError` raised on
158
+ `not sys.stdin.isatty()`); extend it to also branch on
159
+ questionary availability
160
+ - Test surface: split into two test classes — one mocks `input()`
161
+ (current behavior), one mocks `questionary.checkbox()`. Skip the
162
+ questionary tests when not installed.
163
+ - Accessibility: keep the numbered prompt for screen-reader users;
164
+ document `CODEVIRA_DISABLE_TUI=1` env var as the override.
165
+ - No schema changes, no public-API changes.
166
+
167
+ ### Other v1.9 candidates (no design yet)
168
+
169
+ - Watcher restart circuit breaker (deferred from v1.8.1 — see "Out of
170
+ scope" below).
171
+ - Refactor `_enable_wal_with_retry` into a shared `indexer/_sqlite_util.py`
172
+ (deferred from v1.8.1).
173
+ - Watcher hot-reload of `config.yaml` on disk changes.
174
+ - `crash_logger` size cap or rotation (currently grows unbounded).
175
+
176
+ ---
177
+
178
+ ## [1.8.1] — 2026-05-02 — Production Hotfix from Real-World Crash Logs
179
+
180
+ Pure bug-fix release. No new features, no schema changes, no public-API
181
+ changes. Motivated by a real production failure on the maintainer's
182
+ machine: **43 crashes in 70 minutes** logged by `crash_logger` between
183
+ 07:37 and 08:47 on 2026-04-24, all under
184
+ `WHERE: background watcher: incremental reindex`.
185
+
186
+ Breakdown:
187
+ - **41 × `InterruptedError` (EINTR, errno 4)** in
188
+ `_get_changed_files`'s rglob walk, all walking
189
+ `~/Library/Group Containers/...` (WhatsApp, Office, etc.) and
190
+ `~/Library/Containers/...` (TextEdit, mediaanalysisd, …).
191
+ - **2 × `OperationalError("database is locked")`** in
192
+ `SQLiteGraph.add_symbol` and `remove_symbols_for_file`.
193
+
194
+ Root cause: a rogue project data dir with
195
+ `metadata.json.original_path = "/Users/sachin"` (the user's `$HOME`).
196
+ `auto_detect_project` saw `Library`, `Downloads`, `Documents`, `go` as
197
+ "subdirs", and the watcher then walked huge unrelated trees. v1.8.0's
198
+ bootstrap (`cmd_configure`, `auto_init`) didn't refuse `$HOME`, and
199
+ neither did `cmd_init`.
200
+
201
+ ### Fixed
202
+
203
+ - **Refuse `$HOME` and system top-levels as a project root** (the
204
+ critical fix — eliminates 41 of the 43 production crashes by
205
+ preventing the rogue project from forming). New helper
206
+ `mcp_server.paths.is_invalid_project_root()` rejects `$HOME`, `/`,
207
+ `/Users`, `/home`, `/tmp`, `/private/tmp`, `/var`, `/private/var`,
208
+ `/etc`, `/opt` (plus the macOS-resolved `/private/etc` and
209
+ `/System/Volumes/Data/home` forms). Wired into TEN distinct sites
210
+ covering every state-creating path the codebase exposes:
211
+ - **CLI entry points (6):** `cmd_configure`, `cmd_init`, `cmd_index`,
212
+ `cmd_register`, `cmd_serve` (refuses both regular serve AND
213
+ `--install-service`; `--uninstall-service` is exempt so users can
214
+ always remove old launchd plists), `auto_init._run_background_init`.
215
+ - **MCP server entry points (2):** `mcp_server.server.main()` (stdio
216
+ transport) and `mcp_server.http_server.run_http_server()` (HTTP
217
+ transport). Both are reachable directly via `python -m`, not just
218
+ through the CLI.
219
+ - **Direct module entry (1):** `indexer.index_codebase.__main__`
220
+ (`python -m indexer.index_codebase --full | --watch | (default)`)
221
+ — this is a separate CLI surface from the `codevira` binary;
222
+ pre-revalidation it bypassed `cli.cmd_index`'s guard entirely.
223
+ `--status` is exempt (read-only, bails on missing graph.db).
224
+ - **Defense-in-depth (1):** `indexer.index_codebase.start_background_watcher`
225
+ refuses to start the watcher even if a programmatic caller bypasses
226
+ every entry-point guard above. Returns `None`; both `cmd_watch` and
227
+ `server.main` handle `None` correctly.
228
+
229
+ The `server.main()` and `run_http_server` guards are the most critical
230
+ — without them, a user upgrading from v1.8.0 *without* first running
231
+ `clean --orphans` would still hit the original crash mode: their
232
+ leftover rogue `config.yaml` would drive `start_background_watcher`
233
+ into walking `~/Library/Group Containers/...`, which is exactly where
234
+ the 41 production `InterruptedError` crashes came from. The
235
+ `start_background_watcher` defense-in-depth guard is a belt-and-braces
236
+ fallback — even if all entry-point guards regressed, the watcher
237
+ itself cannot start with an invalid project root.
238
+
239
+ `cmd_index`, `cmd_register`, `cmd_serve --install-service` close
240
+ defense-in-depth holes that pre-revalidation could have leaked state
241
+ on disk: silent dead-weight `mkdir` of
242
+ `~/.codevira/projects/<HOME_slug>/{graph,codeindex}/`, IDE configs
243
+ pinned to broken paths, and persistent launchd plists pointing at
244
+ `$HOME`. Pre-release revalidation across three rounds walked every
245
+ CLI sub-command, the stdio/HTTP server entry, the launchd
246
+ `--install-service` path, the `start_background_watcher` direct call
247
+ path, and the production-replay scenario (synthetic v1.8.0 leftover
248
+ rogue + `codevira` from `$HOME`). All paths refuse cleanly with zero
249
+ new crashes; legitimate projects untouched.
250
+
251
+ `auto_init` sets `_progress["status"] = "error"` so the MCP server
252
+ stops looping on retries.
253
+
254
+ - **`SQLiteGraph` WAL with retry — port of the v1.8.0 GlobalDB fix**
255
+ (eliminates the 2 of 43 `database is locked` crashes). v1.8.0 fixed
256
+ the same race for `GlobalDB` after round 3 of binocular review;
257
+ `SQLiteGraph` was missed. `__init__` now opens with `timeout=30`,
258
+ enables WAL via the same retry loop pattern, and sets
259
+ `PRAGMA busy_timeout=30000` for subsequent writes.
260
+
261
+ - **`_get_changed_files` and `cmd_full_rebuild` rglob loops tolerate
262
+ `OSError`** (defense-in-depth — even on legitimate projects,
263
+ transient `EINTR`, `PermissionError`, or "directory changed during
264
+ iteration" should not kill the whole reindex). Per-watch-dir scope
265
+ matches `watchdog.Observer`'s thread-per-watch model: the
266
+ microsecond-spaced parallel-thread crashes (3 within 6μs at
267
+ 08:15:29 and 08:26:04 in the production log) confirm this is the
268
+ right granularity. `InterruptedError` is a subclass of `OSError`, so
269
+ the broader catch covers EINTR plus other transient walk failures.
270
+
271
+ ### Added
272
+
273
+ - **`codevira clean --orphans`** — recovery path for users already hit
274
+ by the `$HOME`-bootstrap bug on v1.8.0. Walks
275
+ `~/.codevira/projects/*/metadata.json`; for each entry whose
276
+ `original_path` is rejected by `is_invalid_project_root()` OR no
277
+ longer exists on disk, removes the data dir and deletes the matching
278
+ row from `~/.codevira/global.db`. Reuses the existing `--dry-run`
279
+ and `-y/--yes` flags. Without this, affected users would need to
280
+ `rm -rf` and run raw sqlite by hand.
281
+
282
+ - **Denylist macOS/Linux/cloud-sync user-data dirs in
283
+ `auto_detect_project`** (defense-in-depth). `_SKIP_DIRS` extended
284
+ with `Library`, `Downloads`, `Music`, `Movies`, `Pictures`,
285
+ `Desktop`, `Public`, `Applications`, `Videos`, `Templates`, plus
286
+ cloud-sync top-levels (`Dropbox`, `iCloud Drive`, `OneDrive`,
287
+ `Google Drive`, `Box`). Even if `is_invalid_project_root` somehow
288
+ misses (e.g. a user passes `--project-dir` to a `$HOME`-shaped
289
+ layout), these never show up in `watched_dirs`. A user who
290
+ legitimately has a project named e.g. `Library` can still pass
291
+ `codevira configure --dirs Library` to opt in.
292
+
293
+ ### Out of scope (deferred to v1.9)
294
+
295
+ - **Watcher restart circuit breaker.** Crash log shows ~60s gaps
296
+ between EINTR crashes — no backoff. Adding a circuit breaker is real
297
+ design work; the rglob `OSError` tolerance closes the immediate
298
+ hole.
299
+ - **Refactoring `_enable_wal_with_retry` to a shared util.** 25 lines
300
+ of duplication for one patch cycle is the right call; touching
301
+ `GlobalDB`'s tested-in-v1.8.0 code is higher risk.
302
+ - **`crash_logger` size cap or rotation.** Log file is ~97KB now; will
303
+ grow unbounded over time. Out of scope for hotfix; flagged for v1.9.
304
+
305
+ ---
306
+
307
+ ## [1.8.0] — 2026-04-23 — Memory Sharpening + Config UX
308
+
309
+ Three internal improvements that make the memory we already capture **sharper**,
310
+ without making it heavier. Zero new MCP tools. Zero new tables. The public API
311
+ shape changes only one thing: `get_session_context()` gains a `focus_source`
312
+ field (~10 tokens, additive, backwards-compatible).
313
+
314
+ The problem this release solves:
315
+ - `get_session_context()` returned the 3 newest decisions by timestamp —
316
+ regardless of whether they had anything to do with the current task.
317
+ - `search_decisions()` ordered purely by recency — a `file_path` match
318
+ was no better than a match buried in an unrelated session summary.
319
+ - `log_session()` inserted every decision unconditionally — a day of
320
+ iterative agent work logged the same intent 5+ times.
321
+
322
+ ### Fixed
323
+
324
+ - **MCP `serverInfo.version` reported the MCP library version, not codevira's**
325
+ (pre-existing bug, surfaced during v1.8 install verification on Python
326
+ 3.13). `Server("codevira")` was constructed without a `version=` argument,
327
+ so the framework defaulted to its own pip-package version (e.g. `1.27.0`)
328
+ in the JSON-RPC `initialize` handshake response. Clients use this field
329
+ for telemetry and version gating, so the wrong value misled them.
330
+ One-line fix: `Server("codevira", version=__version__)`.
331
+ - **`get_session_context()` read the wrong dict key** (pre-existing bug).
332
+ `list_open_changesets()` returns `{"open_changesets": [...], ...}`, but
333
+ `get_session_context` looked for `"changesets"`. The `open_changesets`
334
+ field in the session-context response was **always empty** in production.
335
+ Tests didn't catch it because mocks used the same wrong key.
336
+
337
+ - **`GlobalDB` concurrent-open race condition** (pre-existing bug — latent
338
+ since v1.6's centralized storage introduced shared `~/.codevira/global.db`).
339
+ `PRAGMA journal_mode=WAL` requires an exclusive lock and — unlike normal
340
+ SQL — does NOT honour `sqlite3`'s `busy_timeout`. When multiple processes
341
+ or threads opened the same fresh database concurrently (e.g. several
342
+ projects' first-ever `codevira register` running in parallel, or the
343
+ `global_sync` background export racing the MCP server thread), one or
344
+ more would raise `OperationalError('database is locked')` and silently
345
+ fail to register. The test `test_concurrent_access_from_threads` was
346
+ flaky at 60% failure rate, hinting at the real issue. Fixed with WAL-
347
+ enable retry loop + short-circuit when WAL is already active. Stability
348
+ verified at 20/20 passes across 20 test runs.
349
+
350
+ ### Changed
351
+
352
+ - **Focus-weighted `recent_decisions` in `get_session_context()`**. Instead
353
+ of chronological "newest 3", decisions are now ranked by what the agent
354
+ is currently focused on:
355
+ 1. Open changeset with `files_pending` → focus = first file path of the
356
+ most-recently-created changeset.
357
+ 2. Strong `current_phase.next_action` signal → focus = extracted keywords
358
+ (rejects short or stop-list-only actions like "continue work").
359
+ 3. Otherwise → chronological fallback (unchanged behaviour).
360
+ If focus returns fewer than 3, the list pads with `get_recent_decisions()`.
361
+ New response field `focus_source` (`"open_changeset:<id>"`, `"next_action"`,
362
+ or `null`) lets the agent see *why* it got these decisions.
363
+
364
+ - **Smarter `search_decisions()` ranking**. SQL now adds `file_path` to both
365
+ the WHERE clause and a CASE-based ORDER BY:
366
+ `file_path match (0) > decision text (1) > context (2) > summary-only (3)`,
367
+ then newest first within each tier. Searching for `"src/auth.py"` now
368
+ surfaces file-path matches even when the decision text doesn't mention
369
+ the path.
370
+
371
+ - **Decision dedup on write**. `log_session()` now skips a new decision
372
+ if it has a `file_path` and its token-set overlaps ≥ 80% with any of
373
+ the 5 most recent decisions for that same file. The session row is
374
+ always created; only redundant *decisions* are dropped. Short
375
+ decisions (< 3 tokens) and decisions without `file_path` are always
376
+ inserted.
377
+
378
+ ### Added
379
+
380
+ - `focus_source` field on `get_session_context()` response (≈10 tokens).
381
+ - `mcp_server.tools.learning._infer_focus()` — pure helper, module-private.
382
+ - `indexer.sqlite_graph._is_duplicate()` — pure token-overlap helper,
383
+ module-private, independently testable.
384
+ - **`codevira configure`** — new CLI subcommand. Scans your project
385
+ (gitignore-aware via existing `discover_source_files()`), shows discovered
386
+ directories and file extensions with counts, lets you pick via a numbered-
387
+ list prompt, writes the choices back to `.codevira/config.yaml`, and offers
388
+ to rebuild the index. Non-interactive:
389
+ `codevira configure --dirs src,lib --extensions .py,.ts --no-reindex`.
390
+ Solves the AgentStore-style "0 chunks indexed" case where
391
+ `auto_detect_project()` mis-guesses a monorepo layout.
392
+ When `config.yaml` is missing (normal state after `codevira register` but
393
+ before the first MCP tool call), `configure` auto-bootstraps it in full
394
+ parity with `auto_init`'s first-init path: writes `metadata.json` (rename-
395
+ resilient lookup via `git_remote`) and registers the project in
396
+ `~/.codevira/global.db` for cross-project intelligence. Missing these on
397
+ earlier drafts would have left the project invisible to rename-resilient
398
+ path lookup and absent from global memory until the first session log.
399
+ - **Zero-chunks safety hint at index time.** When `codevira index --full` or
400
+ `codevira index` (incremental, project-wide) matches no files against your
401
+ `watched_dirs` + `file_extensions`, the indexer now prints a one-line
402
+ remedy pointing at `codevira configure`. Output goes to **stderr** (not
403
+ stdout) so the hint never leaks into the MCP JSON-RPC wire when
404
+ `start_background_full_index` runs during auto_init inside the MCP server
405
+ process. Also logged at WARNING level so background invocations
406
+ (auto-init, launchd watcher) leave a trace regardless of terminal
407
+ capture. Does NOT fire for caller-scoped incremental runs (e.g. the
408
+ `refresh_index` MCP tool targeting a specific file) — zero matches there
409
+ is the caller's choice, not a misconfiguration.
410
+ - `codevira register` success banner now nudges toward `codevira configure`.
411
+
412
+ ### Internal
413
+
414
+ - 87 new tests:
415
+ - 34 for v1.8 memory sharpening (focus inference priority rules, ranking
416
+ tier ordering, dedup threshold behaviour, session-row-always-created
417
+ invariant, NULL file_path fallback, session_id filtering + new ranking SQL)
418
+ - 43 for `codevira configure` (scan_project with centralized-mode
419
+ decoupling + skip_dirs honoring, multi-select prompt incl. non-TTY
420
+ fallback + Ctrl+C clean-abort, config writer preserve/dedupe/idempotency,
421
+ orchestrator edge cases incl. bootstrap on missing config, dry-run disk
422
+ safety, corrupt-YAML handling, empty-extensions safety, PermissionError
423
+ friendly wrapper, `--dirs`/`--extensions` normalization)
424
+ - 10 for the zero-chunks hint (unit tests of the helper proving it writes
425
+ to stderr not stdout + integration tests proving it fires ONLY for full
426
+ or project-wide-incremental scans, not caller-scoped or normal "no files
427
+ changed")
428
+ - Full test suite: **1,398 passing, 0 deterministic failures** (up from
429
+ 1,306 at v1.7.1 → +92). The two "pre-existing watchdog failures" that
430
+ haunted earlier drafts of this CHANGELOG turned out to be an environment
431
+ issue in a single dev machine (system Python 3.9 without `watchdog`);
432
+ the pipx-installed v1.8.0 environment has all required deps. The one
433
+ pre-existing flaky test (`test_concurrent_access_from_threads`) is now
434
+ fixed by the `GlobalDB` WAL-enable retry loop described above.
435
+
436
+ ### Verified environments
437
+
438
+ - **macOS (APFS)** + Python 3.9 system + Python 3.11 pipx: full regression
439
+ passes; all interactive + non-interactive flows manually verified on three
440
+ real projects (AgentStore, UDAP, ToolsConnector).
441
+ - **Cross-process + thread concurrency**: stress-tested (12 threads × 20
442
+ writes, 8 subprocesses × 25 writes, 100 concurrent-read/write cycles) —
443
+ 0 errors, 0 data loss.
444
+
445
+ ### Unverified environments / known gaps (candidates for v1.8.1 or v1.9)
446
+
447
+ - **Windows**: `os.replace` atomicity weakens when the destination is open
448
+ by another process. If a Windows user has Claude Code reading
449
+ `config.yaml` at the moment `codevira configure` writes it, the write
450
+ may fail with `PermissionError`. Pre-existing risk; v1.8 does not fix
451
+ and does not regress. Windows smoke-testing is a v1.9 scope item.
452
+ - **Network filesystems (NFS, SMB)**: atomic-replace guarantees are weaker
453
+ on network FS. Unlikely in solo-dev environments (codevira's target);
454
+ possible in enterprise setups.
455
+ - **Python 3.10, 3.12**: The APIs `codevira configure` uses are stable
456
+ across 3.10+. Syntax-verified against 3.10+. **Python 3.13.7
457
+ empirically verified** during v1.8 install validation (full pipx
458
+ install + MCP handshake working). 3.10 and 3.12 are syntax-verified
459
+ only. CI on all Python versions is a v1.8.x task.
460
+ - **Case-insensitive filesystem slugs**: On macOS APFS (default), paths
461
+ differing only in case (`~/Documents` vs `~/documents`) produce
462
+ different slugs for the same physical directory, creating split state.
463
+ Pre-existing since v1.5 — fixing requires a migration step for existing
464
+ users and is scoped to v1.9.
465
+ - **Interactive TTY automated coverage**: The interactive prompt flow is
466
+ tested via mocked stdin + `sys.stdin.isatty`. A real terminal session
467
+ was manually verified during development; automated TTY testing (via
468
+ pexpect or similar) is a v1.8.x nice-to-have.
469
+ - **MCP client post-upgrade reload**: `codevira register` writes config;
470
+ each MCP client (Claude Code, Cursor, Windsurf, Antigravity, Claude
471
+ Desktop) needs to reload to see changes. Verified for Claude Code.
472
+ Other clients may have edge cases that surface post-release.
473
+
474
+ ### Known test flake (NOT v1.8; pre-existing)
475
+
476
+ - `test_chunk_error_continues_to_next_file` fails ~3/10 times in the full
477
+ suite on Python 3.9 (system) due to a chromadb+pydantic version
478
+ incompatibility raising `TypeError` during `import chromadb`, which
479
+ `_check_search_deps()` doesn't catch (it only catches `ImportError`).
480
+ **Not introduced by v1.8 and not touched by v1.8 code paths** — verified
481
+ by measuring the same 3/10 flake rate on clean v1.7.1. v1.8 deliberately
482
+ does not widen the exception catch because it would silently mask real
483
+ dep issues; a proper fix belongs in a targeted follow-up PR with its own
484
+ test coverage. Does not affect production users — the condition requires
485
+ a specific dev environment (Py 3.9 + mismatched chromadb/pydantic).
486
+ - Regression guards added by the binocular review pass:
487
+ - `test_centralized_mode_data_dir_and_project_root_decoupled` — catches
488
+ the production bug where `data_dir.parent` was used where
489
+ `get_project_root()` was required (centralized mode v1.6+).
490
+ - `test_bootstraps_config_when_missing` — catches the workflow where
491
+ `codevira register` was run but config.yaml hasn't been written yet
492
+ (auto_init hadn't fired because no MCP tool call had happened).
493
+ - `test_bootstrap_respects_dry_run` — catches bootstrap writing disk
494
+ during `--dry-run`.
495
+ - `test_fires_on_stderr_when_not_quiet` — catches zero-chunks hint
496
+ leaking to stdout, which would corrupt the MCP JSON-RPC wire in stdio
497
+ mode.
498
+ - `test_empty_extensions_non_interactive_errors_exit_2` — catches
499
+ `--extensions ""` being silently accepted, which would write an empty
500
+ `file_extensions: []` and re-create the zero-chunks bug.
501
+ - `test_ctrl_c_in_prompt_returns_exit_0` — catches KeyboardInterrupt
502
+ propagating a traceback to the user.
503
+ - `test_permission_error_on_write_exits_1` — catches PermissionError /
504
+ OSError propagating a traceback when config.yaml isn't writable.
505
+ - `test_honors_user_skip_dirs_from_config` — catches scan_project
506
+ ignoring the user's explicit skip_dirs in config.yaml.
507
+
508
+ ### Known limitations
509
+
510
+ - A running file-watcher or live MCP server session won't pick up config
511
+ changes until it restarts (the watcher snapshots `watched_dirs` at boot).
512
+ Restart your AI tool after `codevira configure` to apply changes.
513
+ - `yaml.safe_dump` doesn't preserve comments in `config.yaml`. First-time
514
+ configs are auto-generated and have no comments; users who hand-edited
515
+ may see formatting normalized after `codevira configure` rewrites the file.
516
+
517
+ ### Unchanged (intentionally)
518
+
519
+ - No new MCP tools. No new tables. No schema migration.
520
+ - `search_decisions()` method signature unchanged.
521
+ - `log_session()` method signature unchanged.
522
+ - `get_session_context()` keys are additive — no removals.
523
+ - `auto_init.py`, `detect.py`, `gitignore.py`, and `metadata.json` writer
524
+ untouched; `codevira configure` reuses all existing detection machinery.
525
+
14
526
  ---
15
527
 
16
528
  ## [1.7.1] — 2026-04-22 — Search Timeout Fix & Version Display