code-context-control 2.65.0__tar.gz → 2.67.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 (394) hide show
  1. {code_context_control-2.65.0/code_context_control.egg-info → code_context_control-2.67.0}/PKG-INFO +53 -3
  2. {code_context_control-2.65.0 → code_context_control-2.67.0}/README.md +52 -2
  3. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/_hook_utils.py +106 -3
  4. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/c3.py +271 -9
  5. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/commands/parser.py +39 -0
  6. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_access_guard.py +26 -0
  7. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_pretool_enforce.py +167 -45
  8. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_server.py +278 -2
  9. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/app.js +3 -1
  10. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_panel.js +2 -0
  11. code_context_control-2.67.0/cli/hub_ui/components/hub_enforcement.js +1162 -0
  12. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/topbar.js +1 -1
  13. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/server.py +115 -0
  14. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/app.js +4 -0
  15. code_context_control-2.67.0/cli/ui/components/enforcement.js +334 -0
  16. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/icons.js +1 -0
  17. {code_context_control-2.65.0 → code_context_control-2.67.0/code_context_control.egg-info}/PKG-INFO +53 -3
  18. {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/SOURCES.txt +7 -0
  19. {code_context_control-2.65.0 → code_context_control-2.67.0}/pyproject.toml +1 -1
  20. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/access_guard.py +25 -0
  21. code_context_control-2.67.0/services/access_telemetry.py +262 -0
  22. code_context_control-2.67.0/services/enforcement_policy.py +419 -0
  23. code_context_control-2.67.0/tests/test_enforcement_policy.py +672 -0
  24. code_context_control-2.67.0/tests/test_enforcement_routes.py +182 -0
  25. code_context_control-2.67.0/tests/test_hub_enforcement_routes.py +438 -0
  26. {code_context_control-2.65.0 → code_context_control-2.67.0}/LICENSE +0 -0
  27. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/__init__.py +0 -0
  28. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/commands/__init__.py +0 -0
  29. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/commands/common.py +0 -0
  30. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/docs.html +0 -0
  31. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/edits.html +0 -0
  32. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/access.html +0 -0
  33. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/bitbucket.html +0 -0
  34. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/credentials.html +0 -0
  35. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/getting-started.html +0 -0
  36. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/index.html +0 -0
  37. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/masking.html +0 -0
  38. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/oracle.html +0 -0
  39. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/shared.css +0 -0
  40. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/tools.html +0 -0
  41. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/guide/workflow.html +0 -0
  42. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_artifact.py +0 -0
  43. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_auto_snapshot.py +0 -0
  44. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_c3_signal.py +0 -0
  45. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_c3read.py +0 -0
  46. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_dispatch.py +0 -0
  47. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_edit_ledger.py +0 -0
  48. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_edit_unlock.py +0 -0
  49. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_filter.py +0 -0
  50. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_ghost_files.py +0 -0
  51. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_prompt_recall.py +0 -0
  52. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_read.py +0 -0
  53. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_session_stats.py +0 -0
  54. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hook_terse_advisor.py +0 -0
  55. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/add_project.js +0 -0
  56. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/config_editor.js +0 -0
  57. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_artifacts.js +0 -0
  58. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_health.js +0 -0
  59. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_subprojects.js +0 -0
  60. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_tasks.js +0 -0
  61. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/drill_views.js +0 -0
  62. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/global_search.js +0 -0
  63. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/hub_credentials.js +0 -0
  64. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/hub_locks.js +0 -0
  65. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/mcp_manager.js +0 -0
  66. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/modals.js +0 -0
  67. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/project_card.js +0 -0
  68. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/project_tree.js +0 -0
  69. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/session_drawer.js +0 -0
  70. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/settings_modal.js +0 -0
  71. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/sidebar.js +0 -0
  72. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/summary_bar.js +0 -0
  73. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/task_board.js +0 -0
  74. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/components/toasts.js +0 -0
  75. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui/state.js +0 -0
  76. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/hub_ui.html +0 -0
  77. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/mcp_proxy.py +0 -0
  78. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/mcp_server.py +0 -0
  79. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/progress.py +0 -0
  80. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/__init__.py +0 -0
  81. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/_helpers.py +0 -0
  82. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/agent.py +0 -0
  83. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/artifacts.py +0 -0
  84. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/bitbucket.py +0 -0
  85. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/compress.py +0 -0
  86. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/credentials.py +0 -0
  87. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/delegate.py +0 -0
  88. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/edit.py +0 -0
  89. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/edits.py +0 -0
  90. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/federate.py +0 -0
  91. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/filter.py +0 -0
  92. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/impact.py +0 -0
  93. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/jira.py +0 -0
  94. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/locks.py +0 -0
  95. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/memory.py +0 -0
  96. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/project.py +0 -0
  97. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/read.py +0 -0
  98. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/search.py +0 -0
  99. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/session.py +0 -0
  100. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/shell.py +0 -0
  101. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/status.py +0 -0
  102. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/tasks.py +0 -0
  103. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/tools/validate.py +0 -0
  104. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/api.js +0 -0
  105. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/access.js +0 -0
  106. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/bitbucket.js +0 -0
  107. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/chat.js +0 -0
  108. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/credentials.js +0 -0
  109. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/dashboard.js +0 -0
  110. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/edits.js +0 -0
  111. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/instructions.js +0 -0
  112. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/jira.js +0 -0
  113. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/memory.js +0 -0
  114. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/sessions.js +0 -0
  115. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/settings.js +0 -0
  116. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/sidebar.js +0 -0
  117. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/components/tasks.js +0 -0
  118. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/pm_shared.js +0 -0
  119. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/shared.js +0 -0
  120. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui/theme.js +0 -0
  121. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui.html +0 -0
  122. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui_legacy.html +0 -0
  123. {code_context_control-2.65.0 → code_context_control-2.67.0}/cli/ui_nano.html +0 -0
  124. {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/dependency_links.txt +0 -0
  125. {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/entry_points.txt +0 -0
  126. {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/requires.txt +0 -0
  127. {code_context_control-2.65.0 → code_context_control-2.67.0}/code_context_control.egg-info/top_level.txt +0 -0
  128. {code_context_control-2.65.0 → code_context_control-2.67.0}/core/__init__.py +0 -0
  129. {code_context_control-2.65.0 → code_context_control-2.67.0}/core/config.py +0 -0
  130. {code_context_control-2.65.0 → code_context_control-2.67.0}/core/ide.py +0 -0
  131. {code_context_control-2.65.0 → code_context_control-2.67.0}/core/mcp_toml.py +0 -0
  132. {code_context_control-2.65.0 → code_context_control-2.67.0}/core/web_security.py +0 -0
  133. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/__init__.py +0 -0
  134. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/config.py +0 -0
  135. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/mcp_oracle.py +0 -0
  136. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/oracle_server.py +0 -0
  137. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/oracle_ui.html +0 -0
  138. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/__init__.py +0 -0
  139. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/activity_reporter.py +0 -0
  140. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/api_auth.py +0 -0
  141. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/c3_bridge.py +0 -0
  142. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/chat_engine.py +0 -0
  143. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/chat_store.py +0 -0
  144. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/cross_memory.py +0 -0
  145. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/discovery_audit.py +0 -0
  146. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/federated_graph.py +0 -0
  147. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/health_checker.py +0 -0
  148. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/insight_engine.py +0 -0
  149. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/local_session.py +0 -0
  150. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/memory_reader.py +0 -0
  151. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/memory_writer.py +0 -0
  152. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/project_scanner.py +0 -0
  153. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/review_agent.py +0 -0
  154. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/tool_executor.py +0 -0
  155. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/services/tool_registry.py +0 -0
  156. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/activity.js +0 -0
  157. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/agents.js +0 -0
  158. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/app.js +0 -0
  159. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/busy.js +0 -0
  160. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/conversations.js +0 -0
  161. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/input.js +0 -0
  162. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/markdown.js +0 -0
  163. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/send.js +0 -0
  164. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/stream_renderer.js +0 -0
  165. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/chat/toolbar.js +0 -0
  166. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/core.js +0 -0
  167. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/crossgraph.js +0 -0
  168. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/header.js +0 -0
  169. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/insights.js +0 -0
  170. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/projects.js +0 -0
  171. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/settings.js +0 -0
  172. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/suggestions.js +0 -0
  173. {code_context_control-2.65.0 → code_context_control-2.67.0}/oracle/ui/theme_tabs.js +0 -0
  174. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/__init__.py +0 -0
  175. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/activity_log.py +0 -0
  176. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/agent_base.py +0 -0
  177. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/agent_locks.py +0 -0
  178. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/agents.py +0 -0
  179. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/artifact_defs.py +0 -0
  180. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/artifact_store.py +0 -0
  181. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/auto_memory.py +0 -0
  182. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/__init__.py +0 -0
  183. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/external/__init__.py +0 -0
  184. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/external/aider_polyglot.py +0 -0
  185. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bench/external/swe_bench.py +0 -0
  186. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/benchmark_dashboard.py +0 -0
  187. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bitbucket_client.py +0 -0
  188. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/bitbucket_credentials.py +0 -0
  189. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/circuit_breaker.py +0 -0
  190. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/claude_md.py +0 -0
  191. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/compressor.py +0 -0
  192. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/context_snapshot.py +0 -0
  193. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/conversation_store.py +0 -0
  194. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/credential_store.py +0 -0
  195. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/doc_index.py +0 -0
  196. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/e2e_benchmark.py +0 -0
  197. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/e2e_evaluator.py +0 -0
  198. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/e2e_tasks.py +0 -0
  199. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/edit_ledger.py +0 -0
  200. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/embedding_index.py +0 -0
  201. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/error_reporting.py +0 -0
  202. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/file_memory.py +0 -0
  203. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/git_context.py +0 -0
  204. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/hub_service.py +0 -0
  205. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/indexer.py +0 -0
  206. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_client.py +0 -0
  207. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_cloud.py +0 -0
  208. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_credentials.py +0 -0
  209. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_data_center.py +0 -0
  210. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/jira_links.py +0 -0
  211. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/mask_activation.py +0 -0
  212. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/mask_mirror.py +0 -0
  213. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/mask_presets.py +0 -0
  214. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory.py +0 -0
  215. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_consolidator.py +0 -0
  216. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_distiller.py +0 -0
  217. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_graph.py +0 -0
  218. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_grounder.py +0 -0
  219. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_queue.py +0 -0
  220. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/memory_scorer.py +0 -0
  221. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/metrics.py +0 -0
  222. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/notifications.py +0 -0
  223. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/ollama_bridge.py +0 -0
  224. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/ollama_client.py +0 -0
  225. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/ollama_credentials.py +0 -0
  226. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/output_filter.py +0 -0
  227. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/parser.py +0 -0
  228. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/project_manager.py +0 -0
  229. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/project_runtime.py +0 -0
  230. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/protocol.py +0 -0
  231. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/proxy_state.py +0 -0
  232. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/repo_map.py +0 -0
  233. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/retention.py +0 -0
  234. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/retrieval_broker.py +0 -0
  235. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/router.py +0 -0
  236. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/runtime.py +0 -0
  237. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/scanner.py +0 -0
  238. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/session_benchmark.py +0 -0
  239. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/session_manager.py +0 -0
  240. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/session_preloader.py +0 -0
  241. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/subprojects.py +0 -0
  242. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/task_store.py +0 -0
  243. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/telemetry.py +0 -0
  244. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/text_index.py +0 -0
  245. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/time_tracker.py +0 -0
  246. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/tool_classifier.py +0 -0
  247. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/transcript_index.py +0 -0
  248. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/validation_cache.py +0 -0
  249. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/vector_store.py +0 -0
  250. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/watcher.py +0 -0
  251. {code_context_control-2.65.0 → code_context_control-2.67.0}/services/win_subprocess.py +0 -0
  252. {code_context_control-2.65.0 → code_context_control-2.67.0}/setup.cfg +0 -0
  253. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_builtin_optout.py +0 -0
  254. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard.py +0 -0
  255. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_meta.py +0 -0
  256. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_shell_project.py +0 -0
  257. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_surfaces.py +0 -0
  258. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_access_guard_wiring.py +0 -0
  259. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_activity_reporter.py +0 -0
  260. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_agent_locks.py +0 -0
  261. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_aider_polyglot.py +0 -0
  262. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_antigravity_transition.py +0 -0
  263. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_artifact_store.py +0 -0
  264. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_artifact_tool.py +0 -0
  265. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_cli_smoke.py +0 -0
  266. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_client.py +0 -0
  267. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_config_fallback.py +0 -0
  268. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_credentials.py +0 -0
  269. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_bitbucket_tool.py +0 -0
  270. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_c3_bridge_project_artifacts.py +0 -0
  271. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_c3_shell.py +0 -0
  272. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_circuit_breaker.py +0 -0
  273. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_claude_md_merge.py +0 -0
  274. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_cli_smoke.py +0 -0
  275. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_compressor_large_file.py +0 -0
  276. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_credential_store.py +0 -0
  277. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_credentials_routes.py +0 -0
  278. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_credentials_tool.py +0 -0
  279. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_creds_cli_smoke.py +0 -0
  280. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_delegate_cascade.py +0 -0
  281. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_e2e_benchmark.py +0 -0
  282. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_edit_ledger_hook.py +0 -0
  283. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_edit_locking.py +0 -0
  284. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_edit_normalization.py +0 -0
  285. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_enforcement_flip.py +0 -0
  286. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_federated_graph.py +0 -0
  287. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_filter_backoff.py +0 -0
  288. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ghost_files.py +0 -0
  289. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ghost_generation.py +0 -0
  290. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_git_branch_awareness.py +0 -0
  291. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_access_guard.py +0 -0
  292. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_dispatch.py +0 -0
  293. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_pretool_enforce.py +0 -0
  294. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_prompt_recall.py +0 -0
  295. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_smoke.py +0 -0
  296. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_state.py +0 -0
  297. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hook_utf8_stdio.py +0 -0
  298. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_credentials_route.py +0 -0
  299. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_credentials_routes_write.py +0 -0
  300. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_inspect_api.py +0 -0
  301. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_locks_routes.py +0 -0
  302. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_server_smoke.py +0 -0
  303. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_hub_subproject_links.py +0 -0
  304. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ide_workflow_adaptation.py +0 -0
  305. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_init_scan.py +0 -0
  306. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_install_mcp_entrypoint.py +0 -0
  307. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_cli_smoke.py +0 -0
  308. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_client.py +0 -0
  309. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_config_fallback.py +0 -0
  310. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_credentials.py +0 -0
  311. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_links.py +0 -0
  312. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_routes.py +0 -0
  313. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_jira_tool.py +0 -0
  314. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_lazy_store_init.py +0 -0
  315. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mask_guard.py +0 -0
  316. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mask_routes.py +0 -0
  317. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mask_surfaces.py +0 -0
  318. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_host_guard.py +0 -0
  319. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_memory_timeout.py +0 -0
  320. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_server_smoke.py +0 -0
  321. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_mcp_toml.py +0 -0
  322. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_distiller.py +0 -0
  323. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_graph_api.py +0 -0
  324. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_queue.py +0 -0
  325. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_memory_system.py +0 -0
  326. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_no_stale_model_pins.py +0 -0
  327. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_notification_dedup.py +0 -0
  328. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_notification_discipline.py +0 -0
  329. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_ollama_credentials.py +0 -0
  330. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_api_auth.py +0 -0
  331. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_apikey_api.py +0 -0
  332. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_c3_bridge.py +0 -0
  333. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_chat_engine.py +0 -0
  334. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_chat_store.py +0 -0
  335. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_discovery_api.py +0 -0
  336. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_discovery_audit.py +0 -0
  337. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_local_auth.py +0 -0
  338. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_ollama_bridge.py +0 -0
  339. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_scanner_cache.py +0 -0
  340. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_security_fixes.py +0 -0
  341. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_session_bootstrap.py +0 -0
  342. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_subproject_awareness.py +0 -0
  343. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_oracle_ui_bundle.py +0 -0
  344. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_output_filter.py +0 -0
  345. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_permissions.py +0 -0
  346. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_pm_api.py +0 -0
  347. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_project_manager.py +0 -0
  348. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_project_manager_merge.py +0 -0
  349. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_project_tool.py +0 -0
  350. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_read_coercion.py +0 -0
  351. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_read_edit_parity.py +0 -0
  352. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_related_facts.py +0 -0
  353. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_repo_map.py +0 -0
  354. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_response_boilerplate.py +0 -0
  355. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_retention.py +0 -0
  356. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_review_digest.py +0 -0
  357. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_service_durability.py +0 -0
  358. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_session_benchmark.py +0 -0
  359. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_session_budget.py +0 -0
  360. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_shell_creds.py +0 -0
  361. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_shell_robustness.py +0 -0
  362. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_subproject_exclusion.py +0 -0
  363. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_subproject_federation.py +0 -0
  364. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_subprojects.py +0 -0
  365. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_swe_bench.py +0 -0
  366. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_task_store.py +0 -0
  367. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_task_tool.py +0 -0
  368. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_time_tracker.py +0 -0
  369. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_token_telemetry.py +0 -0
  370. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_tool_registry.py +0 -0
  371. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_upgrade_and_version.py +0 -0
  372. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_validate.py +0 -0
  373. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_vault_write_guard.py +0 -0
  374. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_version_sync.py +0 -0
  375. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_web_security.py +0 -0
  376. {code_context_control-2.65.0 → code_context_control-2.67.0}/tests/test_windows_reliability.py +0 -0
  377. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/__init__.py +0 -0
  378. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/backend.py +0 -0
  379. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/main.py +0 -0
  380. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/__init__.py +0 -0
  381. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/benchmark_view.py +0 -0
  382. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/claudemd_view.py +0 -0
  383. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/compress_view.py +0 -0
  384. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/index_view.py +0 -0
  385. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/init_view.py +0 -0
  386. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/mcp_view.py +0 -0
  387. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/optimize_view.py +0 -0
  388. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/pipe_view.py +0 -0
  389. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/projects_view.py +0 -0
  390. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/search_view.py +0 -0
  391. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/session_view.py +0 -0
  392. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/stats.py +0 -0
  393. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/screens/ui_view.py +0 -0
  394. {code_context_control-2.65.0 → code_context_control-2.67.0}/tui/theme.tcss +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-context-control
3
- Version: 2.65.0
3
+ Version: 2.67.0
4
4
  Summary: Local MCP code-intelligence for AI coding tools: surgical search/read/edit, agent-config version history, path-level access + masking guards, and a multi-project hub.
5
5
  Author-email: Dimitri Tselenchuk <dtselenc@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -186,7 +186,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
186
186
 
187
187
  ## The MCP tool suite
188
188
 
189
- C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
189
+ C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
190
190
 
191
191
  | Tool | What it does |
192
192
  |---|---|
@@ -201,6 +201,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
201
201
  | `c3_memory` | Fact store with categories, recall, graph queries, `index`→`fetch` two-step |
202
202
  | `c3_session` | Snapshot, restore, log decisions, compact history |
203
203
  | `c3_impact` | Blast-radius analysis before editing shared symbols |
204
+ | `c3_locks` | Agent leases — who is working on which file, so two agents don't collide (v2.65.0) |
204
205
  | `c3_delegate` | Offload heavy work to local Ollama / Codex / Gemini |
205
206
  | `c3_agent` | Workflows: `review_changes`, `investigate`, `preflight`, `prepare_context`, `validate_compress` |
206
207
  | `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter |
@@ -211,7 +212,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
211
212
  | `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
212
213
  | `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
213
214
 
214
- Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task`.
215
+ Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
215
216
 
216
217
  On Windows `c3_shell` uses Git Bash when available. Git Bash bundles no `jq`; use `python -m json.tool` for portable JSON formatting.
217
218
 
@@ -242,12 +243,61 @@ c3 access mask activate # purge pre-mask artifacts, buil
242
243
  - **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
243
244
  - **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
244
245
  - **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
246
+ - **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
245
247
  - **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
246
248
 
247
249
  → [Access Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/access-guard.md) · [Mask Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/mask-guard.md)
248
250
 
249
251
  ---
250
252
 
253
+ ## Agent Locks — several agents, one repo (v2.65.0)
254
+
255
+ Guards answer *may the agent touch this?* Locks answer *is someone already touching it?*
256
+
257
+ Two agents editing one file used to be silent data loss. `c3_edit` serialized
258
+ same-file edits with an in-process lock, but every session runs its own `c3-mcp`
259
+ server — so two sessions could interleave read → replace → write and lose an edit
260
+ with no error on either side. Create mode was worse: both agents "succeeded" and
261
+ one file won.
262
+
263
+ Now there are two mechanisms, because they solve different problems:
264
+
265
+ - **Torn writes** — a cross-process file lock, held across create, single-edit and
266
+ batch alike. No daemon, no configuration, nothing to switch on.
267
+ - **Overlapping work** — a *lease*. `c3_edit` takes one on the file it edits,
268
+ carrying the intent from your edit summary. A second agent gets told who holds
269
+ it and why:
270
+
271
+ ```text
272
+ [c3-lock:held] services/router.py is held by claude-code:a3f19c2b.
273
+ intent: "refactor retry backoff"
274
+ lease expires in 6m12s.
275
+ ```
276
+
277
+ ```bash
278
+ c3 locks list # who holds what, across the project
279
+ c3 locks force-release services/router.py # break a stuck lease (human-only, audited)
280
+ ```
281
+
282
+ - **TTL is the real release mechanism.** Agents forget to release, so nothing
283
+ assumes they will — a crashed agent can never wedge a repo.
284
+ - **Acquisition is all-or-nothing** over a sorted path list, so two agents grabbing
285
+ the same pair in opposite order cannot deadlock.
286
+ - **`force-release` bumps a fencing counter**, so a holder that comes back is stale
287
+ by construction rather than by hope. It lives in the CLI and the Hub, never in
288
+ the agent-facing tool.
289
+ - **The Hub's Locks tab badges a project it cannot read as `UNREADABLE`**, not as
290
+ zero leases — "all clear" is a different claim from "we don't know".
291
+ - **Honest coverage, again.** Leases gate C3's own tool surfaces. A raw `c3_shell`
292
+ redirect, a non-Claude agent, or a human in an editor is *not* covered, and the
293
+ UI says so on screen.
294
+
295
+ Set `locks.enabled: false` in `.c3/config.json` to opt out.
296
+
297
+ → [Agent Locks](https://github.com/drknowhow/code-context-control/blob/main/docs/agent-locks.md)
298
+
299
+ ---
300
+
251
301
  ## Integrations
252
302
 
253
303
  | | What you get | Guide |
@@ -123,7 +123,7 @@ Twelve tabs. The dashboard above shows token savings, indexed files, the live se
123
123
 
124
124
  ## The MCP tool suite
125
125
 
126
- C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
126
+ C3 exposes **21 tools** as a native MCP server. Your IDE calls them directly:
127
127
 
128
128
  | Tool | What it does |
129
129
  |---|---|
@@ -138,6 +138,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
138
138
  | `c3_memory` | Fact store with categories, recall, graph queries, `index`→`fetch` two-step |
139
139
  | `c3_session` | Snapshot, restore, log decisions, compact history |
140
140
  | `c3_impact` | Blast-radius analysis before editing shared symbols |
141
+ | `c3_locks` | Agent leases — who is working on which file, so two agents don't collide (v2.65.0) |
141
142
  | `c3_delegate` | Offload heavy work to local Ollama / Codex / Gemini |
142
143
  | `c3_agent` | Workflows: `review_changes`, `investigate`, `preflight`, `prepare_context`, `validate_compress` |
143
144
  | `c3_edits` | Edit-ledger queries, version diffs, restore points, per-branch filter |
@@ -148,7 +149,7 @@ C3 exposes **20 tools** as a native MCP server. Your IDE calls them directly:
148
149
  | `c3_jira` | Jira Cloud + Data Center — JQL, issues, transitions (v2.56.0) |
149
150
  | `c3_project` | Cross-project discovery & operations; guarded writes (v2.31.0) |
150
151
 
151
- Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task`.
152
+ Every tool is **read-only safe in plan mode** except `c3_edit`, `c3_shell`, `c3_artifacts(action='restore')`, `c3_delegate` with write delegation enabled, and write actions on `c3_bitbucket` / `c3_jira` / `c3_credentials` / `c3_project` / `c3_task` / `c3_locks`.
152
153
 
153
154
  On Windows `c3_shell` uses Git Bash when available. Git Bash bundles no `jq`; use `python -m json.tool` for portable JSON formatting.
154
155
 
@@ -179,12 +180,61 @@ c3 access mask activate # purge pre-mask artifacts, buil
179
180
  - **Masked means read-only, always.** Cropped rows have no inverse, so an edit in transformed coordinates would corrupt the one file you protected.
180
181
  - **Four deterministic presets, no LLM in the read path:** `redact_secrets`, `redact_columns` (salted one-way pseudonyms — joins survive, no reverse dictionary), `sample_rows`, `signatures_only`.
181
182
  - **Rule changes are human-only** (UI tab or CLI) and ledger-logged. Agents have no mutation surface.
183
+ - **Built-ins can be switched off when you need to** (v2.65.0). `**/.env*`, `**/.c3/**`, `**/.claude/settings*.json` and `**/.git/**` yield to `c3 access builtin disable <glob>`, which makes you retype the glob first. It takes **two keys** — a config entry *and* a keyring attestation — so an agent that manages to write `config.json` still cannot grant itself write access to your settings. The credential vault stays absolute.
182
184
  - **Honest coverage.** This guards *cooperative* agents against mistakes and prompt injection. It is not a sandbox — a raw shell outside C3's tools still sees the real bytes.
183
185
 
184
186
  → [Access Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/access-guard.md) · [Mask Guard](https://github.com/drknowhow/code-context-control/blob/main/docs/mask-guard.md)
185
187
 
186
188
  ---
187
189
 
190
+ ## Agent Locks — several agents, one repo (v2.65.0)
191
+
192
+ Guards answer *may the agent touch this?* Locks answer *is someone already touching it?*
193
+
194
+ Two agents editing one file used to be silent data loss. `c3_edit` serialized
195
+ same-file edits with an in-process lock, but every session runs its own `c3-mcp`
196
+ server — so two sessions could interleave read → replace → write and lose an edit
197
+ with no error on either side. Create mode was worse: both agents "succeeded" and
198
+ one file won.
199
+
200
+ Now there are two mechanisms, because they solve different problems:
201
+
202
+ - **Torn writes** — a cross-process file lock, held across create, single-edit and
203
+ batch alike. No daemon, no configuration, nothing to switch on.
204
+ - **Overlapping work** — a *lease*. `c3_edit` takes one on the file it edits,
205
+ carrying the intent from your edit summary. A second agent gets told who holds
206
+ it and why:
207
+
208
+ ```text
209
+ [c3-lock:held] services/router.py is held by claude-code:a3f19c2b.
210
+ intent: "refactor retry backoff"
211
+ lease expires in 6m12s.
212
+ ```
213
+
214
+ ```bash
215
+ c3 locks list # who holds what, across the project
216
+ c3 locks force-release services/router.py # break a stuck lease (human-only, audited)
217
+ ```
218
+
219
+ - **TTL is the real release mechanism.** Agents forget to release, so nothing
220
+ assumes they will — a crashed agent can never wedge a repo.
221
+ - **Acquisition is all-or-nothing** over a sorted path list, so two agents grabbing
222
+ the same pair in opposite order cannot deadlock.
223
+ - **`force-release` bumps a fencing counter**, so a holder that comes back is stale
224
+ by construction rather than by hope. It lives in the CLI and the Hub, never in
225
+ the agent-facing tool.
226
+ - **The Hub's Locks tab badges a project it cannot read as `UNREADABLE`**, not as
227
+ zero leases — "all clear" is a different claim from "we don't know".
228
+ - **Honest coverage, again.** Leases gate C3's own tool surfaces. A raw `c3_shell`
229
+ redirect, a non-Claude agent, or a human in an editor is *not* covered, and the
230
+ UI says so on screen.
231
+
232
+ Set `locks.enabled: false` in `.c3/config.json` to opt out.
233
+
234
+ → [Agent Locks](https://github.com/drknowhow/code-context-control/blob/main/docs/agent-locks.md)
235
+
236
+ ---
237
+
188
238
  ## Integrations
189
239
 
190
240
  | | What you get | Guide |
@@ -96,12 +96,111 @@ def _empty_state(session_id: str = "") -> dict:
96
96
  return {"session_id": session_id or "", "last_c3_call": None, "unlocked_files": {}}
97
97
 
98
98
 
99
+ #: os.replace retries for when Windows briefly holds a handle on the target —
100
+ #: AV scanner, Search indexer, or a concurrent hook reading the same state.
101
+ _REPLACE_ATTEMPTS = 4
102
+ _REPLACE_BACKOFF_S = 0.02
103
+
104
+
99
105
  def _atomic_write_json(path: Path, data: dict) -> None:
100
- """Write JSON atomically: temp file in the same directory + os.replace."""
106
+ """Write JSON durably: temp file in the same directory + os.replace.
107
+
108
+ Three failure modes this guards against, all observed in the wild
109
+ (10 orphaned .tmp<pid> files and a truncated enforcement_state.json on a
110
+ Windows box before v2.66):
111
+
112
+ 1. **Torn write.** Without fsync, os.replace can publish a file whose
113
+ bytes are still in the OS cache. A crash or power loss then leaves a
114
+ zero-length or half-written JSON that every later read quarantines —
115
+ which silently drops all sticky unlocks and makes enforcement *more*
116
+ aggressive, not less.
117
+ 2. **Orphaned temp files.** If os.replace raised, the temp file was
118
+ simply abandoned. They accumulate forever in .c3/ and are easy to
119
+ mistake for real state.
120
+ 3. **Transient Windows sharing violations.** Another process holding a
121
+ read handle on the target makes os.replace raise PermissionError; a
122
+ single attempt turned that into a lost write.
123
+ """
124
+ import time
125
+
101
126
  path.parent.mkdir(parents=True, exist_ok=True)
102
127
  tmp = path.with_name(f"{path.name}.tmp{os.getpid()}")
103
- tmp.write_text(json.dumps(data), encoding="utf-8")
104
- os.replace(tmp, path)
128
+ try:
129
+ with open(tmp, "w", encoding="utf-8") as fh:
130
+ json.dump(data, fh)
131
+ fh.flush()
132
+ os.fsync(fh.fileno()) # durability before publish (fixes #1)
133
+
134
+ last_exc = None
135
+ for attempt in range(_REPLACE_ATTEMPTS):
136
+ try:
137
+ os.replace(tmp, path)
138
+ return
139
+ except PermissionError as exc: # fixes #3
140
+ last_exc = exc
141
+ if attempt < _REPLACE_ATTEMPTS - 1:
142
+ time.sleep(_REPLACE_BACKOFF_S * (2 ** attempt))
143
+ if last_exc is not None:
144
+ raise last_exc
145
+ finally:
146
+ # fixes #2 — a successful replace already consumed tmp, so this only
147
+ # fires on the failure paths.
148
+ try:
149
+ if tmp.exists():
150
+ tmp.unlink()
151
+ except OSError:
152
+ pass
153
+
154
+
155
+ def sweep_stale_temps(project_path: Path | None = None) -> int:
156
+ """Remove orphaned *.tmp<pid> files left by older C3 builds.
157
+
158
+ Only touches temp files whose owning PID is gone, so a concurrent hook
159
+ mid-write is never disturbed. Returns how many were removed; never raises.
160
+ """
161
+ removed = 0
162
+ try:
163
+ base = project_path if project_path is not None else Path.cwd()
164
+ c3_dir = base / ".c3"
165
+ if not c3_dir.is_dir():
166
+ return 0
167
+ for tmp in c3_dir.glob("*.tmp*"):
168
+ suffix = tmp.name.rsplit(".tmp", 1)[-1]
169
+ if not suffix.isdigit():
170
+ continue
171
+ if _pid_alive(int(suffix)):
172
+ continue
173
+ try:
174
+ tmp.unlink()
175
+ removed += 1
176
+ except OSError:
177
+ pass
178
+ except Exception:
179
+ pass
180
+ return removed
181
+
182
+
183
+ def _pid_alive(pid: int) -> bool:
184
+ """Best-effort liveness check. On error assume ALIVE (don't delete)."""
185
+ if pid <= 0:
186
+ return False
187
+ try:
188
+ if os.name == "nt":
189
+ import ctypes
190
+ # PROCESS_QUERY_LIMITED_INFORMATION — works without elevation.
191
+ handle = ctypes.windll.kernel32.OpenProcess(0x1000, False, pid)
192
+ if not handle:
193
+ return False
194
+ ctypes.windll.kernel32.CloseHandle(handle)
195
+ return True
196
+ os.kill(pid, 0)
197
+ return True
198
+ except ProcessLookupError:
199
+ return False
200
+ except PermissionError:
201
+ return True # exists but not ours
202
+ except Exception:
203
+ return True # unknown → conservative
105
204
 
106
205
 
107
206
  def _read_legacy_state(base: Path) -> dict:
@@ -163,6 +262,10 @@ def load_enforcement_state(project_path: Path | None = None, session_id: str = "
163
262
  state_path.replace(state_path.with_name(state_path.name + ".corrupt"))
164
263
  except Exception:
165
264
  pass
265
+ # Corruption is the one reliable signal that a previous write went
266
+ # wrong, so it is also the moment to clear any temp files that
267
+ # write orphaned (pre-v2.66 _atomic_write_json had no cleanup).
268
+ sweep_stale_temps(base)
166
269
  STATE_WARNINGS.append(
167
270
  "[c3:hook-error] enforcement_state: corrupted "
168
271
  f"{ENFORCEMENT_STATE_FILE} quarantined ({type(exc).__name__}); "