topos-node 1.3.0__tar.gz → 1.3.2__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 (593) hide show
  1. {topos_node-1.3.0 → topos_node-1.3.2}/MANIFEST.in +2 -0
  2. {topos_node-1.3.0/topos_node.egg-info → topos_node-1.3.2}/PKG-INFO +9 -1
  3. {topos_node-1.3.0 → topos_node-1.3.2}/pyproject.toml +13 -1
  4. {topos_node-1.3.0 → topos_node-1.3.2}/topos/__version__.py +2 -2
  5. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/llm.py +47 -0
  6. topos_node-1.3.2/topos/api/shell.py +91 -0
  7. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/signal.py +195 -2
  8. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/uma_data.py +4 -0
  9. {topos_node-1.3.0 → topos_node-1.3.2}/topos/app.py +41 -13
  10. topos_node-1.3.2/topos/cli/assets/topos_blk_rounded.png +0 -0
  11. topos_node-1.3.2/topos/cli/assets/topos_white.png +0 -0
  12. {topos_node-1.3.0 → topos_node-1.3.2}/topos/cli/commands.py +90 -2
  13. topos_node-1.3.2/topos/cli/tray.py +392 -0
  14. {topos_node-1.3.0 → topos_node-1.3.2}/topos/control_plane_client.py +4 -0
  15. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/__init__.py +2 -0
  16. topos_node-1.3.2/topos/core/handlers/complexity.py +145 -0
  17. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/messages.py +3 -0
  18. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/signal_features.py +203 -1
  19. topos_node-1.3.2/topos/core/handlers/timeline_daily.py +40 -0
  20. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/uma.py +15 -0
  21. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/logging.py +47 -7
  22. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/engine.py +93 -0
  23. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/usage_observation.py +6 -1
  24. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/catalog.py +13 -0
  25. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/__init__.py +2 -0
  26. topos_node-1.3.2/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +83 -0
  27. topos_node-1.3.2/topos/features/complexity/__init__.py +10 -0
  28. topos_node-1.3.2/topos/features/complexity/canonical.py +301 -0
  29. topos_node-1.3.2/topos/features/complexity/engine.py +287 -0
  30. topos_node-1.3.2/topos/features/complexity/entropy.py +100 -0
  31. topos_node-1.3.2/topos/features/complexity/focus.py +507 -0
  32. topos_node-1.3.2/topos/features/complexity/graph_metrics.py +177 -0
  33. topos_node-1.3.2/topos/features/complexity/influence.py +664 -0
  34. topos_node-1.3.2/topos/features/complexity/projection.py +567 -0
  35. topos_node-1.3.2/topos/features/complexity/snapshots.py +77 -0
  36. topos_node-1.3.2/topos/features/complexity/store.py +136 -0
  37. topos_node-1.3.2/topos/features/complexity/topic_merge.py +437 -0
  38. topos_node-1.3.2/topos/features/complexity/topics.py +154 -0
  39. topos_node-1.3.2/topos/features/complexity/topics_daily.py +106 -0
  40. topos_node-1.3.2/topos/features/complexity/volatility.py +140 -0
  41. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/edges.py +18 -0
  42. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/reads.py +73 -5
  43. topos_node-1.3.2/topos/features/lifecycle/blackhole.py +533 -0
  44. topos_node-1.3.2/topos/features/lifecycle/blackhole_guard.py +385 -0
  45. topos_node-1.3.2/topos/features/lifecycle/blackhole_llm.py +169 -0
  46. topos_node-1.3.2/topos/features/lifecycle/blackhole_rebuild.py +210 -0
  47. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/conversation_context.py +3 -1
  48. topos_node-1.3.2/topos/features/timeline_rollup.py +121 -0
  49. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/triage/badges.py +7 -3
  50. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/triage/dashboard.py +12 -5
  51. {topos_node-1.3.0 → topos_node-1.3.2}/topos/protocol/handled_message_types.json +11 -0
  52. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/game_layer.py +14 -12
  53. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/pipeline.py +3 -1
  54. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/retrieval.py +275 -24
  55. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/scope_registry.json +34 -8
  56. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/__init__.py +16 -0
  57. topos_node-1.3.2/topos/storage/db/migrations/complexity_v1.py +48 -0
  58. topos_node-1.3.2/topos/storage/db/migrations/entity_blackhole_v1.py +91 -0
  59. {topos_node-1.3.0 → topos_node-1.3.2}/topos/uma_contact_enrichment.py +22 -2
  60. {topos_node-1.3.0 → topos_node-1.3.2}/topos/upgrades/manifests.json +30 -4
  61. {topos_node-1.3.0 → topos_node-1.3.2}/topos/upgrades/runner.py +206 -28
  62. {topos_node-1.3.0 → topos_node-1.3.2/topos_node.egg-info}/PKG-INFO +9 -1
  63. {topos_node-1.3.0 → topos_node-1.3.2}/topos_node.egg-info/SOURCES.txt +28 -0
  64. {topos_node-1.3.0 → topos_node-1.3.2}/topos_node.egg-info/requires.txt +8 -0
  65. {topos_node-1.3.0 → topos_node-1.3.2}/LICENSE +0 -0
  66. {topos_node-1.3.0 → topos_node-1.3.2}/README.md +0 -0
  67. {topos_node-1.3.0 → topos_node-1.3.2}/setup.cfg +0 -0
  68. {topos_node-1.3.0 → topos_node-1.3.2}/shared/__init__.py +0 -0
  69. {topos_node-1.3.0 → topos_node-1.3.2}/shared/filtering.py +0 -0
  70. {topos_node-1.3.0 → topos_node-1.3.2}/shared/schema_registry.py +0 -0
  71. {topos_node-1.3.0 → topos_node-1.3.2}/tests/test_extensions.py +0 -0
  72. {topos_node-1.3.0 → topos_node-1.3.2}/tests/test_llm_integrations_storage.py +0 -0
  73. {topos_node-1.3.0 → topos_node-1.3.2}/tests/test_protocol_handled_types.py +0 -0
  74. {topos_node-1.3.0 → topos_node-1.3.2}/topos/__init__.py +0 -0
  75. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/__init__.py +0 -0
  76. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/duckdb_adapter.py +0 -0
  77. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/messenger_communities.py +0 -0
  78. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/messenger_graph.py +0 -0
  79. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/messenger_labels.py +0 -0
  80. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/profiles.py +0 -0
  81. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/query_engine.py +0 -0
  82. {topos_node-1.3.0 → topos_node-1.3.2}/topos/analytics/raw_queries.py +0 -0
  83. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/__init__.py +0 -0
  84. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/analytics.py +0 -0
  85. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/app_registry.py +0 -0
  86. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/backup.py +0 -0
  87. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/compute_remote.py +0 -0
  88. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/conversation_context.py +0 -0
  89. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/data_commit.py +0 -0
  90. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/data_explorer_table_prefs.py +0 -0
  91. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/database_explorer.py +0 -0
  92. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/db.py +0 -0
  93. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/device.py +0 -0
  94. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/engine_run.py +0 -0
  95. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/enrichment.py +0 -0
  96. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/enrichment_lab.py +0 -0
  97. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/facts_llm_config.py +0 -0
  98. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/filter_lab.py +0 -0
  99. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/health.py +0 -0
  100. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/home_chat.py +0 -0
  101. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/ingestion_api.py +0 -0
  102. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/ingestion_compat.py +0 -0
  103. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/ingestion_sources.py +0 -0
  104. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/intelligence_lifecycle.py +0 -0
  105. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/local_mcp.py +0 -0
  106. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/messenger_analytics.py +0 -0
  107. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/privacy_disclose.py +0 -0
  108. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/query_api.py +0 -0
  109. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/runtime_bootstrap.py +0 -0
  110. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/sanitization_ollama_config.py +0 -0
  111. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/signal_extraction_config.py +0 -0
  112. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/source_install.py +0 -0
  113. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/source_scrub.py +0 -0
  114. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/sources.py +0 -0
  115. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/sources_overview.py +0 -0
  116. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/sync.py +0 -0
  117. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/tool_index.py +0 -0
  118. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/ui_config.py +0 -0
  119. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/upgrades.py +0 -0
  120. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/usage.py +0 -0
  121. {topos_node-1.3.0 → topos_node-1.3.2}/topos/api/user_identity.py +0 -0
  122. {topos_node-1.3.0 → topos_node-1.3.2}/topos/auth.py +0 -0
  123. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/__init__.py +0 -0
  124. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/__init__.py +0 -0
  125. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/base.py +0 -0
  126. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  127. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  128. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  129. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  130. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  131. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  132. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  133. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  134. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/models.py +0 -0
  135. {topos_node-1.3.0 → topos_node-1.3.2}/topos/canonicalization/resolver.py +0 -0
  136. {topos_node-1.3.0 → topos_node-1.3.2}/topos/cli/__init__.py +0 -0
  137. {topos_node-1.3.0 → topos_node-1.3.2}/topos/cli/__main__.py +0 -0
  138. {topos_node-1.3.0 → topos_node-1.3.2}/topos/config/__init__.py +0 -0
  139. {topos_node-1.3.0 → topos_node-1.3.2}/topos/config/conversation_context_llm.py +0 -0
  140. {topos_node-1.3.0 → topos_node-1.3.2}/topos/config/facts_llm.py +0 -0
  141. {topos_node-1.3.0 → topos_node-1.3.2}/topos/config/sanitization_ollama.py +0 -0
  142. {topos_node-1.3.0 → topos_node-1.3.2}/topos/config/settings.py +0 -0
  143. {topos_node-1.3.0 → topos_node-1.3.2}/topos/config/signal_extraction.py +0 -0
  144. {topos_node-1.3.0 → topos_node-1.3.2}/topos/config/uvicorn_logging.json +0 -0
  145. {topos_node-1.3.0 → topos_node-1.3.2}/topos/contacts/__init__.py +0 -0
  146. {topos_node-1.3.0 → topos_node-1.3.2}/topos/contacts/identity.py +0 -0
  147. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/__init__.py +0 -0
  148. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/api_models.py +0 -0
  149. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/connection_resilience.py +0 -0
  150. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/device_helpers.py +0 -0
  151. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/errors.py +0 -0
  152. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/events.py +0 -0
  153. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/common.py +0 -0
  154. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/config.py +0 -0
  155. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/contacts_import.py +0 -0
  156. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/database_explorer.py +0 -0
  157. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/device.py +0 -0
  158. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/enrichment.py +0 -0
  159. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/enrichment_lab.py +0 -0
  160. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/filter_lab.py +0 -0
  161. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/home_chat.py +0 -0
  162. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/ingest.py +0 -0
  163. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/messenger_analytics.py +0 -0
  164. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/query.py +0 -0
  165. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/registry.py +0 -0
  166. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/routines.py +0 -0
  167. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/sources.py +0 -0
  168. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/handlers/tool_index.py +0 -0
  169. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/metrics.py +0 -0
  170. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/routine_access.py +0 -0
  171. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/startup_banner.py +0 -0
  172. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/state.py +0 -0
  173. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/table_layers.py +0 -0
  174. {topos_node-1.3.0 → topos_node-1.3.2}/topos/core/types.py +0 -0
  175. {topos_node-1.3.0 → topos_node-1.3.2}/topos/data_explorer_row_delete.py +0 -0
  176. {topos_node-1.3.0 → topos_node-1.3.2}/topos/data_explorer_table_prefs.py +0 -0
  177. {topos_node-1.3.0 → topos_node-1.3.2}/topos/data_explorer_tables.py +0 -0
  178. {topos_node-1.3.0 → topos_node-1.3.2}/topos/disclosure/__init__.py +0 -0
  179. {topos_node-1.3.0 → topos_node-1.3.2}/topos/disclosure/canonical_writer.py +0 -0
  180. {topos_node-1.3.0 → topos_node-1.3.2}/topos/disclosure/content_policy.py +0 -0
  181. {topos_node-1.3.0 → topos_node-1.3.2}/topos/disclosure/field_registry.py +0 -0
  182. {topos_node-1.3.0 → topos_node-1.3.2}/topos/disclosure/privacy_layer.py +0 -0
  183. {topos_node-1.3.0 → topos_node-1.3.2}/topos/disclosure/tier.py +0 -0
  184. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/__init__.py +0 -0
  185. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/__init__.py +0 -0
  186. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/base.py +0 -0
  187. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/generative_prompts.py +0 -0
  188. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/generative_response.py +0 -0
  189. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/huggingface.py +0 -0
  190. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/ollama.py +0 -0
  191. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/openai.py +0 -0
  192. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/openai_compatible.py +0 -0
  193. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/redpill.py +0 -0
  194. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/backends/stub.py +0 -0
  195. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/client.py +0 -0
  196. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/intake.py +0 -0
  197. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/memory_utils.py +0 -0
  198. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/model_cache.py +0 -0
  199. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/pipeline_memory.py +0 -0
  200. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/queue_manager.py +0 -0
  201. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/registration.py +0 -0
  202. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/result_formatter.py +0 -0
  203. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/router.py +0 -0
  204. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/scoped_token.py +0 -0
  205. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/tasks.py +0 -0
  206. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/transport.py +0 -0
  207. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/usage_guard.py +0 -0
  208. {topos_node-1.3.0 → topos_node-1.3.2}/topos/engine/validator.py +0 -0
  209. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/__init__.py +0 -0
  210. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/derived_tables.py +0 -0
  211. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/job_writer.py +0 -0
  212. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/base.py +0 -0
  213. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  214. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  215. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  216. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  217. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  218. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  219. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  220. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  221. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  222. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  223. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  224. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  225. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  226. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  227. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  228. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  229. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  230. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  231. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  232. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/url_classification_core.py +0 -0
  233. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/url_classification_enrichment_job.py +0 -0
  234. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/canonical/url_classification_signal_job.py +0 -0
  235. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/raw/__init__.py +0 -0
  236. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  237. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/raw/language_job.py +0 -0
  238. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  239. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  240. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/model_overrides.py +0 -0
  241. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/models/__init__.py +0 -0
  242. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/models/manager.py +0 -0
  243. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/models/mvp_defaults.py +0 -0
  244. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/models/registry.py +0 -0
  245. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/models/versioning.py +0 -0
  246. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/orchestrator.py +0 -0
  247. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/processor.py +0 -0
  248. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/progress_bar.py +0 -0
  249. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/registry_contract.py +0 -0
  250. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/signal_derivation_config.json +0 -0
  251. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/source_overrides.py +0 -0
  252. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment/website_classifier.py +0 -0
  253. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment_lab/__init__.py +0 -0
  254. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment_lab/bundles.py +0 -0
  255. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment_lab/model_resolve.py +0 -0
  256. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment_lab/schema.py +0 -0
  257. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment_lab/service.py +0 -0
  258. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment_lab/store.py +0 -0
  259. {topos_node-1.3.0 → topos_node-1.3.2}/topos/enrichment_lab/worker.py +0 -0
  260. {topos_node-1.3.0 → topos_node-1.3.2}/topos/evals/__init__.py +0 -0
  261. {topos_node-1.3.0 → topos_node-1.3.2}/topos/evals/enrichment_eval.py +0 -0
  262. {topos_node-1.3.0 → topos_node-1.3.2}/topos/extensions.py +0 -0
  263. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/__init__.py +0 -0
  264. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/consolidation.py +0 -0
  265. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/declared_mappings.py +0 -0
  266. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/dossier.py +0 -0
  267. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/fact_materializer.py +0 -0
  268. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/graph_enrichers.py +0 -0
  269. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/graph_refresh.py +0 -0
  270. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/graph_search.py +0 -0
  271. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/linking.py +0 -0
  272. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/maintenance.py +0 -0
  273. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/entities/resolver.py +0 -0
  274. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/facts/__init__.py +0 -0
  275. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/facts/extract.py +0 -0
  276. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/facts/llm_extract.py +0 -0
  277. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/facts/reads.py +0 -0
  278. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/facts/store.py +0 -0
  279. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/facts/verdicts.py +0 -0
  280. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/fit/evaluator.py +0 -0
  281. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/fit/opportunity_types.json +0 -0
  282. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/lifecycle/__init__.py +0 -0
  283. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/lifecycle/derived_scrub.py +0 -0
  284. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/lifecycle/exclusions.py +0 -0
  285. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/lifecycle/gc.py +0 -0
  286. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/provenance/__init__.py +0 -0
  287. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/provenance/posture.py +0 -0
  288. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/provenance/roles.py +0 -0
  289. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/__init__.py +0 -0
  290. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/brief_canonical_loader.py +0 -0
  291. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/brief_ontology.py +0 -0
  292. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/brief_renderer.py +0 -0
  293. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/brief_schemas.py +0 -0
  294. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/chunking.py +0 -0
  295. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/cluster_labels.py +0 -0
  296. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/data_health.py +0 -0
  297. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  298. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/definitions/intentions.json +0 -0
  299. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/definitions/profile.json +0 -0
  300. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/definitions/relationships.json +0 -0
  301. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  302. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/definitions/time.json +0 -0
  303. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/definitions/work.json +0 -0
  304. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/dimension_briefs.py +0 -0
  305. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/dimension_definition_loader.py +0 -0
  306. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/dimension_profiles.py +0 -0
  307. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/dimension_registry.py +0 -0
  308. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/embed_context.py +0 -0
  309. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/extraction/artifact_router.py +0 -0
  310. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/extraction/artifact_store.py +0 -0
  311. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/extraction/rule_extractors.py +0 -0
  312. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/graph_sanitize.py +0 -0
  313. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/hybrid_search.py +0 -0
  314. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/incremental_clustering.py +0 -0
  315. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/model_recommendations.py +0 -0
  316. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/query_embed_cache.py +0 -0
  317. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/schemas.py +0 -0
  318. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/service.py +0 -0
  319. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/signal_object_store.py +0 -0
  320. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/source_hydration.py +0 -0
  321. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/structured_signal.py +0 -0
  322. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/tool_index.py +0 -0
  323. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/topic_clustering.py +0 -0
  324. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/typed_stores/aggregates.py +0 -0
  325. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/typed_stores/commitments.py +0 -0
  326. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/typed_stores/rhythm.py +0 -0
  327. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  328. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/vector_codec.py +0 -0
  329. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/vector_math.py +0 -0
  330. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/signal/vector_settings.py +0 -0
  331. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/stats/__init__.py +0 -0
  332. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/stats/definitions.py +0 -0
  333. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/stats/engine.py +0 -0
  334. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/stats/fold.py +0 -0
  335. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/stats/insights.py +0 -0
  336. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/timeline_projection.py +0 -0
  337. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/triage/__init__.py +0 -0
  338. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/triage/daily.py +0 -0
  339. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/triage/instruments.py +0 -0
  340. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/triage/intents.py +0 -0
  341. {topos_node-1.3.0 → topos_node-1.3.2}/topos/features/triage/readiness.py +0 -0
  342. {topos_node-1.3.0 → topos_node-1.3.2}/topos/filter_lab/__init__.py +0 -0
  343. {topos_node-1.3.0 → topos_node-1.3.2}/topos/filter_lab/bundles.py +0 -0
  344. {topos_node-1.3.0 → topos_node-1.3.2}/topos/filter_lab/schema.py +0 -0
  345. {topos_node-1.3.0 → topos_node-1.3.2}/topos/filter_lab/service.py +0 -0
  346. {topos_node-1.3.0 → topos_node-1.3.2}/topos/filter_lab/store.py +0 -0
  347. {topos_node-1.3.0 → topos_node-1.3.2}/topos/filter_lab/worker.py +0 -0
  348. {topos_node-1.3.0 → topos_node-1.3.2}/topos/home_chat/__init__.py +0 -0
  349. {topos_node-1.3.0 → topos_node-1.3.2}/topos/home_chat/schema.py +0 -0
  350. {topos_node-1.3.0 → topos_node-1.3.2}/topos/home_chat/store.py +0 -0
  351. {topos_node-1.3.0 → topos_node-1.3.2}/topos/hosted_pool_lease.py +0 -0
  352. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/__init__.py +0 -0
  353. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/canonical_pipeline.py +0 -0
  354. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/checkpoints/__init__.py +0 -0
  355. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  356. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  357. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/inbox_crypto.py +0 -0
  358. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/inbox_drain.py +0 -0
  359. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/ingest_helpers.py +0 -0
  360. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/jobs.py +0 -0
  361. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/journal_location_fanout.py +0 -0
  362. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/journal_time_log_normalize.py +0 -0
  363. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/local_sync.py +0 -0
  364. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/log_preview.py +0 -0
  365. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/manager.py +0 -0
  366. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parser.py +0 -0
  367. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/__init__.py +0 -0
  368. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/base.py +0 -0
  369. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/browser_parser.py +0 -0
  370. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/calendar_parser.py +0 -0
  371. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  372. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  373. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  374. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/documents_parser.py +0 -0
  375. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  376. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  377. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/grok_parser.py +0 -0
  378. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/messenger_parser.py +0 -0
  379. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  380. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/progress.py +0 -0
  381. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/reprocess.py +0 -0
  382. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/__init__.py +0 -0
  383. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/base.py +0 -0
  384. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/calendar.py +0 -0
  385. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/chatgpt.py +0 -0
  386. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/contact_importers.py +0 -0
  387. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/grok.py +0 -0
  388. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/imessage_reader.py +0 -0
  389. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/signal_export_parser.py +0 -0
  390. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/sources/signal_reader.py +0 -0
  391. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/state_machine.py +0 -0
  392. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/triggers/__init__.py +0 -0
  393. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/triggers/file_trigger.py +0 -0
  394. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  395. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  396. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/validation/__init__.py +0 -0
  397. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/validation/base.py +0 -0
  398. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/validation/schema_registry.py +0 -0
  399. {topos_node-1.3.0 → topos_node-1.3.2}/topos/ingestion/validation/schema_validator.py +0 -0
  400. {topos_node-1.3.0 → topos_node-1.3.2}/topos/lineage/__init__.py +0 -0
  401. {topos_node-1.3.0 → topos_node-1.3.2}/topos/lineage/provenance.py +0 -0
  402. {topos_node-1.3.0 → topos_node-1.3.2}/topos/lineage/tracker.py +0 -0
  403. {topos_node-1.3.0 → topos_node-1.3.2}/topos/llm_integrations_storage.py +0 -0
  404. {topos_node-1.3.0 → topos_node-1.3.2}/topos/mcp_stdio_proxy.py +0 -0
  405. {topos_node-1.3.0 → topos_node-1.3.2}/topos/observability/__init__.py +0 -0
  406. {topos_node-1.3.0 → topos_node-1.3.2}/topos/observability/alerts.py +0 -0
  407. {topos_node-1.3.0 → topos_node-1.3.2}/topos/observability/metrics.py +0 -0
  408. {topos_node-1.3.0 → topos_node-1.3.2}/topos/observability/tracing.py +0 -0
  409. {topos_node-1.3.0 → topos_node-1.3.2}/topos/openai_client.py +0 -0
  410. {topos_node-1.3.0 → topos_node-1.3.2}/topos/pipeline/__init__.py +0 -0
  411. {topos_node-1.3.0 → topos_node-1.3.2}/topos/pipeline/audit.py +0 -0
  412. {topos_node-1.3.0 → topos_node-1.3.2}/topos/pipeline/envelope.py +0 -0
  413. {topos_node-1.3.0 → topos_node-1.3.2}/topos/pipeline/job_runner.py +0 -0
  414. {topos_node-1.3.0 → topos_node-1.3.2}/topos/pipeline/job_store.py +0 -0
  415. {topos_node-1.3.0 → topos_node-1.3.2}/topos/pipeline/stages.py +0 -0
  416. {topos_node-1.3.0 → topos_node-1.3.2}/topos/pipeline/stub_enqueue.py +0 -0
  417. {topos_node-1.3.0 → topos_node-1.3.2}/topos/projections/__init__.py +0 -0
  418. {topos_node-1.3.0 → topos_node-1.3.2}/topos/projections/vector_index/__init__.py +0 -0
  419. {topos_node-1.3.0 → topos_node-1.3.2}/topos/projections/vector_index/base.py +0 -0
  420. {topos_node-1.3.0 → topos_node-1.3.2}/topos/projections/vector_index/builders.py +0 -0
  421. {topos_node-1.3.0 → topos_node-1.3.2}/topos/projections/vector_index/health_checks.py +0 -0
  422. {topos_node-1.3.0 → topos_node-1.3.2}/topos/protocol/__init__.py +0 -0
  423. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/__init__.py +0 -0
  424. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/audit.py +0 -0
  425. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/ddr.py +0 -0
  426. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/disclosure.py +0 -0
  427. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/fingerprint.py +0 -0
  428. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/grant_cache.py +0 -0
  429. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/inference.py +0 -0
  430. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/intent.py +0 -0
  431. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/manifest.py +0 -0
  432. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/manifest_validation.py +0 -0
  433. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/minimizer.py +0 -0
  434. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/negotiation.py +0 -0
  435. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/planner.py +0 -0
  436. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/runtime.py +0 -0
  437. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/scope_registry_loader.py +0 -0
  438. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/session.py +0 -0
  439. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/session_utils.py +0 -0
  440. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/source_generation.py +0 -0
  441. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/truth_facts.py +0 -0
  442. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/truth_prompts.py +0 -0
  443. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/turn_classifier.py +0 -0
  444. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/types.py +0 -0
  445. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/verify.py +0 -0
  446. {topos_node-1.3.0 → topos_node-1.3.2}/topos/query/verify_modes.py +0 -0
  447. {topos_node-1.3.0 → topos_node-1.3.2}/topos/rate_limit.py +0 -0
  448. {topos_node-1.3.0 → topos_node-1.3.2}/topos/routines/__init__.py +0 -0
  449. {topos_node-1.3.0 → topos_node-1.3.2}/topos/routines/schema.py +0 -0
  450. {topos_node-1.3.0 → topos_node-1.3.2}/topos/routines/store.py +0 -0
  451. {topos_node-1.3.0 → topos_node-1.3.2}/topos/runtime_housekeeping.py +0 -0
  452. {topos_node-1.3.0 → topos_node-1.3.2}/topos/runtime_shutdown.py +0 -0
  453. {topos_node-1.3.0 → topos_node-1.3.2}/topos/runtime_update.py +0 -0
  454. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sanitization/__init__.py +0 -0
  455. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sanitization/nsfw_classifier.py +0 -0
  456. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sanitization/ollama_transforms.py +0 -0
  457. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sanitization/prewarm.py +0 -0
  458. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sanitization/privacy_filter.py +0 -0
  459. {topos_node-1.3.0 → topos_node-1.3.2}/topos/scope_resolution.py +0 -0
  460. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/__init__.py +0 -0
  461. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/container.py +0 -0
  462. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/embeddings/__init__.py +0 -0
  463. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/embeddings/base.py +0 -0
  464. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/embeddings/local.py +0 -0
  465. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/embeddings/remote.py +0 -0
  466. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/interfaces.py +0 -0
  467. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/llm/__init__.py +0 -0
  468. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/llm/base.py +0 -0
  469. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/llm/openai.py +0 -0
  470. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/local.py +0 -0
  471. {topos_node-1.3.0 → topos_node-1.3.2}/topos/services/postgres.py +0 -0
  472. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/__init__.py +0 -0
  473. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/bundled_canonical_triples.py +0 -0
  474. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/canonical_signal_defaults.py +0 -0
  475. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/definitions.py +0 -0
  476. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/install_service.py +0 -0
  477. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/registry.py +0 -0
  478. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/runtime_install.py +0 -0
  479. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/scrub_attribution.py +0 -0
  480. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sources/scrub_service.py +0 -0
  481. {topos_node-1.3.0 → topos_node-1.3.2}/topos/startup_banner.py +0 -0
  482. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/__init__.py +0 -0
  483. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/__init__.py +0 -0
  484. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/factory.py +0 -0
  485. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/fakes.py +0 -0
  486. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/postgres/stores.py +0 -0
  487. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/protocols.py +0 -0
  488. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/sqlite/__init__.py +0 -0
  489. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/sqlite/stores.py +0 -0
  490. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  491. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/__init__.py +0 -0
  492. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/activity_tables.py +0 -0
  493. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  494. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  495. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  496. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/ai_chat/model.py +0 -0
  497. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/ai_chat/tables.py +0 -0
  498. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  499. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/canonical_store.py +0 -0
  500. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/conversations_tables.py +0 -0
  501. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/mapping_store.py +0 -0
  502. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/canonical/postgres.py +0 -0
  503. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/__init__.py +0 -0
  504. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/client.py +0 -0
  505. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/connection_tuning.py +0 -0
  506. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  507. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  508. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  509. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  510. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  511. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  512. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  513. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  514. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  515. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  516. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/documents_v1.py +0 -0
  517. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  518. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/episodes_v1.py +0 -0
  519. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  520. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  521. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  522. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  523. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  524. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  525. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  526. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  527. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  528. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  529. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  530. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/signal_objects.py +0 -0
  531. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  532. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  533. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  534. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  535. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  536. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  537. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  538. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  539. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  540. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  541. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  542. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  543. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  544. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  545. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  546. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  547. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  548. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  549. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  550. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  551. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  552. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/paths.py +0 -0
  553. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/postgres.py +0 -0
  554. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/schema.py +0 -0
  555. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/storage_breakdown.py +0 -0
  556. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/db/write_gate.py +0 -0
  557. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/enrichment/__init__.py +0 -0
  558. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  559. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  560. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/normalized/__init__.py +0 -0
  561. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/normalized/normalized_store.py +0 -0
  562. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/oplog/__init__.py +0 -0
  563. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/oplog/decision.py +0 -0
  564. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/oplog/oplog_store.py +0 -0
  565. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/oplog/postgres.py +0 -0
  566. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/person/identity_resolver.py +0 -0
  567. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/projections/__init__.py +0 -0
  568. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/projections/index_ops_store.py +0 -0
  569. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/projections/vector_index_store.py +0 -0
  570. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/raw/__init__.py +0 -0
  571. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/raw/browser_flat_tables.py +0 -0
  572. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/raw/file_store.py +0 -0
  573. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/raw/raw_store.py +0 -0
  574. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/raw/raw_tables_manager.py +0 -0
  575. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/raw/sqlite_raw_store.py +0 -0
  576. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/security/encryption.py +0 -0
  577. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/signal_identity.py +0 -0
  578. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/source_settings.py +0 -0
  579. {topos_node-1.3.0 → topos_node-1.3.2}/topos/storage/user_identity.py +0 -0
  580. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sync/__init__.py +0 -0
  581. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sync/client.py +0 -0
  582. {topos_node-1.3.0 → topos_node-1.3.2}/topos/sync_handlers.py +0 -0
  583. {topos_node-1.3.0 → topos_node-1.3.2}/topos/testing/__init__.py +0 -0
  584. {topos_node-1.3.0 → topos_node-1.3.2}/topos/testing/lifespan.py +0 -0
  585. {topos_node-1.3.0 → topos_node-1.3.2}/topos/uma_filters.py +0 -0
  586. {topos_node-1.3.0 → topos_node-1.3.2}/topos/uma_resource_id.py +0 -0
  587. {topos_node-1.3.0 → topos_node-1.3.2}/topos/uma_rpt.py +0 -0
  588. {topos_node-1.3.0 → topos_node-1.3.2}/topos/upgrades/__init__.py +0 -0
  589. {topos_node-1.3.0 → topos_node-1.3.2}/topos/utils/base_object.py +0 -0
  590. {topos_node-1.3.0 → topos_node-1.3.2}/topos/websocket_client.py +0 -0
  591. {topos_node-1.3.0 → topos_node-1.3.2}/topos_node.egg-info/dependency_links.txt +0 -0
  592. {topos_node-1.3.0 → topos_node-1.3.2}/topos_node.egg-info/entry_points.txt +0 -0
  593. {topos_node-1.3.0 → topos_node-1.3.2}/topos_node.egg-info/top_level.txt +0 -0
@@ -3,3 +3,5 @@
3
3
  # topos/query/scope_registry.json, whose absence denies every scoped query.
4
4
  recursive-include topos *.json
5
5
  recursive-include shared *.json
6
+ # Tray icon glyphs (topos/cli/assets) — without them the tray cannot render.
7
+ recursive-include topos *.png
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: Topos personal AI engine (FastAPI): local data, sync, control plane WebSocket client
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Homepage, https://topos.dialogues.ai
@@ -33,7 +33,12 @@ Requires-Dist: hf-xet~=1.5.1
33
33
  Requires-Dist: sentence-transformers~=5.6.0
34
34
  Requires-Dist: networkx<3.7,>=3.2.1
35
35
  Requires-Dist: python-louvain<0.17,>=0.16
36
+ Requires-Dist: numpy<3,>=1.26
37
+ Requires-Dist: scipy<2,>=1.11
38
+ Requires-Dist: scikit-learn<2,>=1.4
36
39
  Requires-Dist: sqlite-vec~=0.1.9
40
+ Requires-Dist: pystray~=0.19.5
41
+ Requires-Dist: pillow>=10.0
37
42
  Provides-Extra: database
38
43
  Requires-Dist: psycopg[binary]~=3.3.3; extra == "database"
39
44
  Provides-Extra: engine
@@ -46,6 +51,9 @@ Requires-Dist: hf-xet~=1.5.1; extra == "engine"
46
51
  Requires-Dist: sentence-transformers~=5.6.0; extra == "engine"
47
52
  Requires-Dist: networkx<3.7,>=3.2.1; extra == "engine"
48
53
  Requires-Dist: python-louvain<0.17,>=0.16; extra == "engine"
54
+ Requires-Dist: numpy<3,>=1.26; extra == "engine"
55
+ Requires-Dist: scipy<2,>=1.11; extra == "engine"
56
+ Requires-Dist: scikit-learn<2,>=1.4; extra == "engine"
49
57
  Provides-Extra: local
50
58
  Provides-Extra: signal
51
59
  Requires-Dist: pysqlcipher3~=1.2.0; extra == "signal"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "topos-node"
7
- version = "1.3.0"
7
+ version = "1.3.2"
8
8
  description = "Topos personal AI engine (FastAPI): local data, sync, control plane WebSocket client"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -35,7 +35,15 @@ dependencies = [
35
35
  "sentence-transformers~=5.6.0",
36
36
  "networkx>=3.2.1,<3.7",
37
37
  "python-louvain>=0.16,<0.17",
38
+ # Complexity readings (topos.features.complexity): entropy/MI + graph math.
39
+ "numpy>=1.26,<3",
40
+ "scipy>=1.11,<2",
41
+ "scikit-learn>=1.4,<2",
38
42
  "sqlite-vec~=0.1.9",
43
+ # Menu-bar/system-tray status icon (topos.cli.tray). Imported lazily and
44
+ # only when a GUI session is detected — harmless on headless installs.
45
+ "pystray~=0.19.5",
46
+ "pillow>=10.0",
39
47
  ]
40
48
 
41
49
  [project.urls]
@@ -58,6 +66,9 @@ engine = [
58
66
  "sentence-transformers~=5.6.0",
59
67
  "networkx>=3.2.1,<3.7",
60
68
  "python-louvain>=0.16,<0.17",
69
+ "numpy>=1.26,<3",
70
+ "scipy>=1.11,<2",
71
+ "scikit-learn>=1.4,<2",
61
72
  ]
62
73
  # Backward-compatible alias; local runtime deps are in core dependencies.
63
74
  local = []
@@ -109,6 +120,7 @@ markers = [
109
120
  "adversarial: scope-break / access-control adversarial test (privacy enforcement)",
110
121
  "uar: unauthorized-access-rate probe (privacy claim #1); tier-1 CI gate, must find zero leaks",
111
122
  "cer: canary-extraction-rate probe (privacy claim #2); tier-1 CI gate",
123
+ "bhlr: black-hole leak-rate probe (entity black hole); tier-1 CI gate, must find zero leaks",
112
124
  "eval_nightly: statistical privacy eval (attacker advantage, minimality, latency); nightly",
113
125
  "eval_release: release-tier privacy eval (negotiation A/B, Pareto); run per release",
114
126
  ]
@@ -1,6 +1,6 @@
1
1
  """Topos Control Plane Version Information."""
2
2
 
3
- __version__ = "1.3.0"
4
- __version_info__ = (1, 3, 0)
3
+ __version__ = "1.3.2"
4
+ __version_info__ = (1, 3, 2)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -16,6 +16,51 @@ logger = logging.getLogger("topos.api.llm")
16
16
  router = APIRouter()
17
17
 
18
18
 
19
+ def _enforce_blackhole_egress(body: GenerationRequest) -> GenerationRequest:
20
+ """Gate B: this route reaches cloud providers without passing the engine router.
21
+
22
+ `Engine.run` gates every task-shaped inference, but these two endpoints call
23
+ the LLM service directly, so the same policy has to be applied here or the
24
+ hole stays open. Rewrites the provider onto a secure one when the prompt
25
+ mentions a protected entity; refuses when nothing secure can serve it.
26
+
27
+ The refusal is owner-facing (this route is API-key authenticated) and still
28
+ names no entity — the reason may be logged somewhere less private.
29
+ """
30
+ from fastapi import HTTPException
31
+
32
+ try:
33
+ from ..engine.engine import _policy_db_connection
34
+ from ..features.lifecycle.blackhole_llm import describe_block, evaluate
35
+ except Exception: # noqa: BLE001
36
+ return body
37
+
38
+ conn, owned = _policy_db_connection()
39
+ try:
40
+ verdict = evaluate(
41
+ conn,
42
+ {"prompt": body.prompt, "system": getattr(body, "system", None)},
43
+ provider=body.provider or "",
44
+ )
45
+ except Exception as exc: # noqa: BLE001
46
+ raise HTTPException(status_code=503, detail=f"blackhole_policy_unavailable: {exc}")
47
+ finally:
48
+ if owned and conn is not None:
49
+ try:
50
+ conn.close()
51
+ except Exception: # noqa: BLE001
52
+ pass
53
+
54
+ if not verdict.tainted:
55
+ return body
56
+ if verdict.blocked:
57
+ raise HTTPException(status_code=503, detail=describe_block(verdict))
58
+ if verdict.redirected:
59
+ logger.info("blackhole: llm route redirected to %s", verdict.provider)
60
+ return body.model_copy(update={"provider": verdict.provider, "model": None})
61
+ return body
62
+
63
+
19
64
  @router.post(
20
65
  "/llm_generation",
21
66
  response_model=GenerationResponse,
@@ -28,6 +73,7 @@ async def llm_generation(body: GenerationRequest):
28
73
  body.model,
29
74
  len(body.prompt or ""),
30
75
  )
76
+ body = _enforce_blackhole_egress(body)
31
77
  services: Services = get_services()
32
78
  result = await services.llm.generate(body.model_dump())
33
79
  usage = result.get("usage") if isinstance(result, dict) else {}
@@ -60,6 +106,7 @@ async def llm_generation_alias(body: GenerationRequest):
60
106
  body.model,
61
107
  len(body.prompt or ""),
62
108
  )
109
+ body = _enforce_blackhole_egress(body)
63
110
  services: Services = get_services()
64
111
  result = await services.llm.generate(body.model_dump())
65
112
  usage = result.get("usage") if isinstance(result, dict) else {}
@@ -0,0 +1,91 @@
1
+ """Shell contract endpoints.
2
+
3
+ Everything a menu-bar/tray shell (the pystray tray, the future Swift macOS
4
+ shell, the Windows shell) needs to supervise this node lives here, so shells
5
+ stay dumb renderers: identity + version for attach-don't-double-start, the
6
+ log file location for a "Show Logs" action, and cached update state with a
7
+ localhost-only trigger to apply an update.
8
+
9
+ Update *checking* is not done here — the runtime update monitor started in
10
+ app startup keeps ``get_update_info()`` fresh; this router only reads it.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import os
16
+ import threading
17
+ from time import time
18
+
19
+ from fastapi import APIRouter, HTTPException, Request
20
+
21
+ from ..core.logging import get_log_file_path
22
+ from ..runtime_update import (
23
+ DEFAULT_PACKAGE_NAME,
24
+ apply_package_update,
25
+ get_runtime_version,
26
+ get_update_info,
27
+ )
28
+
29
+ router = APIRouter(prefix="/v1/shell", tags=["shell"])
30
+
31
+ _STARTED_AT = time()
32
+
33
+ _apply_lock = threading.Lock()
34
+ _apply_state: dict[str, object] = {"applying": False, "last_result": None}
35
+
36
+
37
+ def _client_is_local(request: Request) -> bool:
38
+ # Applying an update is the one mutating action here; a LAN peer must not
39
+ # be able to trigger it even though the node binds 0.0.0.0. ("testclient"
40
+ # is FastAPI's TestClient peer name — unreachable over a real socket.)
41
+ host = request.client.host if request.client else None
42
+ return host in ("127.0.0.1", "::1", "localhost", "testclient")
43
+
44
+
45
+ @router.get("/status")
46
+ async def shell_status() -> dict:
47
+ info = get_update_info()
48
+ log_file = get_log_file_path()
49
+ return {
50
+ "name": "topos-node",
51
+ "version": get_runtime_version(),
52
+ "pid": os.getpid(),
53
+ "started_at": _STARTED_AT,
54
+ "log_file": str(log_file) if log_file else None,
55
+ "update": {
56
+ "available": info is not None,
57
+ "installed": info.installed if info else None,
58
+ "latest": info.latest if info else None,
59
+ "applying": _apply_state["applying"],
60
+ "last_result": _apply_state["last_result"],
61
+ },
62
+ }
63
+
64
+
65
+ @router.post("/update")
66
+ async def shell_apply_update(request: Request) -> dict:
67
+ if not _client_is_local(request):
68
+ raise HTTPException(
69
+ status_code=403, detail="Shell update can only be triggered from localhost."
70
+ )
71
+ if get_update_info() is None:
72
+ return {"started": False, "reason": "no_update_available"}
73
+ with _apply_lock:
74
+ if _apply_state["applying"]:
75
+ return {"started": False, "reason": "already_applying"}
76
+ _apply_state["applying"] = True
77
+ _apply_state["last_result"] = None
78
+
79
+ def worker() -> None:
80
+ ok = False
81
+ try:
82
+ ok = apply_package_update(DEFAULT_PACKAGE_NAME)
83
+ finally:
84
+ with _apply_lock:
85
+ _apply_state["applying"] = False
86
+ # The running process keeps the old version until restart;
87
+ # shells surface "restart to finish" off this value.
88
+ _apply_state["last_result"] = "success" if ok else "failed"
89
+
90
+ threading.Thread(target=worker, daemon=True, name="topos-shell-update").start()
91
+ return {"started": True}
@@ -217,9 +217,12 @@ async def list_entities(
217
217
  ):
218
218
  """Resolved entity registry (entity spine), sorted by mention count."""
219
219
  from ..features.entities.reads import list_entities as _list
220
+ from ..features.lifecycle.blackhole_guard import owner_ui_guard
220
221
 
222
+ conn = _entities_conn()
221
223
  return _list(
222
- _entities_conn(),
224
+ conn,
225
+ guard=owner_ui_guard(conn),
223
226
  q=q,
224
227
  entity_type=entity_type,
225
228
  contacts_only=contacts_only,
@@ -253,11 +256,13 @@ async def get_entity_graph(
253
256
  import asyncio
254
257
 
255
258
  from ..features.entities.reads import entity_graph
259
+ from ..features.lifecycle.blackhole_guard import owner_ui_guard
256
260
 
257
261
  conn = _entities_conn()
258
262
  return await asyncio.to_thread(
259
263
  entity_graph,
260
264
  conn,
265
+ guard=owner_ui_guard(conn),
261
266
  limit_nodes=limit_nodes,
262
267
  limit_edges=limit_edges,
263
268
  min_weight=min_weight,
@@ -347,8 +352,10 @@ async def get_entity(
347
352
  ):
348
353
  """Entity detail: aliases, connections, recent mentions, dossier (owner view)."""
349
354
  from ..features.entities.reads import get_entity_detail
355
+ from ..features.lifecycle.blackhole_guard import owner_ui_guard
350
356
 
351
- detail = get_entity_detail(_entities_conn(), entity_id)
357
+ conn = _entities_conn()
358
+ detail = get_entity_detail(conn, entity_id, guard=owner_ui_guard(conn))
352
359
  if detail is None:
353
360
  raise HTTPException(status_code=404, detail=f"entity not found: {entity_id}")
354
361
  return detail
@@ -458,6 +465,79 @@ async def exclude_entity_from_intelligence(
458
465
  raise HTTPException(status_code=400, detail=str(exc))
459
466
 
460
467
 
468
+ class EntityBlackholeBody(BaseModel):
469
+ processing_tier: str = Field(default="secure", max_length=20)
470
+ note: Optional[str] = Field(default=None, max_length=500)
471
+
472
+
473
+ @router.post("/entities/{entity_id}/blackhole")
474
+ async def blackhole_entity(
475
+ entity_id: str,
476
+ body: EntityBlackholeBody = EntityBlackholeBody(),
477
+ _api_key: str = Depends(require_api_key),
478
+ ):
479
+ """Owner black hole: this entity is mine alone.
480
+
481
+ Nothing is deleted — the owner keeps full visibility. Every other caller
482
+ (third-party MCP agents, routines, grantees) is denied, and content
483
+ mentioning it may only be processed by the tier's secure model set.
484
+ Raises a rebuild-needed notification before the rebuild runs (D4).
485
+ """
486
+ import asyncio
487
+
488
+ from ..features.lifecycle.blackhole import BlackholeStore
489
+ from ..features.lifecycle.blackhole_rebuild import rebuild_for_blackhole
490
+
491
+ conn = _entities_conn()
492
+ try:
493
+ result = BlackholeStore(conn).blackhole_entity(
494
+ entity_ref=entity_id,
495
+ processing_tier=body.processing_tier,
496
+ note=body.note,
497
+ )
498
+ except ValueError as exc:
499
+ raise HTTPException(status_code=400, detail=str(exc))
500
+
501
+ # D4: the notification above was raised first, so the owner already knows the
502
+ # hide is incomplete; now do the rebuild that makes it true. Non-owners are
503
+ # withheld the prose artifacts for the duration, so this running late is safe
504
+ # while it running silently would not be.
505
+ if not result.get("already_blackholed"):
506
+ result["rebuild"] = await asyncio.to_thread(rebuild_for_blackhole, conn, entity_id)
507
+ result["rebuild"] = result["rebuild"].as_dict()
508
+ return result
509
+
510
+
511
+ @router.delete("/entities/{entity_id}/blackhole")
512
+ async def unblackhole_entity(
513
+ entity_id: str,
514
+ _api_key: str = Depends(require_api_key),
515
+ ):
516
+ """Lift a black hole. Existing grants are not restored — normal permissions resume."""
517
+ from ..features.lifecycle.blackhole import BlackholeStore
518
+
519
+ return BlackholeStore(_entities_conn()).unblackhole_entity(entity_ref=entity_id)
520
+
521
+
522
+ @router.get("/blackholes")
523
+ async def list_blackholes(_api_key: str = Depends(require_api_key)):
524
+ """The owner's off-limits list (mirrors the exclusions list in the drawer)."""
525
+ from ..features.lifecycle.blackhole import BlackholeStore
526
+
527
+ store = BlackholeStore(_entities_conn())
528
+ return {"blackholes": store.list(), "notifications": store.notifications(state="open")}
529
+
530
+
531
+ @router.post("/blackholes/notifications/{notification_id}/dismiss")
532
+ async def dismiss_blackhole_notification(
533
+ notification_id: str,
534
+ _api_key: str = Depends(require_api_key),
535
+ ):
536
+ from ..features.lifecycle.blackhole import BlackholeStore
537
+
538
+ return {"dismissed": BlackholeStore(_entities_conn()).dismiss_notification(notification_id)}
539
+
540
+
461
541
  @router.get("/facts")
462
542
  async def list_facts(
463
543
  predicate: Optional[str] = Query(default=None, max_length=80),
@@ -653,6 +733,23 @@ async def refresh_dimension_brief(
653
733
  raise HTTPException(status_code=400, detail=str(exc)) from exc
654
734
 
655
735
 
736
+ # --------------------------------------------------------------- timeline rollup
737
+
738
+ @router.get("/timeline/daily")
739
+ async def timeline_daily(
740
+ _api_key: str = Depends(require_api_key),
741
+ days: int = Query(90, ge=1, le=365),
742
+ ):
743
+ """Per-day lane counts + births + episodes (PLAN_TIMELINE_UNIFIED.md E1)."""
744
+ from ..core.state import get_db_connection
745
+ from ..features.timeline_rollup import timeline_daily_rollup
746
+
747
+ conn = get_db_connection()
748
+ if conn is None:
749
+ raise HTTPException(status_code=503, detail="database unavailable")
750
+ return timeline_daily_rollup(conn, days=days)
751
+
752
+
656
753
  # --------------------------------------------------------------- attention triage
657
754
 
658
755
  @router.get("/attention/dashboard")
@@ -669,3 +766,99 @@ async def attention_dashboard(
669
766
  if conn is None:
670
767
  raise HTTPException(status_code=503, detail="database unavailable")
671
768
  return attention_dashboard_data(conn, days=days, include_titles=include_titles)
769
+
770
+
771
+ # --------------------------------------------------------------- complexity
772
+
773
+ @router.get("/complexity/summary")
774
+ async def complexity_summary(
775
+ _api_key: str = Depends(require_api_key),
776
+ recompute: bool = Query(False),
777
+ weeks: int = Query(12, ge=1, le=104),
778
+ window_days: int = Query(30, ge=1, le=3650),
779
+ half_life_days: Optional[float] = Query(None, ge=0.1, le=3650.0),
780
+ ):
781
+ """Data spine for the /data/complexity tab (PLAN_COMPLEXITY_DATA_PAGE.md).
782
+
783
+ Snapshot computation is CPU-bound (~1s cold on a live-size DB), so it runs
784
+ in a worker thread; warm calls serve the complexity_snapshots cache.
785
+ """
786
+ import asyncio
787
+
788
+ from ..core.state import get_db_connection
789
+ from ..features.complexity.engine import get_complexity_summary
790
+
791
+ conn = get_db_connection()
792
+ if conn is None:
793
+ raise HTTPException(status_code=503, detail="database unavailable")
794
+ return await asyncio.to_thread(
795
+ get_complexity_summary,
796
+ conn,
797
+ recompute=recompute,
798
+ weeks=weeks,
799
+ window_days=window_days,
800
+ half_life_days=half_life_days,
801
+ )
802
+
803
+
804
+ @router.get("/complexity/timeline")
805
+ async def complexity_timeline(
806
+ _api_key: str = Depends(require_api_key),
807
+ recompute: bool = Query(False),
808
+ weeks: int = Query(12, ge=1, le=104),
809
+ ):
810
+ import asyncio
811
+
812
+ from ..core.state import get_db_connection
813
+ from ..features.complexity.engine import get_shift_timeline
814
+
815
+ conn = get_db_connection()
816
+ if conn is None:
817
+ raise HTTPException(status_code=503, detail="database unavailable")
818
+ return await asyncio.to_thread(get_shift_timeline, conn, recompute=recompute, weeks=weeks)
819
+
820
+
821
+ @router.get("/complexity/topics/daily")
822
+ async def complexity_topics_daily(
823
+ _api_key: str = Depends(require_api_key),
824
+ days: int = Query(90, ge=1, le=365),
825
+ top: int = Query(10, ge=1, le=24),
826
+ ):
827
+ """Per-day supertopic shares — the braid's substrate (PLAN_TIMELINE_UNIFIED.md E2)."""
828
+ import asyncio
829
+
830
+ from ..core.state import get_db_connection
831
+ from ..features.complexity.topics_daily import topics_daily
832
+
833
+ conn = get_db_connection()
834
+ if conn is None:
835
+ raise HTTPException(status_code=503, detail="database unavailable")
836
+ return await asyncio.to_thread(topics_daily, conn, days=days, top=top)
837
+
838
+
839
+ @router.get("/complexity/influence")
840
+ async def complexity_influence(
841
+ _api_key: str = Depends(require_api_key),
842
+ recompute: bool = Query(False),
843
+ weeks: int = Query(12, ge=1, le=104),
844
+ top_k: int = Query(5, ge=1, le=50),
845
+ window_days: int = Query(90, ge=1, le=3650),
846
+ target: Optional[str] = Query(None, max_length=500),
847
+ ):
848
+ import asyncio
849
+
850
+ from ..core.state import get_db_connection
851
+ from ..features.complexity.engine import get_influence_threads
852
+
853
+ conn = get_db_connection()
854
+ if conn is None:
855
+ raise HTTPException(status_code=503, detail="database unavailable")
856
+ return await asyncio.to_thread(
857
+ get_influence_threads,
858
+ conn,
859
+ recompute=recompute,
860
+ weeks=weeks,
861
+ top_k=top_k,
862
+ window_days=window_days,
863
+ target=target,
864
+ )
@@ -253,8 +253,12 @@ async def get_uma_messages(
253
253
  )
254
254
  items = _get_messages_from_db(conn, effective_dataset_id, limited, offset, allowed_tables=allowed_tables)
255
255
  try:
256
+ # UMA data proxy = the grantee HTTP lane; filter unconditionally.
257
+ from ..features.lifecycle.blackhole_guard import BlackholeGuard, CallerClass
258
+
256
259
  items, uma_contact_sidecar = apply_message_contact_pipeline(
257
260
  items,
261
+ blackhole_guard=BlackholeGuard(conn, caller_class=CallerClass.GRANTEE),
258
262
  conn=conn,
259
263
  dataset_id=effective_dataset_id,
260
264
  allowed_scopes=allowed_scopes,
@@ -5,6 +5,7 @@ import importlib.util
5
5
  import logging
6
6
  import os
7
7
  import sys
8
+ import threading
8
9
 
9
10
  from fastapi import FastAPI
10
11
  from fastapi.middleware.cors import CORSMiddleware
@@ -47,6 +48,7 @@ from .api import (
47
48
  home_chat as home_chat_routes,
48
49
  privacy_disclose as privacy_disclose_routes,
49
50
  signal as signal_routes,
51
+ shell as shell_routes,
50
52
  tool_index as tool_index_routes,
51
53
  upgrades as upgrades_routes,
52
54
  )
@@ -99,6 +101,7 @@ app.add_middleware(
99
101
  )
100
102
 
101
103
  app.include_router(health_routes.router)
104
+ app.include_router(shell_routes.router)
102
105
  app.include_router(upgrades_routes.router)
103
106
  app.include_router(local_mcp_routes.router)
104
107
  app.include_router(llm_routes.router)
@@ -171,19 +174,9 @@ async def startup_event() -> None:
171
174
  logger.info("Stage 9 migrations applied at startup: %d renames", len(result["applied"]))
172
175
  except Exception as e:
173
176
  logger.debug("Stage 9 migrations at startup (non-fatal): %s", e)
174
- # Upgrade runner: compare the stamped derivation baseline against the
175
- # shipped version and re-derive what this release invalidated (manifest in
176
- # topos/upgrades). Heavy steps run in a daemon thread; the node serves
177
- # stale derived data meanwhile. Fresh installs stamp-and-skip.
178
- try:
179
- from .core.state import get_db_connection as _get_conn_for_upgrades
180
- from .upgrades.runner import start_background as _start_upgrades
181
-
182
- _upgrade_conn = state.db_conn if state.db_conn is not None else _get_conn_for_upgrades()
183
- if _upgrade_conn is not None:
184
- _start_upgrades(_upgrade_conn)
185
- except Exception as e:
186
- logger.warning("Upgrade runner at startup failed (non-fatal): %s", e)
177
+ # Upgrade runner is armed later — after control-plane / local readiness —
178
+ # so the React UI can fetch bootstrap data before enrichment reprocess
179
+ # contends for SQLite / Ollama / MPS. See _arm_upgrade_runner below.
187
180
  try:
188
181
  from .core.state import get_db_connection as _get_conn_for_pipeline
189
182
  from .pipeline.job_runner import recover_pipeline_jobs, start_pipeline_worker
@@ -295,6 +288,41 @@ async def startup_event() -> None:
295
288
  start_runtime_update_monitor()
296
289
  start_update_hotkey_listener()
297
290
 
291
+ # Upgrade runner: plan/stamp cheaply, but defer heavy re-derivation until the
292
+ # UI can bootstrap (CP connected + grace). Fresh installs stamp-and-skip.
293
+ try:
294
+ from .core.state import get_db_connection as _get_conn_for_upgrades
295
+ from .upgrades.runner import (
296
+ ready_timeout_seconds as _upgrade_ready_timeout,
297
+ start_background as _start_upgrades,
298
+ ui_grace_seconds as _upgrade_ui_grace,
299
+ )
300
+
301
+ _upgrade_conn = state.db_conn if state.db_conn is not None else _get_conn_for_upgrades()
302
+ if _upgrade_conn is not None:
303
+ _upgrade_ready = threading.Event()
304
+ _start_upgrades(
305
+ _upgrade_conn,
306
+ ready_event=_upgrade_ready,
307
+ ui_grace_s=_upgrade_ui_grace(),
308
+ ready_timeout_s=_upgrade_ready_timeout(),
309
+ )
310
+
311
+ async def _signal_upgrade_ui_ready() -> None:
312
+ try:
313
+ if state.control_plane_client is not None:
314
+ await state.control_plane_client.wait_until_connected(
315
+ timeout_s=_upgrade_ready_timeout()
316
+ )
317
+ except Exception as ready_exc: # noqa: BLE001
318
+ logger.debug("Upgrade UI-ready wait ended: %s", ready_exc)
319
+ finally:
320
+ _upgrade_ready.set()
321
+
322
+ asyncio.create_task(_signal_upgrade_ui_ready())
323
+ except Exception as e:
324
+ logger.warning("Upgrade runner at startup failed (non-fatal): %s", e)
325
+
298
326
  if settings.enable_sync and settings.topos_user_id:
299
327
  state.sync_client = SyncClient(
300
328
  sync_url=settings.get_sync_url(),