marvisx-cli 0.3.7b2__tar.gz → 0.3.8__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 (659) hide show
  1. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/PKG-INFO +1 -1
  2. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/config.py +113 -0
  3. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/db.py +57 -42
  4. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/main.py +14 -0
  5. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/server.py +49 -1
  6. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/graph.py +38 -14
  7. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/learnings.py +3 -3
  8. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/graph_ux.py +62 -1
  9. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/search.py +8 -0
  10. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/graph.py +50 -0
  11. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/inbox.py +29 -1
  12. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/learnings.py +45 -2
  13. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/search.py +9 -1
  14. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/jobs.py +72 -0
  15. marvisx_cli-0.3.8/core/api/services/brain/llm/claude_cli.py +201 -0
  16. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/factory.py +13 -0
  17. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/memory_ops.py +15 -4
  18. marvisx_cli-0.3.8/core/api/services/brain/temporal_recency.py +195 -0
  19. marvisx_cli-0.3.8/core/api/services/chunking.py +277 -0
  20. marvisx_cli-0.3.8/core/api/services/dream_cycle.py +213 -0
  21. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/embedding_internal.py +13 -0
  22. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/embedding_service.py +544 -2
  23. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/graph_service.py +123 -5
  24. marvisx_cli-0.3.8/core/api/services/grounding/__init__.py +65 -0
  25. marvisx_cli-0.3.8/core/api/services/grounding/citations.py +348 -0
  26. marvisx_cli-0.3.8/core/api/services/grounding/verifier.py +118 -0
  27. marvisx_cli-0.3.8/core/api/services/inbox_digest_deep_research.py +153 -0
  28. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/embedding_router.py +4 -0
  29. marvisx_cli-0.3.8/core/api/services/kg/communities.py +227 -0
  30. marvisx_cli-0.3.8/core/api/services/kg/community_summary.py +105 -0
  31. marvisx_cli-0.3.8/core/api/services/kg/graph_lane.py +235 -0
  32. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/hybrid_search.py +171 -7
  33. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/rrf.py +40 -0
  34. marvisx_cli-0.3.8/core/api/services/temporal_tiebreak.py +200 -0
  35. marvisx_cli-0.3.8/core/api/services/temporal_write.py +431 -0
  36. marvisx_cli-0.3.8/core/api/tests/test_graph_freshness.py +126 -0
  37. marvisx_cli-0.3.8/core/api/tests/test_graph_freshness_flag.py +136 -0
  38. marvisx_cli-0.3.8/core/api/tests/test_graph_neighbors_denoise.py +167 -0
  39. marvisx_cli-0.3.8/core/api/tests/test_graph_summary.py +32 -0
  40. marvisx_cli-0.3.8/core/api/tests/test_kg_claims_builder.py +171 -0
  41. marvisx_cli-0.3.8/core/api/tests/test_kg_claims_wire.py +128 -0
  42. marvisx_cli-0.3.8/core/api/tests/test_kg_trust_write_path.py +143 -0
  43. marvisx_cli-0.3.8/core/api/tests/test_learnings_create_pre148.py +95 -0
  44. marvisx_cli-0.3.8/core/api/tests/test_migration_149.py +121 -0
  45. marvisx_cli-0.3.8/core/api/tests/test_populate_decay_flag.py +67 -0
  46. marvisx_cli-0.3.8/core/api/tests/test_session_brief_temporal.py +82 -0
  47. marvisx_cli-0.3.8/core/api/tests/test_temporal_recency.py +148 -0
  48. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/graph.py +556 -1
  49. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/learnings.py +327 -24
  50. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/projects.py +77 -3
  51. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/search.py +109 -7
  52. marvisx_cli-0.3.8/core/cli/_onboarding.py +250 -0
  53. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/guides/marvis-way.md +23 -0
  54. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_doctor.py +119 -2
  55. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_init.py +6 -0
  56. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_runtime.py +17 -5
  57. marvisx_cli-0.3.8/core/cli/marvis_task.py +206 -0
  58. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/populate_project_nodes.py +115 -6
  59. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/wizard/validation.py +2 -2
  60. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/marvisx_cli.egg-info/PKG-INFO +1 -1
  61. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/marvisx_cli.egg-info/SOURCES.txt +32 -0
  62. marvisx_cli-0.3.8/migrations/147_chunks.sql +32 -0
  63. marvisx_cli-0.3.8/migrations/147_chunks_down.sql +5 -0
  64. marvisx_cli-0.3.8/migrations/148_bitemporal_learnings.sql +47 -0
  65. marvisx_cli-0.3.8/migrations/148_bitemporal_learnings_down.sql +17 -0
  66. marvisx_cli-0.3.8/migrations/149_kg_trust_columns.sql +43 -0
  67. marvisx_cli-0.3.8/migrations/149_kg_trust_columns_down.sql +17 -0
  68. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/pyproject.toml +1 -1
  69. marvisx_cli-0.3.7b2/core/api/services/inbox_digest_deep_research.py +0 -80
  70. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/LICENSE +0 -0
  71. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/MANIFEST.in +0 -0
  72. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/README.md +0 -0
  73. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/__init__.py +0 -0
  74. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/agents/__init__.py +0 -0
  75. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/agents/session_health.py +0 -0
  76. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/agents/session_manager.py +0 -0
  77. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/bin/marvisx-state-hook.py +0 -0
  78. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/dependencies/__init__.py +0 -0
  79. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/dependencies/tenant.py +0 -0
  80. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/__init__.py +0 -0
  81. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/_adapter.py +0 -0
  82. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/__init__.py +0 -0
  83. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/brain.py +0 -0
  84. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/handoffs.py +0 -0
  85. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/ingest.py +0 -0
  86. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/projects.py +0 -0
  87. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/pull_requests.py +0 -0
  88. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/safety.py +0 -0
  89. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/search.py +0 -0
  90. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/tasks.py +0 -0
  91. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/workflow_playbooks/brainstorm.md +0 -0
  92. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/workflow_playbooks/compound.md +0 -0
  93. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/workflow_playbooks/plan.md +0 -0
  94. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/mcp/tools/workflows.py +0 -0
  95. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/middleware/__init__.py +0 -0
  96. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/middleware/tool_call_audit.py +0 -0
  97. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/__init__.py +0 -0
  98. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/auth.py +0 -0
  99. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/brain.py +0 -0
  100. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/common.py +0 -0
  101. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/costs.py +0 -0
  102. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/graph.py +0 -0
  103. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/graph_cosmo.py +0 -0
  104. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/graph_pr_impact.py +0 -0
  105. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/inbox.py +0 -0
  106. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/ingest_keys.py +0 -0
  107. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/kg.py +0 -0
  108. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/llm_config.py +0 -0
  109. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/monitoring.py +0 -0
  110. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/projects.py +0 -0
  111. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/sessions.py +0 -0
  112. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/tasks.py +0 -0
  113. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/teams.py +0 -0
  114. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/models/users.py +0 -0
  115. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/observability/__init__.py +0 -0
  116. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/observability/tracing.py +0 -0
  117. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/paths.py +0 -0
  118. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/rate_limit.py +0 -0
  119. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/rbac.py +0 -0
  120. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/__init__.py +0 -0
  121. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/_adapter.py +0 -0
  122. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/admin_pr_impact.py +0 -0
  123. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/admin_settings.py +0 -0
  124. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/agent.py +0 -0
  125. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/agent_tokens.py +0 -0
  126. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/app_settings.py +0 -0
  127. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/audit.py +0 -0
  128. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/auth.py +0 -0
  129. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/bench.py +0 -0
  130. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/brain.py +0 -0
  131. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/brain_directions.py +0 -0
  132. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/ci_checks.py +0 -0
  133. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/comments.py +0 -0
  134. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/costs.py +0 -0
  135. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/docs_coverage.py +0 -0
  136. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/docs_governance.py +0 -0
  137. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/documents.py +0 -0
  138. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/files.py +0 -0
  139. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/finder.py +0 -0
  140. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/handoffs.py +0 -0
  141. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/ingest_api_keys.py +0 -0
  142. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/ingest_triage.py +0 -0
  143. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/judge.py +0 -0
  144. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/kg.py +0 -0
  145. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/llm_config.py +0 -0
  146. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/monitoring.py +0 -0
  147. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/notifications.py +0 -0
  148. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/pr_impact.py +0 -0
  149. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/projects.py +0 -0
  150. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/pull_requests.py +0 -0
  151. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/push.py +0 -0
  152. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/raci.py +0 -0
  153. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/sessions.py +0 -0
  154. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/settings.py +0 -0
  155. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/share_repo.py +0 -0
  156. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/status_updates.py +0 -0
  157. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/tags.py +0 -0
  158. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/tasks.py +0 -0
  159. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/teams.py +0 -0
  160. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/terminal.py +0 -0
  161. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/users.py +0 -0
  162. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/routers/webhooks.py +0 -0
  163. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/runtime_settings.py +0 -0
  164. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/security.py +0 -0
  165. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/__init__.py +0 -0
  166. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/_fts.py +0 -0
  167. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/audit.py +0 -0
  168. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/auto_approval.py +0 -0
  169. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/__init__.py +0 -0
  170. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/baseline.py +0 -0
  171. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/capabilities.py +0 -0
  172. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/cascade_rollup.py +0 -0
  173. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/compound_bridge.py +0 -0
  174. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/cycle.py +0 -0
  175. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/cycle_snapshot.py +0 -0
  176. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/digest_collector.py +0 -0
  177. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/direction.py +0 -0
  178. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/drift.py +0 -0
  179. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/drift_router.py +0 -0
  180. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/edge_metrics.py +0 -0
  181. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/events_reader.py +0 -0
  182. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/findings.py +0 -0
  183. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/findings_reader.py +0 -0
  184. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/journal.py +0 -0
  185. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/knowledge_forms.py +0 -0
  186. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/__init__.py +0 -0
  187. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/_runner.py +0 -0
  188. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/base.py +0 -0
  189. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/cache.py +0 -0
  190. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/constants.py +0 -0
  191. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/direction_alignment.py +0 -0
  192. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/finding_reasoning.py +0 -0
  193. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/finding_summary.py +0 -0
  194. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/grounding.py +0 -0
  195. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/journal_polish.py +0 -0
  196. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/local_gateway.py +0 -0
  197. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/parsers.py +0 -0
  198. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/llm/router_glue.py +0 -0
  199. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/models.py +0 -0
  200. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/owner_hint.py +0 -0
  201. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/recap.py +0 -0
  202. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/__init__.py +0 -0
  203. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/_signals.py +0 -0
  204. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr1_activity_without_status.py +0 -0
  205. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr2_decision_without_adr.py +0 -0
  206. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr3_stale_open_loop.py +0 -0
  207. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr4_docs_governance_drift.py +0 -0
  208. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr5_playbook_changed.py +0 -0
  209. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr6_external_update_unpropagated.py +0 -0
  210. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr7_claimed_decision_gap.py +0 -0
  211. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/rules/dr8_direction_misalignment.py +0 -0
  212. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/runs_reader.py +0 -0
  213. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/scope.py +0 -0
  214. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/sources/__init__.py +0 -0
  215. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/sources/base.py +0 -0
  216. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/sources/git_kg.py +0 -0
  217. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/sources/handoffs.py +0 -0
  218. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/sources/ingestor.py +0 -0
  219. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/sources/learnings.py +0 -0
  220. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/sources/pir_tasks.py +0 -0
  221. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/warehouse_consolidate.py +0 -0
  222. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/watermarks.py +0 -0
  223. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/brain/ws_emitter.py +0 -0
  224. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/cc_tasks_reader.py +0 -0
  225. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ci_service.py +0 -0
  226. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/claude_metrics.py +0 -0
  227. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/codex_metrics.py +0 -0
  228. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/conversation_reader.py +0 -0
  229. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/cost_service.py +0 -0
  230. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/crypto.py +0 -0
  231. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/docs_governance/__init__.py +0 -0
  232. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/docs_governance/confidence.py +0 -0
  233. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/docs_governance/config.py +0 -0
  234. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/docs_governance/enrichment.py +0 -0
  235. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/docs_governance/frontmatter_validator.py +0 -0
  236. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/docs_governance/hard_gates.py +0 -0
  237. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/docs_governance/triage_orchestrator.py +0 -0
  238. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/embedding_backends/__init__.py +0 -0
  239. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/event_dispatcher.py +0 -0
  240. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/events.py +0 -0
  241. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/git_ops.py +0 -0
  242. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/graph_cosmo_service.py +0 -0
  243. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/graph_ranker.py +0 -0
  244. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox.py +0 -0
  245. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_digest.py +0 -0
  246. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_digest_jobs.py +0 -0
  247. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_gmail_sync.py +0 -0
  248. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_llm_classifier.py +0 -0
  249. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_source_identity.py +0 -0
  250. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_sources.py +0 -0
  251. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_taxonomy.py +0 -0
  252. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_tldr.py +0 -0
  253. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/inbox_triage.py +0 -0
  254. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/__init__.py +0 -0
  255. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/api_key_auth.py +0 -0
  256. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/auto_approve.py +0 -0
  257. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/classifier.py +0 -0
  258. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/confidence.py +0 -0
  259. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/dispatch.py +0 -0
  260. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/events.py +0 -0
  261. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/ignore_patterns.py +0 -0
  262. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/image_probe.py +0 -0
  263. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/ingress.py +0 -0
  264. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/insert_saga.py +0 -0
  265. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/__init__.py +0 -0
  266. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/anthropic_haiku.py +0 -0
  267. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/base.py +0 -0
  268. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/byok_provider.py +0 -0
  269. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/classification_context.py +0 -0
  270. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/config_store.py +0 -0
  271. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/factory.py +0 -0
  272. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/kg_enricher.py +0 -0
  273. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/local_gateway.py +0 -0
  274. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/local_vllm.py +0 -0
  275. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/llm/openai_nano.py +0 -0
  276. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/lock_advisory.py +0 -0
  277. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parser_router.py +0 -0
  278. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/__init__.py +0 -0
  279. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/docling_parser.py +0 -0
  280. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/docparse_gateway.py +0 -0
  281. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/docx_parser.py +0 -0
  282. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/folder_unpacker.py +0 -0
  283. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/gateway_aux.py +0 -0
  284. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/image_parser.py +0 -0
  285. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/internal_markdown.py +0 -0
  286. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/ocr_gateway.py +0 -0
  287. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/ocr_pdf_parser.py +0 -0
  288. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/pdf_types.py +0 -0
  289. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/transcript_parser.py +0 -0
  290. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/vision_gateway.py +0 -0
  291. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/xlsx_parser.py +0 -0
  292. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/parsers/zip_unpacker.py +0 -0
  293. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/preflight.py +0 -0
  294. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/routing_policy.py +0 -0
  295. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/serializers/__init__.py +0 -0
  296. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/serializers/xlsx_to_markdown.py +0 -0
  297. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/skip_log.py +0 -0
  298. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/ingest/watcher.py +0 -0
  299. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/__init__.py +0 -0
  300. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/audit.py +0 -0
  301. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/lens.py +0 -0
  302. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/pr_impact.py +0 -0
  303. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/queries.py +0 -0
  304. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg/ranking.py +0 -0
  305. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/kg_watcher_control.py +0 -0
  306. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/local_llm/__init__.py +0 -0
  307. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/local_llm/async_client.py +0 -0
  308. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/local_llm/client.py +0 -0
  309. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/local_llm/url_validator.py +0 -0
  310. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/metrics_collector.py +0 -0
  311. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/metrics_providers.py +0 -0
  312. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/model_registry.py +0 -0
  313. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/model_router.py +0 -0
  314. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/n8n_client.py +0 -0
  315. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/newsletter_llm_gateway.py +0 -0
  316. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/notification_service.py +0 -0
  317. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/openai_responses.py +0 -0
  318. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/opencode_metrics.py +0 -0
  319. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/opencode_sessions.py +0 -0
  320. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pii_redactor.py +0 -0
  321. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_impact_pipeline/__init__.py +0 -0
  322. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_impact_pipeline/differ.py +0 -0
  323. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_impact_pipeline/dispatcher.py +0 -0
  324. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_impact_pipeline/gc.py +0 -0
  325. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_impact_pipeline/languages.py +0 -0
  326. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_impact_pipeline/parser.py +0 -0
  327. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_impact_pipeline/writer.py +0 -0
  328. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/pr_service.py +0 -0
  329. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/project_paths.py +0 -0
  330. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/project_status_updates.py +0 -0
  331. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/providers.py +0 -0
  332. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/push_service.py +0 -0
  333. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/reminder_service.py +0 -0
  334. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/runas.py +0 -0
  335. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/salience_service.py +0 -0
  336. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/security_collector.py +0 -0
  337. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/session_catalog.py +0 -0
  338. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/session_metrics_service.py +0 -0
  339. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/session_ops.py +0 -0
  340. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/session_state.py +0 -0
  341. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/share_links.py +0 -0
  342. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/task_transitions.py +0 -0
  343. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/terminal_metrics.py +0 -0
  344. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/terminal_metrics_dump.py +0 -0
  345. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/tmux.py +0 -0
  346. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/webhook_service.py +0 -0
  347. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/services/workspace_sync.py +0 -0
  348. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/templates/__init__.py +0 -0
  349. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/templates/markdown_share.py +0 -0
  350. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/terminal.py +0 -0
  351. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/__init__.py +0 -0
  352. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_agent_facing_auth_dependencies.py +0 -0
  353. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_audit_permissions.py +0 -0
  354. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_backfill_session_conversations.py +0 -0
  355. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_backfill_working_seconds_msg.py +0 -0
  356. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_claude_metrics.py +0 -0
  357. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_codex_metrics.py +0 -0
  358. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_config_env_aliases.py +0 -0
  359. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_finder_paths.py +0 -0
  360. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_git_ops_merge.py +0 -0
  361. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_learnings_check_search.py +0 -0
  362. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_metrics_providers.py +0 -0
  363. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_migration_087.py +0 -0
  364. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_migration_088.py +0 -0
  365. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_migration_089.py +0 -0
  366. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_openai_responses.py +0 -0
  367. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_opencode_metrics.py +0 -0
  368. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_opencode_sessions.py +0 -0
  369. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_pr_workflow_e2e.py +0 -0
  370. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_projects_handoffs.py +0 -0
  371. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_providers.py +0 -0
  372. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_require_scope_empty_deny.py +0 -0
  373. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_safety_bridge.py +0 -0
  374. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_session_catalog.py +0 -0
  375. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_session_conversations.py +0 -0
  376. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_session_metrics_service.py +0 -0
  377. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_session_resume_paths.py +0 -0
  378. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_session_theme_mode_migration.py +0 -0
  379. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_sessions_rbac.py +0 -0
  380. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_share_edit.py +0 -0
  381. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_share_repo.py +0 -0
  382. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_terminal_session_manager.py +0 -0
  383. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_terminal_upload.py +0 -0
  384. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_tmux.py +0 -0
  385. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_workspace_sync.py +0 -0
  386. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/tests/test_ws_ticket_in_memory.py +0 -0
  387. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/__init__.py +0 -0
  388. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/_context.py +0 -0
  389. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/_errors.py +0 -0
  390. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/_roles.py +0 -0
  391. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/audit.py +0 -0
  392. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/brain.py +0 -0
  393. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/costs.py +0 -0
  394. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/handoffs.py +0 -0
  395. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/ingest_triage.py +0 -0
  396. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/pull_requests.py +0 -0
  397. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/use_cases/tasks.py +0 -0
  398. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/api/visibility.py +0 -0
  399. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/README.md +0 -0
  400. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/__init__.py +0 -0
  401. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/_brain_opportunistic.py +0 -0
  402. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/_brain_schedule.py +0 -0
  403. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/_index_source.py +0 -0
  404. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/_runtime_ctx.py +0 -0
  405. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/_transmute.py +0 -0
  406. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/_update_check.py +0 -0
  407. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/guides/__init__.py +0 -0
  408. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_account.py +0 -0
  409. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_brain.py +0 -0
  410. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_feedback.py +0 -0
  411. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_governance.py +0 -0
  412. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_guide.py +0 -0
  413. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_hooks.py +0 -0
  414. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_mcp.py +0 -0
  415. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/cli/marvis_telemetry.py +0 -0
  416. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/platform/__init__.py +0 -0
  417. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/_drift_check.py +0 -0
  418. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/_frontmatter.py +0 -0
  419. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/_graph_writer.py +0 -0
  420. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/ast_parser.py +0 -0
  421. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/__init__.py +0 -0
  422. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/_config.sh +0 -0
  423. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/block-dangerous-bash.sh +0 -0
  424. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/block-db-direct-write.sh +0 -0
  425. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/block-push-no-task.sh +0 -0
  426. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/block-staging-to-prod.sh +0 -0
  427. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/block-subtree-push.sh +0 -0
  428. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/config.json +0 -0
  429. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/enforce-no-merge-main.sh +0 -0
  430. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/enforce-worktree.sh +0 -0
  431. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/quality-gate.sh +0 -0
  432. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/safety_bridge.py +0 -0
  433. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/install_hooks/secret-scan.sh +0 -0
  434. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/migrate_spike_node_ids.py +0 -0
  435. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/populate_artifacts.py +0 -0
  436. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/populate_cross_project.py +0 -0
  437. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/populate_inbox_nodes.py +0 -0
  438. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/populate_pr_impact.py +0 -0
  439. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/populate_touch_counter.py +0 -0
  440. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/reparse_failed.py +0 -0
  441. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/scripts/safety_bridge.py +0 -0
  442. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/telemetry/__init__.py +0 -0
  443. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/telemetry/client.py +0 -0
  444. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/telemetry/entitlements.py +0 -0
  445. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/telemetry/rollup.py +0 -0
  446. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/telemetry/schema.py +0 -0
  447. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/telemetry/sender.py +0 -0
  448. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/wizard/__init__.py +0 -0
  449. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/wizard/byok_vault.py +0 -0
  450. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/wizard/defaults.py +0 -0
  451. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/wizard/state.py +0 -0
  452. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/core/wizard/steps.py +0 -0
  453. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/marvisx_cli.egg-info/dependency_links.txt +0 -0
  454. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/marvisx_cli.egg-info/entry_points.txt +0 -0
  455. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/marvisx_cli.egg-info/requires.txt +0 -0
  456. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/marvisx_cli.egg-info/top_level.txt +0 -0
  457. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/001_initial.sql +0 -0
  458. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/002_tasks.sql +0 -0
  459. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/003_session_management.sql +0 -0
  460. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/004_projects_comments.sql +0 -0
  461. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/005_session_intelligence.sql +0 -0
  462. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/006_settings.sql +0 -0
  463. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/007_task_scoring.sql +0 -0
  464. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/008_cost_tracking.sql +0 -0
  465. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/009_session_card_metrics.sql +0 -0
  466. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/010_monitoring.sql +0 -0
  467. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/012_agent_api.sql +0 -0
  468. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/013_session_complete.sql +0 -0
  469. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/015_pull_requests.sql +0 -0
  470. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/015_pull_requests_down.sql +0 -0
  471. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/016_users_raci.sql +0 -0
  472. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/017_task_cost_entries.sql +0 -0
  473. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/018_agents.sql +0 -0
  474. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/018_agents_down.sql +0 -0
  475. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/019_review_feedback.sql +0 -0
  476. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/020_pr_commit_sha.sql +0 -0
  477. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/021_webhook_events.sql +0 -0
  478. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/022_devx_agent_managed.sql +0 -0
  479. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/022_devx_agent_managed_down.sql +0 -0
  480. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/023_devx_p1_gate.sql +0 -0
  481. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/023_devx_p1_gate_down.sql +0 -0
  482. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/024_chat_messages.sql +0 -0
  483. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/024_pr_conversation_id.sql +0 -0
  484. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/024_task_indexes.sql +0 -0
  485. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/024_task_indexes_down.sql +0 -0
  486. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/025_audit_log.sql +0 -0
  487. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/026_agent_tokens.sql +0 -0
  488. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/027_teams_auth_phase_b.sql +0 -0
  489. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/028_learnings.sql +0 -0
  490. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/029_team_roles.sql +0 -0
  491. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/030_finder_pins.sql +0 -0
  492. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/031_pr_deploy_status.sql +0 -0
  493. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/032_task_reminders.sql +0 -0
  494. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/033_events_retry_count.sql +0 -0
  495. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/033_session_owner.sql +0 -0
  496. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/034_notifications.sql +0 -0
  497. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/035_shared_links.sql +0 -0
  498. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/036_session_index_upgrade.sql +0 -0
  499. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/037_pr_approval.sql +0 -0
  500. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/038_pr_submitted_by.sql +0 -0
  501. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/039_push_subscriptions.sql +0 -0
  502. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/040_semantic_search.sql +0 -0
  503. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/041_workspaces.sql +0 -0
  504. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/042_oidc_providers.sql +0 -0
  505. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/043_ci_checks.sql +0 -0
  506. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/044_agent_metrics.sql +0 -0
  507. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/045_documents_doc_type.sql +0 -0
  508. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/046_salience.sql +0 -0
  509. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/047_seed_missing_agents.sql +0 -0
  510. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/048_fix_agent_paths_roles.sql +0 -0
  511. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/049_agent_role_and_learnings_schema.sql +0 -0
  512. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/050_session_provider.sql +0 -0
  513. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/051_session_launch_profile.sql +0 -0
  514. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/052_session_theme_mode.sql +0 -0
  515. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/052_task_kind.sql +0 -0
  516. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/053_inbox_items.sql +0 -0
  517. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/054_inbox_triage_contract.sql +0 -0
  518. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/055_inbox_topic_treatment.sql +0 -0
  519. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/056_inbox_treatment_read_save.sql +0 -0
  520. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/057_session_theme_mode_backfill.sql +0 -0
  521. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/058_inbox_item_status_lifecycle.sql +0 -0
  522. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/059_inbox_tldr_and_source_scores.sql +0 -0
  523. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/060_newsletter.sql +0 -0
  524. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/061_inbox_redesign.sql +0 -0
  525. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/062_fix_inbox_sources_backfill.sql +0 -0
  526. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/063_task_completion_mode.sql +0 -0
  527. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/064_judge_mode_setting.sql +0 -0
  528. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/065_knowledge_graph_spike.sql +0 -0
  529. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/066_digest_ranking_inputs.sql +0 -0
  530. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/066_kg_artifact_nodes.sql +0 -0
  531. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/067_inbox_digest_selections.sql +0 -0
  532. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/067_kg_temporal.sql +0 -0
  533. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/068_inbox_digest_app_settings.sql +0 -0
  534. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/068_kg_touch_counter.sql +0 -0
  535. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/069_kg_doc_types.sql +0 -0
  536. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/070_digest_ranking_inputs_recovery.sql +0 -0
  537. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/071_inbox_digest_selections_recovery.sql +0 -0
  538. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/072_inbox_digest_app_settings_recovery.sql +0 -0
  539. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/073_kg_cross_project.sql +0 -0
  540. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/073_kg_cross_project_down.sql +0 -0
  541. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/074_kg_infra_types.sql +0 -0
  542. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/074_kg_infra_types_down.sql +0 -0
  543. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/075_kg_file_state_recovery.sql +0 -0
  544. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/075_kg_file_state_recovery_down.sql +0 -0
  545. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/076_kg_watcher_state.sql +0 -0
  546. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/076_kg_watcher_state_down.sql +0 -0
  547. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/077_kg_doc_types_extend.sql +0 -0
  548. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/077_kg_doc_types_extend_down.sql +0 -0
  549. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/078_kg_fts5.sql +0 -0
  550. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/078_kg_fts5_down.sql +0 -0
  551. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/079_kg_missing_indexes.sql +0 -0
  552. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/079_kg_missing_indexes_down.sql +0 -0
  553. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/080_kg_fts5_extended.sql +0 -0
  554. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/080_kg_fts5_extended_down.sql +0 -0
  555. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/081_kg_lens_indexes.sql +0 -0
  556. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/081_kg_lens_indexes_down.sql +0 -0
  557. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/082_kg_pins.sql +0 -0
  558. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/082_kg_pins_down.sql +0 -0
  559. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/083_kg_graph_nodes_degree.sql +0 -0
  560. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/083_kg_graph_nodes_degree_down.sql +0 -0
  561. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/084_drop_legacy_scheduler_tables.sql +0 -0
  562. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/084_drop_legacy_scheduler_tables_down.sql +0 -0
  563. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/085_kg_edge_resolves_to.sql +0 -0
  564. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/085_kg_edge_resolves_to_down.sql +0 -0
  565. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/086_project_status_updates_feed.sql +0 -0
  566. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/086_project_status_updates_feed_down.sql +0 -0
  567. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/087_session_metrics_dual.sql +0 -0
  568. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/087_session_metrics_dual_down.sql +0 -0
  569. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/088_rename_context_pct_legacy.sql +0 -0
  570. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/088_rename_context_pct_legacy_down.sql +0 -0
  571. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/089_session_metrics_equivalent_cost.sql +0 -0
  572. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/089_session_metrics_equivalent_cost_down.sql +0 -0
  573. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/090_kg_inbox_node_type.sql +0 -0
  574. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/090_kg_inbox_node_type_down.sql +0 -0
  575. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/091_kg_inbox_node_type_check.sql +0 -0
  576. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/091_kg_inbox_node_type_check_down.sql +0 -0
  577. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/092_sessions_activity_state_ts.sql +0 -0
  578. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/092_sessions_activity_state_ts_down.sql +0 -0
  579. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/093_sessions_activity_state_column.sql +0 -0
  580. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/093_sessions_activity_state_column_down.sql +0 -0
  581. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/094_ingest_pending.sql +0 -0
  582. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/094_ingest_pending_down.sql +0 -0
  583. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/095_kg_intent_first.sql +0 -0
  584. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/095_kg_intent_first_down.sql +0 -0
  585. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/096_kg_xlsx_artifact_prefix.sql +0 -0
  586. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/096_kg_xlsx_artifact_prefix_down.sql +0 -0
  587. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/097_ingest_change_history.sql +0 -0
  588. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/097_ingest_change_history_down.sql +0 -0
  589. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/098_kg_node_type_business.sql +0 -0
  590. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/098_kg_node_type_business_down.sql +0 -0
  591. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/099_kg_edges_restore_weight.sql +0 -0
  592. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/099_kg_edges_restore_weight_down.sql +0 -0
  593. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/100_kg_enriched_at.sql +0 -0
  594. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/100_kg_enriched_at_down.sql +0 -0
  595. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/101_local_llm_shadow_comparisons.sql +0 -0
  596. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/101_local_llm_shadow_comparisons_down.sql +0 -0
  597. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/102_promote_llm_costs.sql +0 -0
  598. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/102_promote_llm_costs_down.sql +0 -0
  599. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/103_ingest_skipped_log.sql +0 -0
  600. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/103_ingest_skipped_log_down.sql +0 -0
  601. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/120_docs_governance.sql +0 -0
  602. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/120_docs_governance_down.sql +0 -0
  603. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/121_notification_event_fk_cleanup.sql +0 -0
  604. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/121_notification_event_fk_cleanup_down.sql +0 -0
  605. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/122_docs_drift_history.sql +0 -0
  606. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/122_docs_drift_history_down.sql +0 -0
  607. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/123_ingest_parser_waiting_status.sql +0 -0
  608. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/123_ingest_parser_waiting_status_down.sql +0 -0
  609. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/124_heypocket_recordings.sql +0 -0
  610. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/124_heypocket_recordings_down.sql +0 -0
  611. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/125_kg_node_type_record.sql +0 -0
  612. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/125_kg_node_type_record_down.sql +0 -0
  613. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/126_ingest_terminal_upload_source_kind.sql +0 -0
  614. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/126_ingest_terminal_upload_source_kind_down.sql +0 -0
  615. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/127_brain_v1_substrate.sql +0 -0
  616. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/127_brain_v1_substrate_down.sql +0 -0
  617. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/128_brain_drift_signals.sql +0 -0
  618. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/128_brain_drift_signals_down.sql +0 -0
  619. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/129_brain_memory_operations.sql +0 -0
  620. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/129_brain_memory_operations_down.sql +0 -0
  621. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/130_brain_findings.sql +0 -0
  622. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/130_brain_findings_down.sql +0 -0
  623. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/132_kg_pr_modifies.sql +0 -0
  624. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/132_kg_pr_modifies_down.sql +0 -0
  625. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/133_brain_v1_2_direction_schema.sql +0 -0
  626. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/133_brain_v1_2_direction_schema_down.sql +0 -0
  627. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/134_brain_journal_narrative_polished.sql +0 -0
  628. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/134_brain_journal_narrative_polished_down.sql +0 -0
  629. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/135_kg_edges_provider.sql +0 -0
  630. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/136_documents_fts.sql +0 -0
  631. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/137_promote_llm_costs.sql +0 -0
  632. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/137_promote_llm_costs_down.sql +0 -0
  633. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/138_ingest_api_keys.sql +0 -0
  634. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/138_ingest_api_keys_down.sql +0 -0
  635. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/139_ingest_pending_ingress.sql +0 -0
  636. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/139_ingest_pending_ingress_down.sql +0 -0
  637. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/140_ingest_idempotency_quota.sql +0 -0
  638. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/140_ingest_idempotency_quota_down.sql +0 -0
  639. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/141_ingest_pending_metadata.sql +0 -0
  640. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/141_ingest_pending_metadata_down.sql +0 -0
  641. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/142_llm_function_config.sql +0 -0
  642. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/142_llm_function_config_down.sql +0 -0
  643. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/143_kg_code_embeddings.sql +0 -0
  644. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/143_kg_code_embeddings_down.sql +0 -0
  645. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/144_notifications_pending_sync_index.sql +0 -0
  646. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/145_audit_log_immutable.sql +0 -0
  647. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/145_audit_log_immutable_down.sql +0 -0
  648. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/146_drop_kg_backup_tables.sql +0 -0
  649. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/146_drop_kg_backup_tables_down.sql +0 -0
  650. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/migrations/__init__.py +0 -0
  651. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/context.md +0 -0
  652. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/docs/brainstorms/YYYY-MM-DD-example-brainstorm.md +0 -0
  653. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/docs/plans/YYYY-MM-DD-example-plan.md +0 -0
  654. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/docs/solutions/YYYY-MM-DD-example-solution.md +0 -0
  655. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/input/README.md +0 -0
  656. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/memory/handoff.md +0 -0
  657. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/output/README.md +0 -0
  658. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/projects/_template/project.yaml +0 -0
  659. {marvisx_cli-0.3.7b2 → marvisx_cli-0.3.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: marvisx-cli
3
- Version: 0.3.7b2
3
+ Version: 0.3.8
4
4
  Summary: MarvisX OSS — agent-native company-brain CLI runtime (init, status, brief, triage)
5
5
  Author: MarvisX maintainers
6
6
  License: BSL-1.1
@@ -125,6 +125,13 @@ class Settings(BaseSettings):
125
125
  default=86400, alias="BRAIN_WAREHOUSE_CONSOLIDATION_INTERVAL_SECONDS"
126
126
  )
127
127
 
128
+ # KG temporal recency pass (Fase D producer): proposes re-verifying aging,
129
+ # never-verified live nodes. Gated by temporal_memory_enabled (no separate
130
+ # enable flag — the flag IS the gate). Daily cadence guard.
131
+ brain_temporal_recency_interval_seconds: int = Field(
132
+ default=86400, alias="BRAIN_TEMPORAL_RECENCY_INTERVAL_SECONDS"
133
+ )
134
+
128
135
  # GitHub Webhook
129
136
  github_webhook_secret: str = ""
130
137
 
@@ -439,6 +446,103 @@ class Settings(BaseSettings):
439
446
  False # pydantic-settings maps KG_HTTP_DEEP_DEFAULT env var
440
447
  )
441
448
 
449
+ # Track 2 #3a — STRUCTURAL graph-lane in the RRF fusion (DEFAULT OFF).
450
+ # When False the fused ranking is byte-identical to today (5 lanes). When
451
+ # True a 6th lane (seeded 1-hop edge-weighted KG expansion) joins the blend.
452
+ # graph_lane_hops / graph_lane_fanout / graph_lane_weight / graph_lane_seeds
453
+ # tune the lane without code changes. Edge-type subset = all 15 by default.
454
+ graph_lane_enabled: bool = Field(
455
+ default=False, alias="MARVIS_GRAPH_LANE"
456
+ )
457
+ graph_lane_hops: int = Field(default=1, alias="MARVIS_GRAPH_LANE_HOPS")
458
+ graph_lane_fanout: int = Field(default=25, alias="MARVIS_GRAPH_LANE_FANOUT")
459
+ graph_lane_seeds: int = Field(default=10, alias="MARVIS_GRAPH_LANE_SEEDS")
460
+ graph_lane_weight: float = Field(
461
+ default=0.12, alias="MARVIS_GRAPH_LANE_WEIGHT"
462
+ )
463
+ # #13: when a graph read finds its index stale/behind HEAD, surface the
464
+ # reindex as an EXPLICIT next action (command + auto_reindex marker). Default
465
+ # off; even when on, a read NEVER fires the (heavy, repo-re-parsing) KG
466
+ # reindex itself — re-indexing stays an explicit operation.
467
+ graph_autoreindex_on_drift: bool = Field(
468
+ default=False, alias="MARVIS_GRAPH_AUTOREINDEX_ON_DRIFT"
469
+ )
470
+
471
+ # Track 2 #1 — bi-temporal memory READ path (DEFAULT OFF). When False every
472
+ # learnings read is byte-identical to today (no invalid_at filter, no as_of):
473
+ # the temporal helper emits NO extra SQL. When True the default learnings
474
+ # reads (check/list/get + the learnings retrieval lane in search) add
475
+ # ``AND invalid_at IS NULL`` — a MECHANICAL, BINARY exclusion (superseded rows
476
+ # never reach the LLM; never a down-weight, which would still let the model
477
+ # cite the stale value). An explicit ``as_of=<ISO>`` relaxes the filter to the
478
+ # point-in-time window ``valid_from <= as_of AND (invalid_at IS NULL OR
479
+ # invalid_at > as_of)`` for audit. S3/S4/S5 (write path / LLM tiebreak / dream
480
+ # cycle) reuse this SAME flag. Requires migration 148 columns when enabled.
481
+ temporal_memory_enabled: bool = Field(
482
+ default=False, alias="MARVIS_TEMPORAL_MEMORY"
483
+ )
484
+
485
+ # answer-ready claims (DEFAULT OFF). When False every reasoning-tool read is
486
+ # byte-identical to today (no `claims` key). When True, project_impact/
487
+ # graph_impact append a `claims[]` block: server-computed, relation-typed
488
+ # counts with provenance — the agent reports the value instead of re-counting
489
+ # raw edges (faithfulness). Separate from temporal_memory so grounding can be
490
+ # enabled without the freshness surface. See plan 2026-06-08-feat-answer-ready-claims.
491
+ kg_claims_enabled: bool = Field(
492
+ default=False, alias="MARVIS_KG_CLAIMS"
493
+ )
494
+
495
+ # Memory-freshness v2a Phase 1 (B-fix, DEFAULT OFF). The documents_fts
496
+ # INSERT/UPDATE triggers (migration 136) write file_path into the content
497
+ # column, so every doc written AFTER the one-time migration backfill has NO
498
+ # body in the lexical lane (prod 2026-06-09: 100% of recent docs degraded
499
+ # → the BM25 lane sees OLD bodies but never NEW ones — a direct stale-
500
+ # retrieval mechanism). When True, every documents upsert path additionally
501
+ # overwrites the trigger-degraded FTS row with the real title+body
502
+ # (refresh_documents_fts_row). When False the refresh helper is a no-op and
503
+ # behavior is byte-identical to today. The one-shot backfill script
504
+ # (scripts/backfill_documents_fts.py) repairs historical rows; in prod the
505
+ # flag must flip ON at backfill time and stay on, otherwise the next doc
506
+ # update re-degrades its row. See plan
507
+ # 2026-06-09-feat-memory-freshness-v2a-retrieval.
508
+ fts_bodies_enabled: bool = Field(
509
+ default=False, alias="MARVIS_FTS_BODIES"
510
+ )
511
+
512
+ # Memory-freshness v2a Phase 2 (A-span, DEFAULT OFF). When False the search
513
+ # read path never touches the chunks/vec_chunks sidecars and the response is
514
+ # byte-identical to today (no span_* fields populated). When True (and
515
+ # MARVIS_CHUNKING populated the sidecars), the semantic lane max-pools
516
+ # chunk-KNN hits into the doc ranking and each file-backed hit carries the
517
+ # winning chunk's span expanded to line boundaries ±12 lines (span_text /
518
+ # span_path / span_line_start / span_line_end) so the agent can answer FROM
519
+ # the search result without a follow-up Read. Write-side chunking stays
520
+ # gated by MARVIS_CHUNKING (env, read per-call). See plan
521
+ # 2026-06-09-feat-memory-freshness-v2a-retrieval.
522
+ search_spans_enabled: bool = Field(
523
+ default=False, alias="MARVIS_SEARCH_SPANS"
524
+ )
525
+
526
+ # Track 2 #3c — community summaries in the brief (GraphRAG global-search,
527
+ # DEFAULT OFF). When False the brief is byte-identical to today: the
528
+ # communities/community_summary modules are a flag-gated library + seam,
529
+ # never imported into session_brief. When True (off-host wiring), the KG is
530
+ # partitioned (deterministic label propagation, NO LLM) and per-community
531
+ # summaries enter the brief AFTER #2 so they inherit span-citation + NLI
532
+ # verification (a summary is itself a claim to ground, not free text).
533
+ community_summaries_enabled: bool = Field(
534
+ default=False, alias="MARVIS_COMMUNITY_SUMMARIES"
535
+ )
536
+
537
+ # Track 2 #2: span-citation + grounding-verification layer for the brief.
538
+ # DEFAULT OFF — the layer exists as a flag-gated library; when off the
539
+ # session_brief output is byte-for-byte unchanged (the seam is never entered).
540
+ # See core/api/services/grounding/. Wiring the NLI head (MiniCheck) is a
541
+ # separate, deliberate, off-host step (NoopVerifier is the default).
542
+ brief_citations_enabled: bool = Field(
543
+ default=False, alias="MARVIS_BRIEF_CITATIONS"
544
+ )
545
+
442
546
  # WIP limit: max tasks in_progress per project (doc/none tasks count as 0.5)
443
547
  wip_max_in_progress: int = 3
444
548
 
@@ -461,6 +565,15 @@ class Settings(BaseSettings):
461
565
  brain_llm_polish_enabled: bool = Field(
462
566
  default=True, alias="BRAIN_LLM_POLISH_ENABLED"
463
567
  )
568
+ # P1: pick the Brain LLM backend. "gateway" (default, unchanged) = the HTTP
569
+ # Mac-gateway client (requires BRAIN_LLM_GATEWAY_API_KEY). "claude_cli" = run
570
+ # `claude -p` headless on the user's Claude Code subscription (NO API key) —
571
+ # see core/api/services/brain/llm/claude_cli.py.
572
+ brain_llm_provider: Literal["gateway", "claude_cli"] = Field(
573
+ default="gateway", alias="BRAIN_LLM_PROVIDER"
574
+ )
575
+ # Path/name of the `claude` binary for the claude_cli provider.
576
+ marvis_claude_bin: str = Field(default="claude", alias="MARVIS_CLAUDE_BIN")
464
577
  brain_llm_journal_polish_enabled: bool = Field(
465
578
  default=True, alias="BRAIN_LLM_JOURNAL_POLISH_ENABLED"
466
579
  )
@@ -118,6 +118,13 @@ async def init_pool(size: int = 2) -> None:
118
118
 
119
119
  Pool size=8 supports concurrent deep=true requests (4 parallel KG subqueries × 2 concurrent requests).
120
120
  """
121
+ # Apply any pending schema migrations before opening the pool, so EVERY
122
+ # entry point (CLI, MCP, brain, API) lands on a current schema — not only
123
+ # `marvis init` and the API lifespan. Idempotent and cheap when already
124
+ # current (the API path migrates explicitly first, so this finds nothing).
125
+ # Fail-loud here is a clearer signal than a later "no such column" on the
126
+ # first write against a half-upgraded DB. (#12)
127
+ run_migrations()
121
128
  global _pool, _pool_size, _writer
122
129
  actual_size = 8 # read-only pool: expanded for KG lens 4-subquery parallel pattern (Phase 7.0)
123
130
  _pool = asyncio.Queue(maxsize=actual_size)
@@ -732,54 +739,62 @@ def _backfill_session_uuids(conn: sqlite3.Connection) -> None:
732
739
 
733
740
 
734
741
  def _seed_users_and_migrate_owner(conn: sqlite3.Connection) -> None:
735
- """Migration 016 post-hook: seed the admin user + data-migrate tasks.owner_id.
742
+ """Migration 016 post-hook: seed the admin user (when configured) + data-migrate
743
+ tasks.owner_id.
736
744
 
737
745
  Runs synchronously inside run_migrations() — do NOT use await here.
738
- Accepts either PIR_ADMIN_PASSWORD_HASH (pre-hashed, preferred in production)
739
- or PIR_PASSWORD (plaintext, will be bcrypt-hashed here).
740
- At least one must be set or the migration aborts.
741
-
742
- The admin identity is config-driven via the same MARVIS_ADMIN_* vars used by
743
- the deploy bootstrap (scripts/init.sh), with generic defaults, so a fresh
744
- install seeds no hardcoded name. On an existing deployment this seed is
745
- skipped (users already exist), so the defaults never affect a running install.
746
- """
747
- # Prefer pre-hashed password. Canonical var is MARVIS_ADMIN_PASSWORD_HASH;
748
- # PIR_ADMIN_PASSWORD_HASH stays accepted as a deprecated alias.
749
- hashed = (
750
- os.environ.get("MARVIS_ADMIN_PASSWORD_HASH")
751
- or os.environ.get("PIR_ADMIN_PASSWORD_HASH", "")
752
- ).strip()
753
- if not hashed:
754
- import bcrypt
755
-
756
- seed_password = (
757
- os.environ.get("MARVIS_PASSWORD")
758
- or os.environ.get("PIR_PASSWORD", "")
759
- ).strip()
760
- if not seed_password:
761
- raise RuntimeError(
762
- "Migration 016 requires MARVIS_ADMIN_PASSWORD_HASH or MARVIS_PASSWORD "
763
- "env var (PIR_* aliases still accepted) to seed the admin user. "
764
- "Set at least one in .env."
765
- )
766
- hashed = bcrypt.hashpw(seed_password.encode("utf-8"), bcrypt.gensalt()).decode()
767
-
768
- admin_id = os.environ.get("MARVIS_ADMIN_USER_ID", "").strip() or "usr_admin"
769
- admin_slug = os.environ.get("MARVIS_ADMIN_SLUG", "").strip() or "admin"
770
- admin_name = os.environ.get("MARVIS_ADMIN_DISPLAY_NAME", "").strip() or "Admin"
771
746
 
747
+ Admin seeding is OPTIONAL and config-driven: the admin user is created only when
748
+ a real credential is present (MARVIS_ADMIN_PASSWORD_HASH or MARVIS_PASSWORD; PIR_*
749
+ aliases accepted). With NO credential — the OSS single-user case, where the CLI
750
+ uses the local single-user context and never logs in with a password — the seed
751
+ is SKIPPED (not aborted), so a fresh-DB boot via init_pool (MCP server / brain,
752
+ which now run migrations) does not crash on a clean install. `marvis init` sets
753
+ MARVIS_PASSWORD before migrating, so it still seeds the admin. The owner_id
754
+ slug→id data migration always runs (idempotent), regardless of seeding.
755
+
756
+ b3 note: the real cleanup is to decouple admin seeding from run_migrations
757
+ entirely — it belongs in `marvis init` / `marvis account`, not in a schema hook.
758
+ """
772
759
  cursor = conn.execute("SELECT COUNT(*) FROM users")
773
760
  user_count = cursor.fetchone()[0]
774
761
  if user_count == 0:
775
- conn.execute(
776
- "INSERT OR IGNORE INTO users "
777
- "(id, slug, display_name, type, password_hash, system_role) "
778
- "VALUES (?, ?, ?, ?, ?, ?)",
779
- (admin_id, admin_slug, admin_name, "human", hashed, "super_admin"),
780
- )
781
- conn.commit()
782
- logger.info("Migration 016: seeded admin user '%s' (super_admin)", admin_slug)
762
+ # Prefer a pre-hashed password (canonical MARVIS_ADMIN_PASSWORD_HASH;
763
+ # PIR_ADMIN_PASSWORD_HASH stays a deprecated alias).
764
+ hashed = (
765
+ os.environ.get("MARVIS_ADMIN_PASSWORD_HASH")
766
+ or os.environ.get("PIR_ADMIN_PASSWORD_HASH", "")
767
+ ).strip()
768
+ if not hashed:
769
+ seed_password = (
770
+ os.environ.get("MARVIS_PASSWORD")
771
+ or os.environ.get("PIR_PASSWORD", "")
772
+ ).strip()
773
+ if seed_password:
774
+ import bcrypt
775
+
776
+ hashed = bcrypt.hashpw(
777
+ seed_password.encode("utf-8"), bcrypt.gensalt()
778
+ ).decode()
779
+ else:
780
+ logger.warning(
781
+ "Migration 016: no MARVIS_ADMIN_PASSWORD_HASH / MARVIS_PASSWORD in "
782
+ "env — admin user NOT seeded (schema applied). Single-user CLI uses "
783
+ "the local context (no login); create an admin later with `marvis "
784
+ "init` if you want HTTP login."
785
+ )
786
+ if hashed: # seed ONLY when we actually have a credential
787
+ admin_id = os.environ.get("MARVIS_ADMIN_USER_ID", "").strip() or "usr_admin"
788
+ admin_slug = os.environ.get("MARVIS_ADMIN_SLUG", "").strip() or "admin"
789
+ admin_name = os.environ.get("MARVIS_ADMIN_DISPLAY_NAME", "").strip() or "Admin"
790
+ conn.execute(
791
+ "INSERT OR IGNORE INTO users "
792
+ "(id, slug, display_name, type, password_hash, system_role) "
793
+ "VALUES (?, ?, ?, ?, ?, ?)",
794
+ (admin_id, admin_slug, admin_name, "human", hashed, "super_admin"),
795
+ )
796
+ conn.commit()
797
+ logger.info("Migration 016: seeded admin user '%s' (super_admin)", admin_slug)
783
798
 
784
799
  # Data migration: owner_id may contain slug strings (e.g. "emilio") from before
785
800
  # the users table existed. Resolve each slug to the corresponding users.id.
@@ -931,6 +931,20 @@ async def _periodic_inbox_digest() -> None:
931
931
  result.get("overflow", 0),
932
932
  result.get("expired", 0),
933
933
  )
934
+ # Invariant guard: every VISIBLE item must be deepened. The 6 UTC
935
+ # precompute is best-effort/one-shot; this sweep catches its failures
936
+ # and items promoted into visible later in the day.
937
+ from core.api.services.inbox_digest_deep_research import (
938
+ sweep_visible_missing_deep_research,
939
+ )
940
+
941
+ sweep = await sweep_visible_missing_deep_research()
942
+ if sweep.get("missing"):
943
+ logger.info(
944
+ "Digest deep-research sweep: deepened %d/%d missing visible items",
945
+ sweep.get("generated", 0),
946
+ sweep.get("missing", 0),
947
+ )
934
948
  except asyncio.CancelledError:
935
949
  break
936
950
  except Exception:
@@ -34,10 +34,58 @@ from core.api.mcp.tools import register_all
34
34
  # `app.state` equivalent for a server with no FastAPI `app`). Tools register on
35
35
  # this at import time so `from core.api.mcp.server import mcp` already carries the
36
36
  # full tool set — the smoke test introspects it without launching stdio.
37
- mcp = FastMCP("marvis")
37
+ _INSTRUCTIONS = (
38
+ "Marvis is a company-brain MCP for cross-project orchestration and institutional memory.\n"
39
+ "Route by task type (prefer these structured tools over re-deriving context from raw files):\n"
40
+ "- Cold-start / 'state of project X': session_brief(slug) — it also suggests the next tool when the project is cross-project.\n"
41
+ "- 'If I pause / close / de-prioritize project X, what blocks?': project_impact(slug) — the project-level blast radius. "
42
+ "(graph_impact on a 'project:artifact:<slug>' node with depends_on does the same.)\n"
43
+ "- 'What breaks if I change function X' (code level): graph_impact / graph_neighbors on a 'py:function:...' node.\n"
44
+ "- 'What do we already know / what bit us before' (decisions and risky actions): check_learnings(q).\n"
45
+ "- Cross-project discovery by meaning: search(q). Body of ONE known project: get_project(slug) — do not layer search on top of get_project.\n"
46
+ "Before answering an orchestration or planning task, confirm you actually called the relevant "
47
+ "tool (session_brief / project_impact / graph_impact) AND that your answer addresses the task "
48
+ "as asked — do not reply from raw files or pivot to an unrelated skill.\n"
49
+ "When you state a number from the knowledge graph (a count, in-degree, how many dependents), "
50
+ "quote it from the tool result's `summary` block and cite it inline — e.g. \"148 edges from 11 "
51
+ "sources [graph_neighbors summary]\". Do NOT re-count a returned list by hand, and do NOT state a "
52
+ "count that no tool result supports.\n"
53
+ )
54
+
55
+ mcp = FastMCP("marvis", instructions=_INSTRUCTIONS)
38
56
 
39
57
  register_all(mcp)
40
58
 
59
+ # mcp-ergonomics (tiering): mark the cold-start core always-loaded so clients with
60
+ # MCP tool-search (e.g. Claude Code — the agent that drives the brain) keep these in
61
+ # context and defer the other ~60 tools on demand. A 70-tool surface is well over the
62
+ # ~20-30 threshold where tool-selection accuracy degrades. Additive: clients without
63
+ # tool-search still see every tool (no regression). Best-effort — a FastMCP registry
64
+ # shape change degrades to a no-op, never a boot failure.
65
+ _CORE_TOOLS = frozenset(
66
+ {
67
+ "session_brief",
68
+ "search",
69
+ "check_learnings",
70
+ "list_tasks",
71
+ "get_task",
72
+ "create_task",
73
+ "update_task",
74
+ "get_project",
75
+ "graph_impact",
76
+ "graph_neighbors",
77
+ "project_impact",
78
+ }
79
+ )
80
+ try:
81
+ for _name, _tool in mcp._tool_manager._tools.items():
82
+ if _name in _CORE_TOOLS:
83
+ _m = dict(_tool.meta or {})
84
+ _m["anthropic/alwaysLoad"] = True
85
+ _tool.meta = _m
86
+ except Exception: # pragma: no cover - FastMCP internal-shape guard
87
+ pass
88
+
41
89
 
42
90
  def main() -> None:
43
91
  """Run the MCP server over stdio (the OSS runtime entrypoint).
@@ -123,10 +123,11 @@ def register(mcp) -> None:
123
123
  rank: NeighborRank = "none",
124
124
  as_of: Annotated[str, Field(pattern=_AS_OF_PATTERN, max_length=32)] | None = None,
125
125
  ) -> dict[str, Any]:
126
- """[Power-user] Surgical 1-hop neighbour query for a KG node (calls/imports/defines/mentions/...) per context completo su un nodo usa get_task/get_project/get_handoff/get_learning(deep=true). Usa questo tool solo quando hai bisogno di ispezionare il vicinato topologico diretto senza il bundle completo.
127
- QUANDO USARLO: refactor impact assessment su una singola function; verificare se un nodo ha caller inattesi; time-travel as_of su commit specifico; rank=suspect_write per bug write-through-read.
128
- QUANDO NON USARLO: NOT per context di un task/handoff/learning -> usa get_*(deep=true). NOT per BFS transitivo -> usa graph_impact.
129
- RESTITUISCE: list of {node_id, relation, direction, rank_score?} cap 200."""
126
+ """1-hop: chi tocca / dipende direttamente da un nodo. Funziona su codice ('py:function:...') E su progetti ('project:artifact:<slug>').
127
+ CHI DIPENDE DA X (in UNA call): graph_neighbors(node_id, direction='incoming', rank='degree') i dipendenti diretti ordinati per grado + un blocco `summary` GIA' aggregato. E' il tool ovvio per 'chi cita / dipende da X' — NON fare N micro-query (project_impact e' il primo passo, non N).
128
+ ORCHESTRAZIONE: per i vicini diretti di un PROGETTO passa node_id='project:artifact:<slug>' con edge_types=['depends_on']. Codice: caller/callee 1-hop di una function.
129
+ QUANDO USARLO: vicinato diretto; caller inattesi; time-travel as_of; rank=suspect_write per bug write-through-read. Per il blast radius transitivo usa graph_impact / project_impact.
130
+ RESTITUISCE: {neighbors:[{node_id, relation, direction, rank_score?}], summary:{total, distinct_nodes, by_relation, by_direction} (CITA questi numeri, non ricontare la lista), freshness} cap 200."""
130
131
  try:
131
132
  async with acquire_db() as db:
132
133
  # Node proxy hardcodes limit=200 (the surface exposes no limit param).
@@ -152,7 +153,7 @@ def register(mcp) -> None:
152
153
  limit: Annotated[int, Field(ge=1, le=100)] = 20,
153
154
  type_filter: HotspotTypeFilter = "file",
154
155
  ) -> dict[str, Any]:
155
- """[Power-user] DORA-style churn ranking: files/functions sorted by touch_count 7d/30d with bus-factor warning — per context completo su un progetto usa get_project(deep=true). Usa questo tool per analisi architetturale di rischio o pianificazione refactor.
156
+ """DORA-style churn ranking: files/functions sorted by touch_count 7d/30d with bus-factor warning — per context completo su un progetto usa get_project(deep=true). Usa questo tool per analisi architetturale di rischio o pianificazione refactor.
156
157
  QUANDO USARLO: identificare moduli ad alto rischio prima di una release; trovare ownership gaps (bus_factor=1); pianificare tech debt.
157
158
  QUANDO NON USARLO: NOT per context di un progetto specifico -> usa get_project(deep=true). NOT per BFS da un nodo -> usa graph_impact.
158
159
  RESTITUISCE: list of {node_id, touch_count_7d, touch_count_30d, authors[], bus_factor} top N."""
@@ -178,10 +179,10 @@ def register(mcp) -> None:
178
179
  edge_types: list[EdgeType] | None = None,
179
180
  project: Annotated[str, Field(max_length=50, pattern=_PROJECT_PATTERN)] | None = None,
180
181
  ) -> dict[str, Any]:
181
- """[Power-user] BFS impact analysis: 'cosa si rompe se cambio X?' con ranker su direct callers + transitive list per context completo usa get_task(deep=true). Usa questo tool per delete/rename risk assessment o pre-refactor sweep.
182
- QUANDO USARLO: prima di eliminare/rinominare una function critica; misurare blast radius di una migration; dependency cascade analysis.
183
- QUANDO NON USARLO: NOT per context standard -> usa get_*(deep=true). NOT per 1-hop only -> usa graph_neighbors.
184
- RESTITUISCE: {direct_callers[], transitive_list[], rank_score} depth configurabile."""
182
+ """Impact / blast radius: 'cosa si rompe o quali progetti si bloccano se cambio / pauso / chiudo X?'. BFS sui rami transitivi + ranker sui diretti.
183
+ ORCHESTRAZIONE DI PORTAFOGLIO: per sapere quali PROGETTI si bloccano se pausi/chiudi un progetto, passa node_id='project:artifact:<slug>' con edge_types=['depends_on','mentions','refers_to'] oppure usa il tool dedicato project_impact(slug). Livello-codice: per 'cosa si rompe se cambio questa function' passa un node 'py:function:...'.
184
+ QUANDO USARLO: prima di pausare/chiudere/de-prioritizzare un progetto (blast radius cross-project); prima di eliminare/rinominare una function critica; dependency cascade analysis; sequenziare lavoro (cosa sblocca cosa).
185
+ RESTITUISCE: {direct (callers/dependents)[], transitive_list[], rank_score, freshness (indexed_sha vs HEAD)} depth configurabile."""
185
186
  try:
186
187
  async with acquire_db() as db:
187
188
  result = await graph_uc.graph_impact(
@@ -197,15 +198,38 @@ def register(mcp) -> None:
197
198
  except ServiceError as e:
198
199
  raise_mcp_error(e)
199
200
 
201
+ @mcp.tool()
202
+ async def project_impact(
203
+ slug: Annotated[str, Field(max_length=50, pattern=_PROJECT_PATTERN)],
204
+ depth: Annotated[int, Field(ge=1, le=5)] = 2,
205
+ ) -> dict[str, Any]:
206
+ """Portfolio blast radius: 'se pauso / chiudo / de-prioritizzo questo PROGETTO, quali altri progetti si bloccano?'. Il tool di prima classe per l'orchestrazione cross-progetto — distinto dal grafo-codice.
207
+ Risolve 'project:artifact:<slug>' e fa l'impact BFS sui soli edge progetto->progetto (depends_on / mentions / refers_to). La response porta il segnale freshness (indexed_sha vs HEAD) per non fidarsi di un indice stantio.
208
+ QUANDO USARLO: prima di pausare/chiudere/de-prioritizzare un progetto; sequenziare un portafoglio (cosa sblocca cosa); capire le dipendenze cross-progetto di una decisione.
209
+ RESTITUISCE: {direct_dependents[], transitive_list[], rank_score, freshness}. Col flag MARVIS_KG_CLAIMS anche claims[]: quanti progetti dipendono DAVVERO da questo (kind=dependents_depends_on) vs quanti lo nominano soltanto (kind=mentioned_by), gia' contati server-side con provenienza e freschezza — riporta quei numeri, non ri-contare le liste."""
210
+ try:
211
+ async with acquire_db() as db:
212
+ result = await graph_uc.graph_impact(
213
+ LOCAL_CTX,
214
+ db,
215
+ node_id=f"project:artifact:{slug}",
216
+ depth=depth,
217
+ limit=100,
218
+ edge_types=["depends_on", "mentions", "refers_to"],
219
+ project=None,
220
+ )
221
+ return dump(result)
222
+ except ServiceError as e:
223
+ raise_mcp_error(e)
224
+
200
225
  @mcp.tool()
201
226
  async def graph_context(
202
227
  node_id: Annotated[str, Field(pattern=_NODE_ID_PATTERN, max_length=256)],
203
228
  per_category_limit: Annotated[int, Field(ge=1, le=20)] = 5,
204
229
  project: Annotated[str, Field(max_length=50, pattern=_PROJECT_PATTERN)] | None = None,
205
230
  ) -> dict[str, Any]:
206
- """[Power-user] Rationale chain: function→commit→PR→task→handoff→learning in 1 call — per context su un singolo artefatto usa get_task/get_handoff/get_learning(deep=true). Usa questo tool quando hai un node_id e vuoi la storia completa del PERCHE'.
207
- QUANDO USARLO: archeologia di codice legacy ('perche esiste questa function?'); audit trail pre-refactor; linkare codice a decision record.
208
- QUANDO NON USARLO: NOT per workflow standard su task/handoff -> usa get_*(deep=true). NOT per vicinato topologico -> usa graph_neighbors.
231
+ """Rationale chain di un nodo: function/progetto commit PR task handoff learning in 1 call. Il PERCHE' dietro qualcosa.
232
+ QUANDO USARLO: perche' esiste / da dove viene una function o una decisione di progetto; audit trail; linkare codice o progetto a un decision record.
209
233
  RESTITUISCE: chain {commits[], PR?, task?, handoffs[], learnings[]} per_category_limit configurabile."""
210
234
  try:
211
235
  async with acquire_db() as db:
@@ -225,7 +249,7 @@ def register(mcp) -> None:
225
249
  scope: Annotated[str, Field(max_length=256)],
226
250
  limit: Annotated[int, Field(ge=1, le=100)] = 20,
227
251
  ) -> dict[str, Any]:
228
- """[Power-user] Learnings scoped a un modulo/path specifico via KG — per learnings generici usa check_learnings. Usa questo tool per learnings chirurgici su un file/modulo specifico prima di toccare codice in quella area.
252
+ """Learnings scoped a un modulo/path specifico via KG — per learnings generici usa check_learnings. Usa questo tool per learnings chirurgici su un file/modulo specifico prima di toccare codice in quella area.
229
253
  QUANDO USARLO: 'quali learnings esistono per api.db?' prima di toccare il DB module; scoping pre-deployment di un servizio specifico.
230
254
  QUANDO NON USARLO: NOT per ricerca semantica generica pre-azione -> usa check_learnings. NOT per context di un nodo -> usa graph_context.
231
255
  RESTITUISCE: list of {learning_id, title, prevention, severity, scope_match_score}."""
@@ -240,7 +264,7 @@ def register(mcp) -> None:
240
264
 
241
265
  @mcp.tool()
242
266
  async def graph_capabilities() -> dict[str, Any]:
243
- """[Power-user] KG schema metadata per agent discovery (edge_types + node_kinds + prefixes + versions).
267
+ """KG schema metadata per agent discovery (edge_types + node_kinds + prefixes + versions).
244
268
  QUANDO USARLO: prima di costruire query graph_* o validare node_id pattern; cold-start agent discovery.
245
269
  QUANDO NON USARLO: per query topologiche -> usa graph_neighbors/impact/context.
246
270
  RESTITUISCE: {edge_types[], node_kinds[], node_prefixes[], schema_version}.
@@ -47,10 +47,10 @@ def register(mcp) -> None:
47
47
  q: Annotated[str, Field(min_length=1, max_length=500)],
48
48
  module: str | None = None,
49
49
  ) -> dict[str, Any]:
50
- """Search learnings DB (past post-mortems + prevention rules) for a risky action.
50
+ """Cosa sappiamo gia' / cosa ci ha morso: cerca nei learnings (post-mortem + regole di prevenzione) prima di una decisione o di un'azione.
51
51
 
52
- QUANDO USARLO: PRIMA di qualunque azione production-affecting (deploy, migration, auth change, push to main, dependency upgrade) Quality Gate 9.4. BOUNDARY: create_learning vs check_learnings = create scrive nuovo; check cerca rilevante PRE-azione rischiosa. BOUNDARY: check_learnings vs list_learnings = check = semantic match su situazione; list = enumerazione filtrata.
53
- QUANDO NON USARLO: NOT quando hai gia' un file/module path e vuoi learnings scoped -> usa graph_pattern. NOT per scrivere un nuovo learning -> usa create_learning.
52
+ QUANDO USARLO: prima di qualunque azione production-affecting (deploy, migration, auth change, push, dependency upgrade); E prima di una DECISIONE o di un piano (per non ripetere errori noti e riusare cio' che ha funzionato). Non e' solo un gate pre-deploy: e' la memoria istituzionale a cui attingere quando ragioni. BOUNDARY: create_learning scrive nuovo; check_learnings = semantic match sulla situazione; list_learnings = enumerazione filtrata.
53
+ QUANDO NON USARLO: se hai gia' un file/module path e vuoi learnings scoped -> graph_pattern. Per scrivere un nuovo learning -> create_learning.
54
54
  RESTITUISCE: list of {id, title, prevention, severity, module} ranked per rilevanza."""
55
55
  try:
56
56
  async with acquire_db() as db:
@@ -13,7 +13,38 @@ from __future__ import annotations
13
13
  from datetime import datetime
14
14
  from typing import Literal
15
15
 
16
- from pydantic import BaseModel, ConfigDict, Field
16
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
17
+
18
+ # ---------------------------------------------------------------------------
19
+ # answer-ready claims (behind MARVIS_KG_CLAIMS) — server-computed, relation-typed
20
+ # ---------------------------------------------------------------------------
21
+
22
+ class KGClaim(BaseModel):
23
+ """A server-computed claim about a KG node: the value is counted by the DB,
24
+ not by the agent. The agent reports it (and the relation) instead of
25
+ re-counting raw edges — this is the faithfulness fix.
26
+
27
+ `kind` names the relation explicitly (e.g. `dependents_depends_on` = real
28
+ dependency, `mentioned_by` = associative, NOT a dependency). `sources` is a
29
+ capped sample of the provenance; `sources_total` is the full count.
30
+ """
31
+ model_config = ConfigDict(extra="forbid")
32
+
33
+ kind: str = Field(..., description="dependents_depends_on | dependents_imports | dependents_calls | mentioned_by")
34
+ subject: str = Field(..., description="node_id the claim is about")
35
+ value: int = Field(..., ge=0, description="server-computed count (the number to report)")
36
+ sources: list[str] = Field(default_factory=list, description="capped sample of source node ids (provenance)")
37
+ sources_total: int = Field(..., ge=0, description="full provenance count before capping")
38
+ as_of: str | None = Field(None, description="last observation (last_seen_at) of the subject")
39
+ verified: str | None = Field(None, description="last Brain re-confirmation (last_verified_at), or null")
40
+ needs_review: bool = Field(False, description="subject is stale per the read-time freshness budget")
41
+
42
+ @model_validator(mode="after")
43
+ def _sources_within_total(self) -> "KGClaim":
44
+ if self.sources_total < len(self.sources):
45
+ raise ValueError("sources_total must be >= len(sources)")
46
+ return self
47
+
17
48
 
18
49
  # ---------------------------------------------------------------------------
19
50
  # Shared type alias (validated at model-field level via annotation)
@@ -47,6 +78,36 @@ class PinOut(BaseModel):
47
78
  is_stale: bool = False # True if node was soft-deleted after pinning (belt-and-braces)
48
79
 
49
80
 
81
+ # ---------------------------------------------------------------------------
82
+ # Fase D — KG trust write-path request bodies (behind MARVIS_TEMPORAL_MEMORY).
83
+ # The apply actions an agent performs after Triage approves a Brain proposal.
84
+ # ---------------------------------------------------------------------------
85
+
86
+ class VerifyNodeIn(BaseModel):
87
+ """Request body for POST /graph/nodes/verify — stamp last_verified_at = now."""
88
+ node_id: str = Field(
89
+ ...,
90
+ min_length=6,
91
+ max_length=256,
92
+ pattern=r"^[a-z]+:[a-z]+:.+$",
93
+ description="Node ID to mark re-verified (REINFORCE apply)",
94
+ )
95
+
96
+
97
+ class SupersedeEdgeIn(BaseModel):
98
+ """Request body for POST /graph/edges/supersede — soft-invalidate an edge."""
99
+ source_id: str = Field(..., min_length=6, max_length=256, pattern=r"^[a-z]+:[a-z]+:.+$")
100
+ target_id: str = Field(..., min_length=6, max_length=256, pattern=r"^[a-z]+:[a-z]+:.+$")
101
+ relation: str = Field(
102
+ ..., min_length=2, max_length=32,
103
+ description="Edge relation of the triple to supersede (e.g. depends_on)",
104
+ )
105
+ superseded_by: str | None = Field(
106
+ None, max_length=256,
107
+ description="Optional audit pointer to the replacing edge",
108
+ )
109
+
110
+
50
111
  # ---------------------------------------------------------------------------
51
112
  # Landing bundle
52
113
  # ---------------------------------------------------------------------------
@@ -26,6 +26,14 @@ class SearchHit(BaseModel):
26
26
  edge_path: list[str] | None = None
27
27
  edge_path_summary: str | None = None
28
28
  rrf_score: float | None = None
29
+ # Memory-freshness v2a Phase 2 (A-span, MARVIS_SEARCH_SPANS): the winning
30
+ # chunk's text expanded to line boundaries ±12 lines, so the agent answers
31
+ # FROM the result without a follow-up Read. None when the flag is off, the
32
+ # hit is row-backed (task/learning/inbox), or the source file is gone.
33
+ span_text: str | None = None
34
+ span_path: str | None = None
35
+ span_line_start: int | None = None
36
+ span_line_end: int | None = None
29
37
 
30
38
 
31
39
  class SearchResponse(BaseModel):
@@ -79,6 +79,8 @@ from core.api.models.graph_ux import (
79
79
  PinIn,
80
80
  PinOut,
81
81
  ResolveOut,
82
+ SupersedeEdgeIn,
83
+ VerifyNodeIn,
82
84
  )
83
85
  from core.api.models.graph_cosmo import GraphCosmoOut
84
86
  from core.api.rate_limit import limiter
@@ -701,6 +703,54 @@ async def delete_graph_pin(
701
703
  return result
702
704
 
703
705
 
706
+ # --- KG trust write-path (Fase D, behind MARVIS_TEMPORAL_MEMORY) ---
707
+
708
+ @router.post("/nodes/verify", response_model=dict, summary="Mark a KG node re-verified")
709
+ @limiter.limit("60/minute")
710
+ async def mark_node_verified(
711
+ body: VerifyNodeIn,
712
+ request: Request,
713
+ user: UserInfo = Depends(get_current_user_or_agent),
714
+ db: aiosqlite.Connection = Depends(get_write_db),
715
+ ) -> dict:
716
+ """Stamp graph_nodes.last_verified_at = now (REINFORCE apply).
717
+
718
+ The action an agent performs after Triage approves a Brain recency proposal.
719
+ Inert (422) when MARVIS_TEMPORAL_MEMORY is off. 404 if the node is missing.
720
+ """
721
+ ctx = CallerContext.from_user_info(user, is_human_session=False)
722
+ try:
723
+ return await uc.mark_node_verified(ctx, db, node_id=body.node_id)
724
+ except ServiceError as e:
725
+ raise to_http_legacy(e)
726
+
727
+
728
+ @router.post("/edges/supersede", response_model=dict, summary="Soft-invalidate a KG edge")
729
+ @limiter.limit("60/minute")
730
+ async def mark_edge_superseded(
731
+ body: SupersedeEdgeIn,
732
+ request: Request,
733
+ user: UserInfo = Depends(get_current_user_or_agent),
734
+ db: aiosqlite.Connection = Depends(get_write_db),
735
+ ) -> dict:
736
+ """Set graph_edges.valid_until = now (+ optional superseded_by) on a triple.
737
+
738
+ SUPERSEDE / CONTRADICTION apply. Soft, never deletes. Inert (422) when the
739
+ flag is off. 404 if the triple is absent.
740
+ """
741
+ ctx = CallerContext.from_user_info(user, is_human_session=False)
742
+ try:
743
+ return await uc.mark_edge_superseded(
744
+ ctx, db,
745
+ source_id=body.source_id,
746
+ target_id=body.target_id,
747
+ relation=body.relation,
748
+ superseded_by=body.superseded_by,
749
+ )
750
+ except ServiceError as e:
751
+ raise to_http_legacy(e)
752
+
753
+
704
754
  # --- Resolve file path → node_id ---
705
755
 
706
756
  @router.get("/resolve", response_model=ResolveOut, summary="Resolve file path to KG node")