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.
- {codevira-2.1.2 → codevira-3.0.0}/CHANGELOG.md +585 -1
- codevira-3.0.0/PKG-INFO +522 -0
- codevira-3.0.0/README.md +473 -0
- codevira-3.0.0/codevira.egg-info/PKG-INFO +522 -0
- {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/SOURCES.txt +28 -32
- {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/requires.txt +7 -3
- codevira-3.0.0/docs/architecture.md +264 -0
- codevira-3.0.0/docs/audit-2026-05-22.md +274 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/foolproof-product-charter.md +3 -2
- {codevira-2.1.2 → codevira-3.0.0}/docs/how-i-built-persistent-memory-for-ai-agents.md +10 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/linkedin-article-ai-agent-memory.md +9 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/medium-your-ai-coding-agent-has-amnesia.md +10 -0
- codevira-3.0.0/docs/morning-handoff-2026-05-22.md +337 -0
- codevira-3.0.0/docs/plans/v2.1.3.md +361 -0
- codevira-3.0.0/docs/plans/v2.2.0.md +960 -0
- codevira-3.0.0/docs/plans/v3.0.0.md +256 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/qa-playbook.md +14 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/roadmap.md +17 -4
- codevira-3.0.0/docs/surface-cuts-2026-05-22.md +348 -0
- {codevira-2.1.2 → codevira-3.0.0}/indexer/fix_history.py +57 -19
- {codevira-2.1.2 → codevira-3.0.0}/indexer/graph_generator.py +95 -36
- {codevira-2.1.2 → codevira-3.0.0}/indexer/index_codebase.py +51 -94
- {codevira-2.1.2 → codevira-3.0.0}/indexer/outcome_tracker.py +115 -43
- {codevira-2.1.2 → codevira-3.0.0}/indexer/sqlite_graph.py +13 -204
- {codevira-2.1.2 → codevira-3.0.0}/indexer/treesitter_parser.py +61 -23
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/__init__.py +1 -1
- codevira-3.0.0/mcp_server/_mcp_registry.py +145 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_repair_init.py +46 -22
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_safe_crash.py +0 -1
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/auto_init.py +45 -14
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli.py +353 -851
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_export.py +34 -8
- codevira-3.0.0/mcp_server/cli_graph.py +447 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_hooks_admin.py +80 -7
- codevira-3.0.0/mcp_server/cli_init.py +296 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_replay.py +73 -24
- codevira-3.0.0/mcp_server/cli_sync.py +109 -0
- codevira-3.0.0/mcp_server/cli_uninstall.py +478 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/post_tool_use.sh +8 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/pre_tool_use.sh +8 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/session_start.sh +8 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/stop.sh +8 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/hooks/user_prompt_submit.sh +9 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/decision_replay.py +125 -75
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/doctor.py +287 -99
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/__init__.py +11 -14
- codevira-3.0.0/mcp_server/engine/policies/__init__.py +45 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/_signature_detect.py +0 -1
- codevira-3.0.0/mcp_server/engine/policies/relevance_inject.py +458 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/signals.py +120 -185
- codevira-3.0.0/mcp_server/global_sync.py +96 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/http_server.py +119 -47
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/ide_inject.py +130 -48
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/log_retention.py +30 -9
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/migrate.py +21 -5
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/paths.py +65 -24
- codevira-3.0.0/mcp_server/prompts.py +77 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/roadmap_drift.py +1 -1
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/server.py +294 -730
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/setup_wizard.py +274 -137
- codevira-3.0.0/mcp_server/storage/__init__.py +43 -0
- codevira-3.0.0/mcp_server/storage/agents_md_generator.py +360 -0
- codevira-3.0.0/mcp_server/storage/atomic.py +268 -0
- codevira-3.0.0/mcp_server/storage/decisions_store.py +546 -0
- codevira-3.0.0/mcp_server/storage/digest.py +134 -0
- codevira-3.0.0/mcp_server/storage/fts5_index.py +430 -0
- codevira-3.0.0/mcp_server/storage/jsonl_store.py +390 -0
- codevira-3.0.0/mcp_server/storage/manifest.py +199 -0
- codevira-3.0.0/mcp_server/storage/outcomes_writer.py +295 -0
- codevira-3.0.0/mcp_server/storage/paths.py +160 -0
- codevira-3.0.0/mcp_server/storage/sessions_store.py +123 -0
- codevira-3.0.0/mcp_server/storage/token_estimator.py +106 -0
- codevira-3.0.0/mcp_server/tools/changesets.py +50 -0
- codevira-3.0.0/mcp_server/tools/check_conflict.py +286 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/graph.py +9 -421
- codevira-3.0.0/mcp_server/tools/learning.py +678 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/roadmap.py +396 -347
- codevira-3.0.0/mcp_server/tools/search.py +296 -0
- {codevira-2.1.2 → codevira-3.0.0}/pyproject.toml +25 -13
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_auto_init.py +119 -52
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_call_edge_fk_safety.py +0 -2
- codevira-3.0.0/tests/test_check_conflict.py +293 -0
- codevira-3.0.0/tests/test_cli_graph.py +162 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_cli_replay.py +136 -47
- codevira-3.0.0/tests/test_cli_uninstall.py +475 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_cli_version.py +0 -1
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_crash_logger.py +1 -3
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_doctor.py +71 -34
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_fk_safety_extended.py +0 -1
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_fork_safety.py +0 -3
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_gitignore.py +173 -80
- codevira-3.0.0/tests/test_global_sync.py +152 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_graph_generator.py +39 -36
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_http_server.py +167 -119
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_ide_inject.py +260 -30
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_index_codebase.py +51 -43
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_launchd.py +1 -2
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_log_retention.py +0 -2
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_migrate.py +54 -37
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_outcome_tracker.py +1 -2
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_paths.py +237 -28
- codevira-3.0.0/tests/test_prompts.py +88 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_record_decision.py +39 -34
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_repair_init.py +0 -2
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_roadmap_drift.py +0 -2
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_server.py +81 -413
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_setup_wizard.py +298 -261
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_sqlite_graph.py +13 -176
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_sqlite_util.py +0 -1
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_code_reader.py +93 -26
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_graph.py +55 -496
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_learning.py +104 -483
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_playbook.py +0 -1
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_tools_roadmap.py +0 -2
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_treesitter_parser.py +0 -3
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_watcher_circuit.py +0 -1
- codevira-2.1.2/PKG-INFO +0 -809
- codevira-2.1.2/README.md +0 -762
- codevira-2.1.2/codevira.egg-info/PKG-INFO +0 -809
- codevira-2.1.2/indexer/rule_learner.py +0 -336
- codevira-2.1.2/mcp_server/agents_md.py +0 -442
- codevira-2.1.2/mcp_server/cli_agents.py +0 -232
- codevira-2.1.2/mcp_server/cli_budget.py +0 -213
- codevira-2.1.2/mcp_server/cli_calibrate.py +0 -140
- codevira-2.1.2/mcp_server/cli_configure.py +0 -977
- codevira-2.1.2/mcp_server/cli_insights.py +0 -337
- codevira-2.1.2/mcp_server/data/templates/agents_md.tmpl +0 -3
- codevira-2.1.2/mcp_server/data/templates/canonical_block.md +0 -81
- codevira-2.1.2/mcp_server/data/templates/claude_md.tmpl +0 -3
- codevira-2.1.2/mcp_server/data/templates/copilot_instructions.tmpl +0 -3
- codevira-2.1.2/mcp_server/data/templates/cursor_rules.mdc.tmpl +0 -8
- codevira-2.1.2/mcp_server/data/templates/gemini_md.tmpl +0 -3
- codevira-2.1.2/mcp_server/data/templates/windsurfrules.tmpl +0 -3
- codevira-2.1.2/mcp_server/engine/intent_classifier.py +0 -214
- codevira-2.1.2/mcp_server/engine/policies/__init__.py +0 -44
- codevira-2.1.2/mcp_server/engine/policies/ai_promotion.py +0 -337
- codevira-2.1.2/mcp_server/engine/policies/cross_session.py +0 -591
- codevira-2.1.2/mcp_server/engine/policies/intent_inference.py +0 -421
- codevira-2.1.2/mcp_server/engine/policies/live_style.py +0 -445
- codevira-2.1.2/mcp_server/engine/policies/scope_contract.py +0 -362
- codevira-2.1.2/mcp_server/engine/promotion_score.py +0 -208
- codevira-2.1.2/mcp_server/engine/scope_contract.py +0 -201
- codevira-2.1.2/mcp_server/global_sync.py +0 -187
- codevira-2.1.2/mcp_server/prompts.py +0 -145
- codevira-2.1.2/mcp_server/tools/_decision_embeddings.py +0 -694
- codevira-2.1.2/mcp_server/tools/changesets.py +0 -225
- codevira-2.1.2/mcp_server/tools/check_conflict.py +0 -175
- codevira-2.1.2/mcp_server/tools/learning.py +0 -984
- codevira-2.1.2/mcp_server/tools/search.py +0 -897
- codevira-2.1.2/tests/test_cli.py +0 -1423
- codevira-2.1.2/tests/test_cli_agents.py +0 -375
- codevira-2.1.2/tests/test_cli_configure.py +0 -1075
- codevira-2.1.2/tests/test_cli_insights.py +0 -159
- codevira-2.1.2/tests/test_decision_embeddings.py +0 -253
- codevira-2.1.2/tests/test_global_sync.py +0 -325
- codevira-2.1.2/tests/test_prompts.py +0 -101
- codevira-2.1.2/tests/test_retire_rule.py +0 -271
- codevira-2.1.2/tests/test_rule_learner.py +0 -411
- codevira-2.1.2/tests/test_tools_changesets.py +0 -424
- codevira-2.1.2/tests/test_tools_search.py +0 -489
- {codevira-2.1.2 → codevira-3.0.0}/LICENSE +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/MANIFEST.in +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/builder.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/developer.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/documenter.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/orchestrator.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/planner.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/01-code-review.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/02-adversarial-fix-review.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/03-cross-module-impact.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/06-doc-drift.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/07-security-audit.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/12-llm-redteam.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/13-multi-ide-schema.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/22-competitor-benchmark.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/README.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/tier2-scripts.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/qa/tier3-manual.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/reviewer.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/agents/tester.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/dependency_links.txt +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/entry_points.txt +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/codevira.egg-info/top_level.txt +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/config.example.yaml +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/alpha-tester-invites.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/demo/README.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/00-engine.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/01-decision-lock.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/02-anti-regression.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/03-scope-contract.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/04-blast-radius.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/05-cross-session.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/06-token-budget.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/07-live-style.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/08-decision-replay.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/09-intent-inference.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/10-ai-promotion.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/README.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/heroes/pillar-1-setup.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/hn-launch-day.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/internal/competitive-landscape.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/linkedin-post-ai-agent-memory.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/local-pypi-https.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/plans/v2.1.2.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/release-process.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/troubleshooting/antigravity.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/v2-completion-plan.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/v2-execution-log.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/v2-master-plan.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/docs/vs-other-memory-tools.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/graph/_schema.yaml +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/indexer/__init__.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/indexer/_dedupe_migration.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/indexer/_fork_safety.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/indexer/_sqlite_util.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/indexer/chunker.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/indexer/global_db.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/__main__.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_ghost_check.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_project_inventory.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/_prompts.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/cli_projects.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/crash_logger.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/__init__.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/builder.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/developer.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/documenter.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/orchestrator.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/planner.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/reviewer.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/agents/tester.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/config.example.yaml +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards-generic.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards-go.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards-typescript.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/coding-standards.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/engineering-excellence.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/git-cicd-governance.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/git_commits.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/incremental-updates.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/master_rule.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/multi-language.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/persistence.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/resilience-observability.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/smoke-testing.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/data/rules/testing-standards.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/detect.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/demo_policy.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/events.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/anti_regression.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/blast_radius.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/decision_lock.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/post_edit_refresh.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policies/token_budget.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/policy.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/runner.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/token_meter.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/wiring/__init__.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/wiring/claude_code_hooks.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/engine/wiring/mcp_dispatch.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/gitignore.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/launchd.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/__init__.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/code_reader.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/mcp_server/tools/playbook.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/coding-standards.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/engineering-excellence.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/git-cicd-governance.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/git_commits.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/incremental-updates.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/master_rule.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/persistence.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/resilience-observability.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/smoke-testing.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/rules/testing-standards.md +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/setup.cfg +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test__prompts.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_chunker.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_cli_projects.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_dedupe_migration.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_detect.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_ghost_check.py +0 -0
- {codevira-2.1.2 → codevira-3.0.0}/tests/test_global_db.py +0 -0
- {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
|
-
## [
|
|
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
|
|