topos-node 1.3.38__tar.gz → 1.3.40__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 (766) hide show
  1. {topos_node-1.3.38/topos_node.egg-info → topos_node-1.3.40}/PKG-INFO +3 -3
  2. {topos_node-1.3.38 → topos_node-1.3.40}/README.md +2 -2
  3. {topos_node-1.3.38 → topos_node-1.3.40}/pyproject.toml +3 -3
  4. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_active_database_binding.py +2 -1
  5. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_profile_hygiene.py +2 -1
  6. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_profiles.py +4 -3
  7. {topos_node-1.3.38 → topos_node-1.3.40}/topos/__version__.py +2 -2
  8. topos_node-1.3.40/topos/api/ingestion_api.py +155 -0
  9. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/commands.py +3 -2
  10. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/profile_cmd.py +2 -1
  11. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/__init__.py +1 -0
  12. topos_node-1.3.40/topos/core/handlers/graph_summary.py +72 -0
  13. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/ingest.py +75 -0
  14. topos_node-1.3.40/topos/defaults.py +9 -0
  15. {topos_node-1.3.38 → topos_node-1.3.40}/topos/disclosure/privacy_layer.py +52 -7
  16. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/entities_job.py +17 -2
  17. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/orchestrator.py +35 -5
  18. topos_node-1.3.40/topos/features/entities/chatgpt_declared.py +256 -0
  19. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/declared_mappings.py +48 -3
  20. topos_node-1.3.40/topos/features/signal/conversation_windows.py +263 -0
  21. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/canonical_pipeline.py +71 -0
  22. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/ingest_helpers.py +26 -3
  23. topos_node-1.3.40/topos/ingestion/local_exports.py +713 -0
  24. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/manager.py +188 -7
  25. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parser.py +43 -15
  26. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +10 -2
  27. topos_node-1.3.40/topos/ingestion/parsers/chatgpt_export.py +697 -0
  28. topos_node-1.3.40/topos/ingestion/triggers/file_trigger.py +77 -0
  29. {topos_node-1.3.38 → topos_node-1.3.40}/topos/mcp_stdio_proxy.py +7 -5
  30. {topos_node-1.3.38 → topos_node-1.3.40}/topos/pipeline/job_runner.py +48 -1
  31. {topos_node-1.3.38 → topos_node-1.3.40}/topos/profiles.py +4 -3
  32. {topos_node-1.3.38 → topos_node-1.3.40}/topos/protocol/handled_message_types.json +3 -0
  33. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/retrieval.py +16 -1
  34. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/ai_chat/canonicalizer.py +20 -1
  35. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/raw/file_store.py +21 -1
  36. {topos_node-1.3.38 → topos_node-1.3.40}/topos/upgrades/manifests.json +31 -0
  37. {topos_node-1.3.38 → topos_node-1.3.40/topos_node.egg-info}/PKG-INFO +3 -3
  38. {topos_node-1.3.38 → topos_node-1.3.40}/topos_node.egg-info/SOURCES.txt +6 -0
  39. topos_node-1.3.38/topos/api/ingestion_api.py +0 -80
  40. topos_node-1.3.38/topos/ingestion/triggers/file_trigger.py +0 -36
  41. {topos_node-1.3.38 → topos_node-1.3.40}/LICENSE +0 -0
  42. {topos_node-1.3.38 → topos_node-1.3.40}/MANIFEST.in +0 -0
  43. {topos_node-1.3.38 → topos_node-1.3.40}/setup.cfg +0 -0
  44. {topos_node-1.3.38 → topos_node-1.3.40}/shared/__init__.py +0 -0
  45. {topos_node-1.3.38 → topos_node-1.3.40}/shared/filtering.py +0 -0
  46. {topos_node-1.3.38 → topos_node-1.3.40}/shared/schema_registry.py +0 -0
  47. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_active_ingestion_binding.py +0 -0
  48. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_extensions.py +0 -0
  49. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_gate_leg_hermeticity.py +0 -0
  50. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_llm_integrations_storage.py +0 -0
  51. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_local_gate_composition.py +0 -0
  52. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_owner_database_hermeticity.py +0 -0
  53. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_prewarm_first_run.py +0 -0
  54. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_protocol_handled_types.py +0 -0
  55. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_query_field_contract.py +0 -0
  56. {topos_node-1.3.38 → topos_node-1.3.40}/tests/test_system_computer_name.py +0 -0
  57. {topos_node-1.3.38 → topos_node-1.3.40}/topos/__init__.py +0 -0
  58. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/__init__.py +0 -0
  59. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/dataset_resolution.py +0 -0
  60. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/duckdb_adapter.py +0 -0
  61. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/luck_surface.py +0 -0
  62. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/messenger_communities.py +0 -0
  63. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/messenger_directed.py +0 -0
  64. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/messenger_graph.py +0 -0
  65. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/messenger_labels.py +0 -0
  66. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/person_graph.py +0 -0
  67. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/person_overlay.py +0 -0
  68. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/profiles.py +0 -0
  69. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/query_engine.py +0 -0
  70. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/raw_queries.py +0 -0
  71. {topos_node-1.3.38 → topos_node-1.3.40}/topos/analytics/relationship_reads.py +0 -0
  72. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/__init__.py +0 -0
  73. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/analytics.py +0 -0
  74. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/app_registry.py +0 -0
  75. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/backup.py +0 -0
  76. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/community_naming_config.py +0 -0
  77. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/compute_remote.py +0 -0
  78. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/connected_apps.py +0 -0
  79. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/conversation_context.py +0 -0
  80. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/data_commit.py +0 -0
  81. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/data_explorer_table_prefs.py +0 -0
  82. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/database_explorer.py +0 -0
  83. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/db.py +0 -0
  84. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/device.py +0 -0
  85. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/disk_space_config.py +0 -0
  86. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/engine_run.py +0 -0
  87. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/enrichment.py +0 -0
  88. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/enrichment_lab.py +0 -0
  89. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/facts_llm_config.py +0 -0
  90. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/filter_lab.py +0 -0
  91. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/health.py +0 -0
  92. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/home_chat.py +0 -0
  93. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/ingestion_compat.py +0 -0
  94. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/ingestion_sources.py +0 -0
  95. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/intelligence_lifecycle.py +0 -0
  96. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/llm.py +0 -0
  97. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/local_mcp.py +0 -0
  98. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/messenger_analytics.py +0 -0
  99. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/privacy_disclose.py +0 -0
  100. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/query_api.py +0 -0
  101. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/runtime_bootstrap.py +0 -0
  102. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/sanitization_ollama_config.py +0 -0
  103. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/shell.py +0 -0
  104. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/signal.py +0 -0
  105. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/signal_extraction_config.py +0 -0
  106. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/source_install.py +0 -0
  107. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/source_scrub.py +0 -0
  108. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/sources.py +0 -0
  109. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/sources_overview.py +0 -0
  110. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/sync.py +0 -0
  111. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/tool_index.py +0 -0
  112. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/ui_config.py +0 -0
  113. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/uma_data.py +0 -0
  114. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/upgrades.py +0 -0
  115. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/usage.py +0 -0
  116. {topos_node-1.3.38 → topos_node-1.3.40}/topos/api/user_identity.py +0 -0
  117. {topos_node-1.3.38 → topos_node-1.3.40}/topos/app.py +0 -0
  118. {topos_node-1.3.38 → topos_node-1.3.40}/topos/auth.py +0 -0
  119. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/__init__.py +0 -0
  120. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/declared_field_map.py +0 -0
  121. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/__init__.py +0 -0
  122. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/base.py +0 -0
  123. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  124. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  125. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  126. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  127. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  128. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  129. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  130. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  131. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/models.py +0 -0
  132. {topos_node-1.3.38 → topos_node-1.3.40}/topos/canonicalization/resolver.py +0 -0
  133. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/__init__.py +0 -0
  134. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/__main__.py +0 -0
  135. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/assets/topos_blk_rounded.png +0 -0
  136. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/assets/topos_white.png +0 -0
  137. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/reprocess_cmd.py +0 -0
  138. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/setup_models_cmd.py +0 -0
  139. {topos_node-1.3.38 → topos_node-1.3.40}/topos/cli/tray.py +0 -0
  140. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/__init__.py +0 -0
  141. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/conversation_context_llm.py +0 -0
  142. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/facts_llm.py +0 -0
  143. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/local_model_builds.py +0 -0
  144. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/model_packs.py +0 -0
  145. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/node_function_providers.py +0 -0
  146. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/sanitization_ollama.py +0 -0
  147. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/settings.py +0 -0
  148. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/signal_extraction.py +0 -0
  149. {topos_node-1.3.38 → topos_node-1.3.40}/topos/config/uvicorn_logging.json +0 -0
  150. {topos_node-1.3.38 → topos_node-1.3.40}/topos/contacts/__init__.py +0 -0
  151. {topos_node-1.3.38 → topos_node-1.3.40}/topos/contacts/identity.py +0 -0
  152. {topos_node-1.3.38 → topos_node-1.3.40}/topos/control_plane_client.py +0 -0
  153. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/__init__.py +0 -0
  154. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/api_models.py +0 -0
  155. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/connection_resilience.py +0 -0
  156. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/db_health.py +0 -0
  157. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/device_helpers.py +0 -0
  158. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/errors.py +0 -0
  159. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/events.py +0 -0
  160. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/common.py +0 -0
  161. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/complexity.py +0 -0
  162. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/config.py +0 -0
  163. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/contacts_import.py +0 -0
  164. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/database_explorer.py +0 -0
  165. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/derivation.py +0 -0
  166. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/device.py +0 -0
  167. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/enrichment.py +0 -0
  168. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/enrichment_lab.py +0 -0
  169. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/filter_lab.py +0 -0
  170. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/graph_query.py +0 -0
  171. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/home_chat.py +0 -0
  172. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/mcp_client_elevations.py +0 -0
  173. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/mcp_clients.py +0 -0
  174. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/messages.py +0 -0
  175. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/messenger_analytics.py +0 -0
  176. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/query.py +0 -0
  177. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/registry.py +0 -0
  178. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/routines.py +0 -0
  179. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/signal_features.py +0 -0
  180. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/sources.py +0 -0
  181. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/timeline_daily.py +0 -0
  182. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/tool_index.py +0 -0
  183. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/handlers/uma.py +0 -0
  184. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/logging.py +0 -0
  185. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/metrics.py +0 -0
  186. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/routine_access.py +0 -0
  187. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/startup_banner.py +0 -0
  188. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/state.py +0 -0
  189. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/table_layers.py +0 -0
  190. {topos_node-1.3.38 → topos_node-1.3.40}/topos/core/types.py +0 -0
  191. {topos_node-1.3.38 → topos_node-1.3.40}/topos/data_explorer_row_delete.py +0 -0
  192. {topos_node-1.3.38 → topos_node-1.3.40}/topos/data_explorer_table_prefs.py +0 -0
  193. {topos_node-1.3.38 → topos_node-1.3.40}/topos/data_explorer_tables.py +0 -0
  194. {topos_node-1.3.38 → topos_node-1.3.40}/topos/disclosure/__init__.py +0 -0
  195. {topos_node-1.3.38 → topos_node-1.3.40}/topos/disclosure/canonical_writer.py +0 -0
  196. {topos_node-1.3.38 → topos_node-1.3.40}/topos/disclosure/content_policy.py +0 -0
  197. {topos_node-1.3.38 → topos_node-1.3.40}/topos/disclosure/field_registry.py +0 -0
  198. {topos_node-1.3.38 → topos_node-1.3.40}/topos/disclosure/tier.py +0 -0
  199. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/__init__.py +0 -0
  200. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/__init__.py +0 -0
  201. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/base.py +0 -0
  202. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/generative_prompts.py +0 -0
  203. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/generative_response.py +0 -0
  204. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/huggingface.py +0 -0
  205. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/ollama.py +0 -0
  206. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/openai.py +0 -0
  207. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/openai_compatible.py +0 -0
  208. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/redpill.py +0 -0
  209. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/backends/stub.py +0 -0
  210. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/client.py +0 -0
  211. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/disk_space.py +0 -0
  212. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/engine.py +0 -0
  213. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/hosted_llm_wallet.py +0 -0
  214. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/intake.py +0 -0
  215. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/memory_utils.py +0 -0
  216. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/model_cache.py +0 -0
  217. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/model_manager.py +0 -0
  218. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/ollama_install.py +0 -0
  219. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/ollama_pull.py +0 -0
  220. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/ollama_runtime.py +0 -0
  221. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/ollama_setup_guidance.py +0 -0
  222. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/pipeline_memory.py +0 -0
  223. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/queue_manager.py +0 -0
  224. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/registration.py +0 -0
  225. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/result_formatter.py +0 -0
  226. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/router.py +0 -0
  227. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/scoped_token.py +0 -0
  228. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/tasks.py +0 -0
  229. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/torch_runtime.py +0 -0
  230. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/transport.py +0 -0
  231. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/usage_guard.py +0 -0
  232. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/usage_observation.py +0 -0
  233. {topos_node-1.3.38 → topos_node-1.3.40}/topos/engine/validator.py +0 -0
  234. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/__init__.py +0 -0
  235. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/catalog.py +0 -0
  236. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/derivation_recovery.py +0 -0
  237. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/derived_tables.py +0 -0
  238. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/job_readiness.py +0 -0
  239. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/job_writer.py +0 -0
  240. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/__init__.py +0 -0
  241. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/base.py +0 -0
  242. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  243. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  244. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  245. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  246. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  247. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  248. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
  249. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
  250. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/derived_object_embeddings_job.py +0 -0
  251. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  252. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  253. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  254. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  255. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  256. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  257. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  258. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  259. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  260. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  261. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  262. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  263. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/raw/__init__.py +0 -0
  264. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  265. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/raw/language_job.py +0 -0
  266. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  267. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  268. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/model_overrides.py +0 -0
  269. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/models/__init__.py +0 -0
  270. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/models/manager.py +0 -0
  271. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/models/mvp_defaults.py +0 -0
  272. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/models/registry.py +0 -0
  273. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/models/versioning.py +0 -0
  274. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/pipeline_activity.py +0 -0
  275. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/processor.py +0 -0
  276. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/progress_bar.py +0 -0
  277. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/record_progress.py +0 -0
  278. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/registry_contract.py +0 -0
  279. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/signal_derivation_config.json +0 -0
  280. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment/source_overrides.py +0 -0
  281. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment_lab/__init__.py +0 -0
  282. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment_lab/bundles.py +0 -0
  283. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment_lab/model_resolve.py +0 -0
  284. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment_lab/schema.py +0 -0
  285. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment_lab/service.py +0 -0
  286. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment_lab/store.py +0 -0
  287. {topos_node-1.3.38 → topos_node-1.3.40}/topos/enrichment_lab/worker.py +0 -0
  288. {topos_node-1.3.38 → topos_node-1.3.40}/topos/evals/__init__.py +0 -0
  289. {topos_node-1.3.38 → topos_node-1.3.40}/topos/evals/enrichment_eval.py +0 -0
  290. {topos_node-1.3.38 → topos_node-1.3.40}/topos/extensions.py +0 -0
  291. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/__init__.py +0 -0
  292. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/canonical.py +0 -0
  293. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/engine.py +0 -0
  294. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/entropy.py +0 -0
  295. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/focus.py +0 -0
  296. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/graph_metrics.py +0 -0
  297. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/influence.py +0 -0
  298. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/projection.py +0 -0
  299. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/snapshots.py +0 -0
  300. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/store.py +0 -0
  301. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/topic_merge.py +0 -0
  302. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/topics.py +0 -0
  303. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/topics_daily.py +0 -0
  304. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/complexity/volatility.py +0 -0
  305. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/__init__.py +0 -0
  306. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
  307. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
  308. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +0 -0
  309. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
  310. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
  311. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
  312. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
  313. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
  314. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
  315. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
  316. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
  317. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
  318. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
  319. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/health.mental.yaml +0 -0
  320. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
  321. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
  322. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
  323. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
  324. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
  325. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
  326. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/net.capability.yaml +0 -0
  327. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/obligations.commitments.yaml +0 -0
  328. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
  329. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/places.mobility.yaml +0 -0
  330. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
  331. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
  332. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
  333. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
  334. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
  335. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
  336. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
  337. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
  338. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
  339. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
  340. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
  341. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/bundled_packs/work.career.yaml +0 -0
  342. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/candidates.py +0 -0
  343. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/guard.py +0 -0
  344. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/kernels.py +0 -0
  345. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/net_subject_policy.py +0 -0
  346. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/packs.py +0 -0
  347. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/person_bridge.py +0 -0
  348. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/prefilter.py +0 -0
  349. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/registry.py +0 -0
  350. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/report_card.py +0 -0
  351. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/router.py +0 -0
  352. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/social_bench.py +0 -0
  353. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/social_kernels.py +0 -0
  354. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/surfaces.py +0 -0
  355. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/synthesize.py +0 -0
  356. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/template.py +0 -0
  357. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/verify.py +0 -0
  358. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/derivation/writer.py +0 -0
  359. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/__init__.py +0 -0
  360. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/affinity.py +0 -0
  361. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/affinity_owner.py +0 -0
  362. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/affinity_quality.py +0 -0
  363. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/community_names.py +0 -0
  364. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/community_naming.py +0 -0
  365. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/consolidation.py +0 -0
  366. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/context_vectors.py +0 -0
  367. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/cypher.py +0 -0
  368. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/dossier.py +0 -0
  369. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/edges.py +0 -0
  370. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/fact_materializer.py +0 -0
  371. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/graph_enrichers.py +0 -0
  372. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/graph_refresh.py +0 -0
  373. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/graph_search.py +0 -0
  374. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/linking.py +0 -0
  375. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/maintenance.py +0 -0
  376. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/owner.py +0 -0
  377. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/reads.py +0 -0
  378. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/rebuild_subprocess.py +0 -0
  379. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/resolver.py +0 -0
  380. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/entities/structured_fields.py +0 -0
  381. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/facts/__init__.py +0 -0
  382. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/facts/extract.py +0 -0
  383. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/facts/llm_extract.py +0 -0
  384. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/facts/reads.py +0 -0
  385. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/facts/store.py +0 -0
  386. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/facts/verdicts.py +0 -0
  387. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/fit/evaluator.py +0 -0
  388. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/fit/opportunity_types.json +0 -0
  389. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/__init__.py +0 -0
  390. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/blackhole.py +0 -0
  391. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/blackhole_guard.py +0 -0
  392. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/blackhole_llm.py +0 -0
  393. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
  394. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/derived_scrub.py +0 -0
  395. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/exclusions.py +0 -0
  396. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/lifecycle/gc.py +0 -0
  397. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/provenance/__init__.py +0 -0
  398. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/provenance/posture.py +0 -0
  399. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/provenance/roles.py +0 -0
  400. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/__init__.py +0 -0
  401. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/brief_canonical_loader.py +0 -0
  402. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/brief_ontology.py +0 -0
  403. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/brief_renderer.py +0 -0
  404. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/brief_schemas.py +0 -0
  405. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/chunking.py +0 -0
  406. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/cluster_labels.py +0 -0
  407. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/conversation_context.py +0 -0
  408. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/data_health.py +0 -0
  409. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  410. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/intentions.json +0 -0
  411. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/interests.json +0 -0
  412. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/memory.json +0 -0
  413. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/places.json +0 -0
  414. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/profile.json +0 -0
  415. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/relationships.json +0 -0
  416. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/resources.json +0 -0
  417. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  418. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/time.json +0 -0
  419. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/wellbeing.json +0 -0
  420. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/definitions/work.json +0 -0
  421. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/derived_index.py +0 -0
  422. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/derived_spec.py +0 -0
  423. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/dimension_briefs.py +0 -0
  424. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/dimension_definition_loader.py +0 -0
  425. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/dimension_profiles.py +0 -0
  426. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/dimension_registry.py +0 -0
  427. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/embed_context.py +0 -0
  428. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/extraction/artifact_router.py +0 -0
  429. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/extraction/artifact_store.py +0 -0
  430. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/extraction/rule_extractors.py +0 -0
  431. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/graph_sanitize.py +0 -0
  432. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/hybrid_search.py +0 -0
  433. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/incremental_clustering.py +0 -0
  434. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/model_recommendations.py +0 -0
  435. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/query_embed_cache.py +0 -0
  436. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/schemas.py +0 -0
  437. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/service.py +0 -0
  438. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/signal_object_store.py +0 -0
  439. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/source_hydration.py +0 -0
  440. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/structured_signal.py +0 -0
  441. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/tool_index.py +0 -0
  442. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/topic_clustering.py +0 -0
  443. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/typed_stores/aggregates.py +0 -0
  444. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/typed_stores/commitments.py +0 -0
  445. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/typed_stores/rhythm.py +0 -0
  446. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  447. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/vector_codec.py +0 -0
  448. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/vector_math.py +0 -0
  449. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/signal/vector_settings.py +0 -0
  450. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/stats/__init__.py +0 -0
  451. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/stats/definitions.py +0 -0
  452. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/stats/engine.py +0 -0
  453. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/stats/fold.py +0 -0
  454. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/stats/insights.py +0 -0
  455. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/timeline_projection.py +0 -0
  456. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/timeline_rollup.py +0 -0
  457. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/triage/__init__.py +0 -0
  458. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/triage/badges.py +0 -0
  459. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/triage/daily.py +0 -0
  460. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/triage/dashboard.py +0 -0
  461. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/triage/instruments.py +0 -0
  462. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/triage/intents.py +0 -0
  463. {topos_node-1.3.38 → topos_node-1.3.40}/topos/features/triage/readiness.py +0 -0
  464. {topos_node-1.3.38 → topos_node-1.3.40}/topos/filter_lab/__init__.py +0 -0
  465. {topos_node-1.3.38 → topos_node-1.3.40}/topos/filter_lab/bundles.py +0 -0
  466. {topos_node-1.3.38 → topos_node-1.3.40}/topos/filter_lab/schema.py +0 -0
  467. {topos_node-1.3.38 → topos_node-1.3.40}/topos/filter_lab/service.py +0 -0
  468. {topos_node-1.3.38 → topos_node-1.3.40}/topos/filter_lab/store.py +0 -0
  469. {topos_node-1.3.38 → topos_node-1.3.40}/topos/filter_lab/worker.py +0 -0
  470. {topos_node-1.3.38 → topos_node-1.3.40}/topos/home_chat/__init__.py +0 -0
  471. {topos_node-1.3.38 → topos_node-1.3.40}/topos/home_chat/schema.py +0 -0
  472. {topos_node-1.3.38 → topos_node-1.3.40}/topos/home_chat/store.py +0 -0
  473. {topos_node-1.3.38 → topos_node-1.3.40}/topos/hosted_pool_lease.py +0 -0
  474. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/__init__.py +0 -0
  475. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/checkpoints/__init__.py +0 -0
  476. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  477. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  478. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/inbox_crypto.py +0 -0
  479. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/inbox_drain.py +0 -0
  480. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/jobs.py +0 -0
  481. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/journal_location_fanout.py +0 -0
  482. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/journal_time_log_normalize.py +0 -0
  483. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/local_sync.py +0 -0
  484. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/log_preview.py +0 -0
  485. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/__init__.py +0 -0
  486. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/base.py +0 -0
  487. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/browser_parser.py +0 -0
  488. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/calendar_parser.py +0 -0
  489. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  490. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  491. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/documents_parser.py +0 -0
  492. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  493. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  494. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/grok_parser.py +0 -0
  495. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/messenger_parser.py +0 -0
  496. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  497. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/progress.py +0 -0
  498. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/reprocess.py +0 -0
  499. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/__init__.py +0 -0
  500. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/base.py +0 -0
  501. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/calendar.py +0 -0
  502. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/chatgpt.py +0 -0
  503. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/contact_importers.py +0 -0
  504. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/grok.py +0 -0
  505. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/imessage_reader.py +0 -0
  506. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/signal_export_parser.py +0 -0
  507. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/sources/signal_reader.py +0 -0
  508. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/state_machine.py +0 -0
  509. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/triggers/__init__.py +0 -0
  510. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  511. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  512. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/validation/__init__.py +0 -0
  513. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/validation/base.py +0 -0
  514. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/validation/schema_registry.py +0 -0
  515. {topos_node-1.3.38 → topos_node-1.3.40}/topos/ingestion/validation/schema_validator.py +0 -0
  516. {topos_node-1.3.38 → topos_node-1.3.40}/topos/lineage/__init__.py +0 -0
  517. {topos_node-1.3.38 → topos_node-1.3.40}/topos/lineage/provenance.py +0 -0
  518. {topos_node-1.3.38 → topos_node-1.3.40}/topos/lineage/tracker.py +0 -0
  519. {topos_node-1.3.38 → topos_node-1.3.40}/topos/llm_integrations_storage.py +0 -0
  520. {topos_node-1.3.38 → topos_node-1.3.40}/topos/mcp_clients.py +0 -0
  521. {topos_node-1.3.38 → topos_node-1.3.40}/topos/observability/__init__.py +0 -0
  522. {topos_node-1.3.38 → topos_node-1.3.40}/topos/observability/alerts.py +0 -0
  523. {topos_node-1.3.38 → topos_node-1.3.40}/topos/observability/metrics.py +0 -0
  524. {topos_node-1.3.38 → topos_node-1.3.40}/topos/observability/tracing.py +0 -0
  525. {topos_node-1.3.38 → topos_node-1.3.40}/topos/openai_client.py +0 -0
  526. {topos_node-1.3.38 → topos_node-1.3.40}/topos/owner_key.py +0 -0
  527. {topos_node-1.3.38 → topos_node-1.3.40}/topos/pipeline/__init__.py +0 -0
  528. {topos_node-1.3.38 → topos_node-1.3.40}/topos/pipeline/audit.py +0 -0
  529. {topos_node-1.3.38 → topos_node-1.3.40}/topos/pipeline/envelope.py +0 -0
  530. {topos_node-1.3.38 → topos_node-1.3.40}/topos/pipeline/job_store.py +0 -0
  531. {topos_node-1.3.38 → topos_node-1.3.40}/topos/pipeline/stages.py +0 -0
  532. {topos_node-1.3.38 → topos_node-1.3.40}/topos/pipeline/stub_enqueue.py +0 -0
  533. {topos_node-1.3.38 → topos_node-1.3.40}/topos/principal.py +0 -0
  534. {topos_node-1.3.38 → topos_node-1.3.40}/topos/projections/__init__.py +0 -0
  535. {topos_node-1.3.38 → topos_node-1.3.40}/topos/projections/vector_index/__init__.py +0 -0
  536. {topos_node-1.3.38 → topos_node-1.3.40}/topos/projections/vector_index/base.py +0 -0
  537. {topos_node-1.3.38 → topos_node-1.3.40}/topos/projections/vector_index/builders.py +0 -0
  538. {topos_node-1.3.38 → topos_node-1.3.40}/topos/projections/vector_index/health_checks.py +0 -0
  539. {topos_node-1.3.38 → topos_node-1.3.40}/topos/protocol/__init__.py +0 -0
  540. {topos_node-1.3.38 → topos_node-1.3.40}/topos/protocol/narrowing_vocabulary.json +0 -0
  541. {topos_node-1.3.38 → topos_node-1.3.40}/topos/protocol/query_field_contract.json +0 -0
  542. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/__init__.py +0 -0
  543. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/audit.py +0 -0
  544. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/closeness.py +0 -0
  545. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/cohort_resolvers.py +0 -0
  546. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/collaborators.py +0 -0
  547. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/ddr.py +0 -0
  548. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/disclosure.py +0 -0
  549. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/entity_window.py +0 -0
  550. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/exclusion.py +0 -0
  551. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/facts_direct.py +0 -0
  552. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/fingerprint.py +0 -0
  553. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/game_layer.py +0 -0
  554. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/grant_cache.py +0 -0
  555. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/inference.py +0 -0
  556. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/intent.py +0 -0
  557. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/manifest.py +0 -0
  558. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/manifest_validation.py +0 -0
  559. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/minimizer.py +0 -0
  560. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/narrowing.py +0 -0
  561. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/negotiation.py +0 -0
  562. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/packet_resolution.py +0 -0
  563. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/pipeline.py +0 -0
  564. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/planner.py +0 -0
  565. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/runtime.py +0 -0
  566. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/scope_arbiter.py +0 -0
  567. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/scope_classifier.py +0 -0
  568. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/scope_head.py +0 -0
  569. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/scope_registry.json +0 -0
  570. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/scope_registry_loader.py +0 -0
  571. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/scope_shadow.py +0 -0
  572. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/session.py +0 -0
  573. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/session_utils.py +0 -0
  574. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/source_generation.py +0 -0
  575. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/truth_facts.py +0 -0
  576. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/truth_prompts.py +0 -0
  577. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/turn_classifier.py +0 -0
  578. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/types.py +0 -0
  579. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/verify.py +0 -0
  580. {topos_node-1.3.38 → topos_node-1.3.40}/topos/query/verify_modes.py +0 -0
  581. {topos_node-1.3.38 → topos_node-1.3.40}/topos/rate_limit.py +0 -0
  582. {topos_node-1.3.38 → topos_node-1.3.40}/topos/relay_stamp.py +0 -0
  583. {topos_node-1.3.38 → topos_node-1.3.40}/topos/routines/__init__.py +0 -0
  584. {topos_node-1.3.38 → topos_node-1.3.40}/topos/routines/schema.py +0 -0
  585. {topos_node-1.3.38 → topos_node-1.3.40}/topos/routines/store.py +0 -0
  586. {topos_node-1.3.38 → topos_node-1.3.40}/topos/runtime_housekeeping.py +0 -0
  587. {topos_node-1.3.38 → topos_node-1.3.40}/topos/runtime_shutdown.py +0 -0
  588. {topos_node-1.3.38 → topos_node-1.3.40}/topos/runtime_update.py +0 -0
  589. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sanitization/__init__.py +0 -0
  590. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sanitization/nsfw_classifier.py +0 -0
  591. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sanitization/ollama_transforms.py +0 -0
  592. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sanitization/prewarm.py +0 -0
  593. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sanitization/privacy_filter.py +0 -0
  594. {topos_node-1.3.38 → topos_node-1.3.40}/topos/scope_resolution.py +0 -0
  595. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/__init__.py +0 -0
  596. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/container.py +0 -0
  597. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/embeddings/__init__.py +0 -0
  598. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/embeddings/base.py +0 -0
  599. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/embeddings/local.py +0 -0
  600. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/embeddings/remote.py +0 -0
  601. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/interfaces.py +0 -0
  602. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/llm/__init__.py +0 -0
  603. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/llm/base.py +0 -0
  604. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/llm/openai.py +0 -0
  605. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/local.py +0 -0
  606. {topos_node-1.3.38 → topos_node-1.3.40}/topos/services/postgres.py +0 -0
  607. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/__init__.py +0 -0
  608. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/bundled_canonical_triples.py +0 -0
  609. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/canonical_signal_defaults.py +0 -0
  610. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/declared_field_map_spec.py +0 -0
  611. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/definitions.py +0 -0
  612. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/install_service.py +0 -0
  613. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/registry.py +0 -0
  614. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/runtime_install.py +0 -0
  615. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/scrub_attribution.py +0 -0
  616. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sources/scrub_service.py +0 -0
  617. {topos_node-1.3.38 → topos_node-1.3.40}/topos/startup_banner.py +0 -0
  618. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/__init__.py +0 -0
  619. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/__init__.py +0 -0
  620. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/factory.py +0 -0
  621. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/fakes.py +0 -0
  622. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/postgres/stores.py +0 -0
  623. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/protocols.py +0 -0
  624. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/sqlite/__init__.py +0 -0
  625. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/sqlite/stores.py +0 -0
  626. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  627. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/__init__.py +0 -0
  628. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/activity_tables.py +0 -0
  629. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  630. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  631. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/ai_chat/model.py +0 -0
  632. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/ai_chat/tables.py +0 -0
  633. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  634. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/canonical_store.py +0 -0
  635. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/conversations_tables.py +0 -0
  636. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/journal_repair.py +0 -0
  637. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/mapping_store.py +0 -0
  638. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/canonical/postgres.py +0 -0
  639. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/__init__.py +0 -0
  640. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/client.py +0 -0
  641. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/connection_tuning.py +0 -0
  642. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/__init__.py +0 -0
  643. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  644. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  645. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
  646. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  647. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  648. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/backup.py +0 -0
  649. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/backup_custody.py +0 -0
  650. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  651. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  652. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  653. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  654. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/community_names_v1.py +0 -0
  655. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/complexity_v1.py +0 -0
  656. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/conflict_provenance_v1.py +0 -0
  657. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  658. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
  659. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  660. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
  661. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/derived_row_identity_v1.py +0 -0
  662. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/documents_v1.py +0 -0
  663. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
  664. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
  665. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
  666. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
  667. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
  668. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
  669. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  670. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
  671. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
  672. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
  673. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
  674. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/episodes_v1.py +0 -0
  675. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  676. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/fact_dimension_by_entity_type_v1.py +0 -0
  677. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  678. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  679. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  680. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  681. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  682. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
  683. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/mention_table_stamp_backfill_v1.py +0 -0
  684. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
  685. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
  686. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/net_subject_policy_v1.py +0 -0
  687. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
  688. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  689. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
  690. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/registry.py +0 -0
  691. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/registry_checksums.json +0 -0
  692. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  693. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
  694. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  695. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  696. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  697. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/signal_objects.py +0 -0
  698. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  699. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  700. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
  701. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  702. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  703. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  704. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  705. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  706. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  707. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  708. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  709. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  710. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  711. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  712. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  713. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  714. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  715. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  716. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  717. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  718. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  719. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  720. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/paths.py +0 -0
  721. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/postgres.py +0 -0
  722. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/schema.py +0 -0
  723. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/schema_probe.py +0 -0
  724. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/storage_breakdown.py +0 -0
  725. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/db/write_gate.py +0 -0
  726. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/derived_row_identity.py +0 -0
  727. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/enrichment/__init__.py +0 -0
  728. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  729. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  730. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/normalized/__init__.py +0 -0
  731. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/normalized/normalized_store.py +0 -0
  732. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/oplog/__init__.py +0 -0
  733. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/oplog/decision.py +0 -0
  734. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/oplog/oplog_store.py +0 -0
  735. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/oplog/postgres.py +0 -0
  736. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/person/identity_resolver.py +0 -0
  737. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/projections/__init__.py +0 -0
  738. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/projections/index_ops_store.py +0 -0
  739. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/projections/vector_index_store.py +0 -0
  740. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/raw/__init__.py +0 -0
  741. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/raw/browser_flat_tables.py +0 -0
  742. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/raw/raw_store.py +0 -0
  743. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/raw/raw_tables_manager.py +0 -0
  744. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/raw/sqlite_raw_store.py +0 -0
  745. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/security/encryption.py +0 -0
  746. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/signal_identity.py +0 -0
  747. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/source_settings.py +0 -0
  748. {topos_node-1.3.38 → topos_node-1.3.40}/topos/storage/user_identity.py +0 -0
  749. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sync/__init__.py +0 -0
  750. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sync/client.py +0 -0
  751. {topos_node-1.3.38 → topos_node-1.3.40}/topos/sync_handlers.py +0 -0
  752. {topos_node-1.3.38 → topos_node-1.3.40}/topos/testing/__init__.py +0 -0
  753. {topos_node-1.3.38 → topos_node-1.3.40}/topos/testing/lifespan.py +0 -0
  754. {topos_node-1.3.38 → topos_node-1.3.40}/topos/uds.py +0 -0
  755. {topos_node-1.3.38 → topos_node-1.3.40}/topos/uma_contact_enrichment.py +0 -0
  756. {topos_node-1.3.38 → topos_node-1.3.40}/topos/uma_filters.py +0 -0
  757. {topos_node-1.3.38 → topos_node-1.3.40}/topos/uma_resource_id.py +0 -0
  758. {topos_node-1.3.38 → topos_node-1.3.40}/topos/uma_rpt.py +0 -0
  759. {topos_node-1.3.38 → topos_node-1.3.40}/topos/upgrades/__init__.py +0 -0
  760. {topos_node-1.3.38 → topos_node-1.3.40}/topos/upgrades/runner.py +0 -0
  761. {topos_node-1.3.38 → topos_node-1.3.40}/topos/utils/base_object.py +0 -0
  762. {topos_node-1.3.38 → topos_node-1.3.40}/topos/websocket_client.py +0 -0
  763. {topos_node-1.3.38 → topos_node-1.3.40}/topos_node.egg-info/dependency_links.txt +0 -0
  764. {topos_node-1.3.38 → topos_node-1.3.40}/topos_node.egg-info/entry_points.txt +0 -0
  765. {topos_node-1.3.38 → topos_node-1.3.40}/topos_node.egg-info/requires.txt +0 -0
  766. {topos_node-1.3.38 → topos_node-1.3.40}/topos_node.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 1.3.38
3
+ Version: 1.3.40
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
@@ -163,13 +163,13 @@ Optional:
163
163
  ### 3) Run
164
164
 
165
165
  ```bash
166
- topos-node --host 0.0.0.0 --port 9000
166
+ topos-node --host 0.0.0.0 --port 8676
167
167
  ```
168
168
 
169
169
  ### 4) Verify
170
170
 
171
171
  ```bash
172
- curl http://localhost:9000/health
172
+ curl http://localhost:8676/health
173
173
  ```
174
174
 
175
175
  ## Common Commands
@@ -96,13 +96,13 @@ Optional:
96
96
  ### 3) Run
97
97
 
98
98
  ```bash
99
- topos-node --host 0.0.0.0 --port 9000
99
+ topos-node --host 0.0.0.0 --port 8676
100
100
  ```
101
101
 
102
102
  ### 4) Verify
103
103
 
104
104
  ```bash
105
- curl http://localhost:9000/health
105
+ curl http://localhost:8676/health
106
106
  ```
107
107
 
108
108
  ## Common Commands
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "topos-node"
7
- version = "1.3.38"
7
+ version = "1.3.40"
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"
@@ -112,7 +112,7 @@ tmp_path_retention_count = 1
112
112
  tmp_path_retention_policy = "failed"
113
113
  # The DEFAULT lane is hermetic. Without this, a plain `pytest tests/` selects
114
114
  # every marker, and the three lanes below are the ones that read and WRITE the
115
- # developer's own ~/.topos/database.db or drive the node running on :9000 —
115
+ # developer's own ~/.topos/database.db or drive the node running on :8676 —
116
116
  # `tests/conftest.py::_no_live_db_guard` waives its protection for exactly these
117
117
  # markers, which only makes sense if the ordinary gate never selects them.
118
118
  # On 2026-08-19 it did: one `pytest tests/ -q` run inserted 71 rows into the
@@ -137,7 +137,7 @@ markers = [
137
137
  "public: public-safe test lane for OSS CI",
138
138
  "private: internal architecture or fixtures; excluded from public CI",
139
139
  "e2e: end-to-end tests (live Keycloak + Control Plane; require config and running CP)",
140
- "live: requires a running local engine (localhost:9000) and a real TOPOS_KEY; excluded from deterministic lanes",
140
+ "live: requires a running local engine (localhost:8676) and a real TOPOS_KEY; excluded from deterministic lanes",
141
141
  "release_pressure: iteration-4 live pressure smoke; run explicitly before releases",
142
142
  "p0: priority marker on release pressure tests",
143
143
  "retrieval_eval: dense-intelligence retrieval eval (loads local embedding model; run explicitly)",
@@ -20,6 +20,7 @@ from pathlib import Path
20
20
 
21
21
  import pytest
22
22
 
23
+ from topos.defaults import DEFAULT_NODE_PORT
23
24
  from topos.storage.db import paths
24
25
 
25
26
  pytestmark = [pytest.mark.public]
@@ -381,7 +382,7 @@ class TestSwitchPreflight:
381
382
  def _no_running_node(self, monkeypatch):
382
383
  from topos import profiles
383
384
 
384
- monkeypatch.setattr(profiles, "node_is_running", lambda port=9000: False)
385
+ monkeypatch.setattr(profiles, "node_is_running", lambda port=DEFAULT_NODE_PORT: False)
385
386
 
386
387
  def test_refuses_a_topos_from_a_newer_engine(self, tmp_path):
387
388
  from topos import profiles
@@ -22,6 +22,7 @@ from pathlib import Path
22
22
  import pytest
23
23
 
24
24
  from topos import profiles
25
+ from topos.defaults import DEFAULT_NODE_PORT
25
26
  from topos.storage.db.migrations import backup as backup_mod
26
27
 
27
28
  pytestmark = [pytest.mark.public]
@@ -70,7 +71,7 @@ def _seed_active(base: Path, *, key: str = "KEYAAA", real_db: bool = True) -> No
70
71
 
71
72
  @pytest.fixture(autouse=True)
72
73
  def _no_running_node(monkeypatch):
73
- monkeypatch.setattr(profiles, "node_is_running", lambda port=9000: False)
74
+ monkeypatch.setattr(profiles, "node_is_running", lambda port=DEFAULT_NODE_PORT: False)
74
75
 
75
76
 
76
77
  class TestArchiveIsSelfContained:
@@ -17,6 +17,7 @@ from click.testing import CliRunner
17
17
 
18
18
  from topos import profiles
19
19
  from topos.cli.profile_cmd import profile_group
20
+ from topos.defaults import DEFAULT_NODE_PORT
20
21
 
21
22
  pytestmark = [pytest.mark.public]
22
23
 
@@ -45,7 +46,7 @@ def _seed_profile(base: Path, slug: str, *, name: str | None = None, key: str =
45
46
 
46
47
  @pytest.fixture(autouse=True)
47
48
  def _no_running_node(monkeypatch):
48
- monkeypatch.setattr(profiles, "node_is_running", lambda port=9000: False)
49
+ monkeypatch.setattr(profiles, "node_is_running", lambda port=DEFAULT_NODE_PORT: False)
49
50
 
50
51
 
51
52
  class TestNewProfile:
@@ -128,7 +129,7 @@ class TestSwitchProfile:
128
129
  def test_refuses_while_node_running(self, tmp_path, monkeypatch):
129
130
  _seed_active(tmp_path)
130
131
  _seed_profile(tmp_path, "work")
131
- monkeypatch.setattr(profiles, "node_is_running", lambda port=9000: True)
132
+ monkeypatch.setattr(profiles, "node_is_running", lambda port=DEFAULT_NODE_PORT: True)
132
133
  with pytest.raises(profiles.ProfileError, match="running"):
133
134
  profiles.switch_profile("work", tmp_path)
134
135
  # Nothing moved.
@@ -328,7 +329,7 @@ class TestRemoveProfile:
328
329
  def test_does_not_require_the_node_to_be_stopped(self, tmp_path, monkeypatch):
329
330
  # An archived Topos is not the one a running engine has open, so unlike
330
331
  # new/switch this must work without asking anyone to quit Topos.
331
- monkeypatch.setattr(profiles, "node_is_running", lambda port=9000: True)
332
+ monkeypatch.setattr(profiles, "node_is_running", lambda port=DEFAULT_NODE_PORT: True)
332
333
  _seed_profile(tmp_path, "work")
333
334
 
334
335
  profiles.remove_profile("work", tmp_path)
@@ -1,6 +1,6 @@
1
1
  """Topos Control Plane Version Information."""
2
2
 
3
- __version__ = "1.3.38"
4
- __version_info__ = (1, 3, 38)
3
+ __version__ = "1.3.40"
4
+ __version_info__ = (1, 3, 40)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -0,0 +1,155 @@
1
+ from __future__ import annotations
2
+
3
+ from fastapi import APIRouter, Body, Depends, HTTPException, Request
4
+
5
+ from ..auth import require_api_key
6
+ from ..ingestion.reprocess import reprocess_source
7
+ from .ingestion_sources import ingest_source
8
+
9
+ router = APIRouter()
10
+
11
+
12
+ @router.post("/ingestion/start")
13
+ async def start_ingestion() -> dict:
14
+ return {"status": "stub"}
15
+
16
+
17
+ @router.post("/ingestion/progress")
18
+ async def report_progress() -> dict:
19
+ return {"status": "stub"}
20
+
21
+
22
+ @router.post("/ingestion/reprocess", dependencies=[Depends(require_api_key)])
23
+ async def ingestion_reprocess(payload: dict = Body(default_factory=dict)) -> dict:
24
+ """Re-run raw→canonical for a source (optional newest-N via ``limit``).
25
+
26
+ Body:
27
+ - source_id (required)
28
+ - dataset_id (required)
29
+ - from_stage: ``raw`` (default) | ``canonical``
30
+ - limit: optional int — newest N raw rows only
31
+ - run_enrichment: optional bool (default true)
32
+ - force / sync_batch_id: optional
33
+ """
34
+ try:
35
+ limit_raw = payload.get("limit")
36
+ limit = int(limit_raw) if limit_raw is not None and str(limit_raw).strip() != "" else None
37
+ return await reprocess_source(
38
+ source_id=str(payload["source_id"]),
39
+ dataset_id=str(payload["dataset_id"]),
40
+ from_stage=payload.get("from_stage") or "raw",
41
+ sync_batch_id=payload.get("sync_batch_id"),
42
+ force=bool(payload.get("force", False)),
43
+ limit=limit,
44
+ run_enrichment=bool(payload.get("run_enrichment", True)),
45
+ )
46
+ except KeyError as exc:
47
+ raise HTTPException(status_code=400, detail=f"Missing field: {exc}") from exc
48
+ except ValueError as exc:
49
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
50
+
51
+
52
+ @router.get("/ingestion/audit", dependencies=[Depends(require_api_key)])
53
+ async def get_ingestion_audit(sync_batch_id: str) -> dict:
54
+ from ..core.state import get_db_connection
55
+ from ..pipeline.audit import SQLiteIngestAuditStore
56
+
57
+ conn = get_db_connection()
58
+ if not conn:
59
+ raise HTTPException(status_code=503, detail="Database unavailable")
60
+ store = SQLiteIngestAuditStore(conn)
61
+ return {"sync_batch_id": sync_batch_id, "stages": store.query_by_batch(sync_batch_id)}
62
+
63
+
64
+ @router.post("/ingestion/upload", dependencies=[Depends(require_api_key)])
65
+ async def upload_ingestion_file(request: Request) -> dict:
66
+ return await ingest_source("chatgpt_file_ingestion", request)
67
+
68
+
69
+ @router.get("/ingestion/local-exports", dependencies=[Depends(require_api_key)])
70
+ async def list_local_exports() -> dict:
71
+ """Exports sitting on this machine, for the import screen to offer.
72
+
73
+ The node is the only party that can answer this: a browser cannot read a
74
+ filesystem, and cannot produce an absolute path even for a file the user
75
+ picks. So the node looks, and hands back opaque handles plus labels a person
76
+ can recognise -- never the paths themselves.
77
+
78
+ Bounded and stateless by construction (see ``local_exports``): a few known
79
+ folders, shallow, symlinks skipped, time-boxed, nothing written down.
80
+ """
81
+ import asyncio
82
+
83
+ from ..ingestion.local_exports import find_exports
84
+
85
+ result = await asyncio.to_thread(find_exports)
86
+ return result.as_payload()
87
+
88
+
89
+ @router.get("/ingestion/local-exports/{handle}/describe", dependencies=[Depends(require_api_key)])
90
+ async def describe_local_export(handle: str) -> dict:
91
+ """What is inside one discovered export: conversation count and date range.
92
+
93
+ Separate from discovery on purpose. Listing candidates reads only an
94
+ archive's central directory and stays in the low hundreds of milliseconds;
95
+ this opens the conversations file and parses it, which is about a second on
96
+ a 52 MB export. Paying that for every row of a scan to inform a choice about
97
+ one of them would be the wrong trade.
98
+
99
+ It exists because a window is measured against today while an export is
100
+ fixed in the past, and nothing in the UI could see the gap: a six-month
101
+ window against a fourteen-month-old export drops every conversation and
102
+ completes successfully with nothing imported.
103
+ """
104
+ import asyncio
105
+
106
+ from ..ingestion.local_exports import describe_export, resolve
107
+
108
+ path = await asyncio.to_thread(resolve, handle)
109
+ if path is None:
110
+ raise HTTPException(
111
+ status_code=404,
112
+ detail="That export is no longer where we found it. Scan again and pick it.",
113
+ )
114
+ try:
115
+ return await asyncio.to_thread(describe_export, path)
116
+ except Exception as exc: # noqa: BLE001 — a describe failure must not block the import
117
+ raise HTTPException(status_code=422, detail=f"Could not read that export: {exc}") from exc
118
+
119
+
120
+ @router.post("/ingestion/upload-local-path", dependencies=[Depends(require_api_key)])
121
+ async def upload_ingestion_local_path(
122
+ request: Request, payload: dict = Body(default_factory=dict)
123
+ ) -> dict:
124
+ """Ingest a file that is already on this machine. No bytes cross a network.
125
+
126
+ Accepts either a ``handle`` from ``/ingestion/local-exports`` -- the path
127
+ never leaves the node -- or an explicit ``file_path``, which is still how
128
+ someone points at an export outside the searched folders.
129
+ """
130
+ from ..ingestion.local_exports import resolve
131
+
132
+ dataset_id = payload.get("dataset_id")
133
+ file_path = payload.get("file_path")
134
+ handle = str(payload.get("handle") or "").strip()
135
+
136
+ if handle and not file_path:
137
+ resolved = resolve(handle)
138
+ if resolved is None:
139
+ # Handles are re-found rather than remembered, so a stale one means
140
+ # the file moved or went away -- not that the user did anything odd.
141
+ raise HTTPException(
142
+ status_code=404,
143
+ detail="That export is no longer where we found it. Scan again and pick it.",
144
+ )
145
+ file_path = str(resolved)
146
+
147
+ if not file_path:
148
+ raise HTTPException(status_code=400, detail="Provide a handle or a file_path.")
149
+
150
+ return await ingest_source(
151
+ "chatgpt_file_ingestion",
152
+ request,
153
+ dataset_id=dataset_id,
154
+ file_path=file_path,
155
+ )
@@ -12,6 +12,7 @@ import uvicorn
12
12
  # Add parent directory to path for imports
13
13
  sys.path.insert(0, str(Path(__file__).parent.parent.parent))
14
14
 
15
+ from topos.defaults import DEFAULT_NODE_PORT
15
16
  from topos.runtime_update import (
16
17
  DEFAULT_PACKAGE_NAME,
17
18
  apply_package_update,
@@ -232,8 +233,8 @@ def _maybe_offer_self_update(
232
233
  )
233
234
  @click.option(
234
235
  "--port",
235
- default=9000,
236
- help="Server port (default: 9000)",
236
+ default=DEFAULT_NODE_PORT,
237
+ help=f"Server port (default: {DEFAULT_NODE_PORT})",
237
238
  )
238
239
  @click.option(
239
240
  "--host",
@@ -17,6 +17,7 @@ from typing import Optional
17
17
  import click
18
18
 
19
19
  from topos import profiles
20
+ from topos.defaults import DEFAULT_NODE_PORT
20
21
 
21
22
 
22
23
  def _echo(payload: dict, as_json: bool, human: str) -> None:
@@ -41,7 +42,7 @@ _BASE_OPTION = click.option(
41
42
  )
42
43
  _JSON_OPTION = click.option("--json", "as_json", is_flag=True, help="Machine-readable output.")
43
44
  _PORT_OPTION = click.option(
44
- "--port", default=9000, show_default=True, help="Port probed for a running node."
45
+ "--port", default=DEFAULT_NODE_PORT, show_default=True, help="Port probed for a running node."
45
46
  )
46
47
 
47
48
 
@@ -170,6 +170,7 @@ from . import ( # noqa: F401 (imported for handler registration side effects)
170
170
  complexity,
171
171
  timeline_daily,
172
172
  graph_query,
173
+ graph_summary,
173
174
  )
174
175
 
175
176
 
@@ -0,0 +1,72 @@
1
+ """How much is in the graph — the smallest possible answer.
2
+
3
+ Why this exists rather than a count taken from ``/v1/signal/graph``: that
4
+ endpoint returns node and edge LISTS, capped at 200 and 500, and no totals. To
5
+ learn "how many" from it you would fetch rows you throw away, and still not
6
+ know the answer once the graph passed the cap.
7
+
8
+ Why not carry the number on the ingestion job instead: the progress channel is
9
+ a fixed set of columns on the control plane's ``ingestion_jobs`` table, with no
10
+ JSON field, and ``stage_event`` is filtered down to four keys. Adding it there
11
+ means a schema migration on the production database — a real cost to pay for a
12
+ reassurance line, and a change that is hard to take back.
13
+
14
+ So: three COUNT(*) queries, read on demand, owned by nothing.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import asyncio
20
+ from typing import Any, Dict, Optional
21
+
22
+ from .registry import handles
23
+
24
+
25
+ def _counts() -> Dict[str, Any]:
26
+ from ...core.state import get_db_connection
27
+
28
+ conn = get_db_connection()
29
+ if conn is None:
30
+ return {"available": False}
31
+
32
+ out: Dict[str, Any] = {"available": True}
33
+ # Each table is counted independently and a failure on one is not a failure
34
+ # of the reply: a missing table on an older node should cost that number,
35
+ # not the whole answer.
36
+ for key, table in (
37
+ ("nodes", "graph_nodes"),
38
+ ("edges", "graph_edges"),
39
+ ("entities", "entities"),
40
+ ):
41
+ try:
42
+ row = conn.execute(f"SELECT COUNT(*) FROM {table}").fetchone() # noqa: S608 — fixed names
43
+ out[key] = int(row[0]) if row else 0
44
+ except Exception: # noqa: BLE001
45
+ out[key] = None
46
+ try:
47
+ row = conn.execute(
48
+ "SELECT MAX(materialized_at) FROM graph_materialization_state"
49
+ ).fetchone()
50
+ out["materialized_at"] = row[0] if row else None
51
+ except Exception: # noqa: BLE001
52
+ out["materialized_at"] = None
53
+ return out
54
+
55
+
56
+ @handles("graph_summary")
57
+ async def handle_graph_summary(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
58
+ """Node, edge and entity counts, for a screen that wants to show growth.
59
+
60
+ The reason it is worth showing during an import: entity data lands at the
61
+ third of twenty stages and the graph is materialised twice, so these numbers
62
+ move long before the import finishes. Watching them move is the difference
63
+ between a long wait and a long wait you can see the point of.
64
+ """
65
+ req_id = message.get("id")
66
+ if not req_id:
67
+ return None
68
+ try:
69
+ payload = await asyncio.to_thread(_counts)
70
+ return {"id": req_id, "status": "ok", "payload": payload}
71
+ except Exception as exc: # noqa: BLE001
72
+ return {"id": req_id, "status": "error", "error": str(exc)}
@@ -365,6 +365,22 @@ async def handle_start_ingestion(message: Dict[str, Any]) -> Optional[Dict[str,
365
365
  file_url = payload.get("file_url")
366
366
  file_base64 = payload.get("file_base64")
367
367
  file_path = payload.get("file_path")
368
+ local_handle = str(payload.get("local_export_handle") or "").strip()
369
+ if local_handle and not file_path:
370
+ # A handle from `list_local_exports`. The path was never sent to the
371
+ # browser, so it is resolved here — and only ever to something still
372
+ # inside a searched folder, which is what makes a handle safe to accept
373
+ # back over the relay.
374
+ from ...ingestion.local_exports import resolve as _resolve_local_export
375
+
376
+ resolved = _resolve_local_export(local_handle)
377
+ if resolved is None:
378
+ return {
379
+ "id": req_id,
380
+ "status": "error",
381
+ "error": "That export is no longer where we found it. Scan again and pick it.",
382
+ }
383
+ file_path = str(resolved)
368
384
  job_id = payload.get("job_id")
369
385
  source_id = payload.get("source_id") # Optional source_id from control plane
370
386
  source_definition = payload.get("source_definition")
@@ -408,10 +424,13 @@ async def handle_start_ingestion(message: Dict[str, Any]) -> Optional[Dict[str,
408
424
  "payload": {"job_id": job_id, "status": "completed", "deduplicated": True},
409
425
  }
410
426
 
427
+ # Import-time policy chosen in the UI (date window, inclusion flags).
428
+ ingest_options = payload.get("ingest_options")
411
429
  job_payload: Dict[str, Any] = {
412
430
  "dataset_id": dataset_id or "",
413
431
  "schema_id": schema_id,
414
432
  "file_format": file_format,
433
+ "ingest_options": ingest_options if isinstance(ingest_options, dict) else None,
415
434
  "job_id": job_id,
416
435
  "source_id": source_id,
417
436
  "source_definition": source_definition,
@@ -478,6 +497,62 @@ async def handle_ingestion_reprocess(message: Dict[str, Any]) -> Optional[Dict[s
478
497
  except Exception as exc: # noqa: BLE001
479
498
  return {"id": req_id, "status": "error", "error": str(exc)}
480
499
 
500
+ @handles("list_local_exports")
501
+ async def handle_list_local_exports(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
502
+ """Exports sitting on this machine, for the import screen to offer.
503
+
504
+ Only the node can answer this. A browser cannot read a filesystem, and
505
+ cannot produce an absolute path even for a file the user picks — so without
506
+ this the only way to reach the free import path was to type one out by hand.
507
+
508
+ What comes back is opaque handles and labels a person can recognise, never
509
+ paths: the reply travels to the browser over the relay, and a home-directory
510
+ path carries the account name and whatever else lives beside it.
511
+ """
512
+ req_id = message.get("id")
513
+ if not req_id:
514
+ return None
515
+ try:
516
+ import asyncio
517
+
518
+ from ...ingestion.local_exports import find_exports
519
+
520
+ result = await asyncio.to_thread(find_exports)
521
+ return {"id": req_id, "status": "ok", "payload": result.as_payload()}
522
+ except Exception as exc: # noqa: BLE001
523
+ return {"id": req_id, "status": "error", "error": str(exc)}
524
+
525
+
526
+ @handles("describe_local_export")
527
+ async def handle_describe_local_export(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
528
+ """Conversation count and date range for one discovered export.
529
+
530
+ The window a person picks is measured from today; the export is fixed in
531
+ the past. Nothing in the UI could see that gap, so a six-month window
532
+ against a fourteen-month-old file imported nothing and said it succeeded.
533
+ This is the number that closes it, read where the dates are.
534
+ """
535
+ req_id = message.get("id")
536
+ if not req_id:
537
+ return None
538
+ payload = message.get("payload") or {}
539
+ handle = str(payload.get("handle") or "").strip()
540
+ if not handle:
541
+ return {"id": req_id, "status": "error", "error": "handle required"}
542
+ try:
543
+ import asyncio
544
+
545
+ from ...ingestion.local_exports import describe_export, resolve
546
+
547
+ path = await asyncio.to_thread(resolve, handle)
548
+ if path is None:
549
+ return {"id": req_id, "status": "error", "error": "export no longer found"}
550
+ described = await asyncio.to_thread(describe_export, path)
551
+ return {"id": req_id, "status": "ok", "payload": described}
552
+ except Exception as exc: # noqa: BLE001
553
+ return {"id": req_id, "status": "error", "error": str(exc)}
554
+
555
+
481
556
  @handles("get_ingestion_audit")
482
557
  async def handle_get_ingestion_audit(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
483
558
  req_id = message.get("id")
@@ -0,0 +1,9 @@
1
+ """Stable defaults for a local Topos node.
2
+
3
+ 8676 is TOPO on a phone keypad. Keep this the only Python source of the
4
+ listen port so CLI, probes, and the local MCP proxy cannot drift.
5
+ """
6
+
7
+ DEFAULT_NODE_PORT = 8676
8
+ DEFAULT_NODE_HTTP_URL = f"http://127.0.0.1:{DEFAULT_NODE_PORT}"
9
+ DEFAULT_NODE_LOCALHOST_URL = f"http://localhost:{DEFAULT_NODE_PORT}"
@@ -169,13 +169,36 @@ class PrivacyLayerClient:
169
169
  return {"status": "failed", "error": str(last_exc), "items": []}
170
170
 
171
171
 
172
+ # Names for the two model passes below. They are reported to the caller's
173
+ # progress callback and surface verbatim in the UI, so they are written for a
174
+ # person watching an import rather than for a log grep.
175
+ #
176
+ # "Filtering private information" rather than "checking for private details":
177
+ # this pass does not merely look. It detects PII spans and REDACTS them into
178
+ # the disclosure copy, which is the whole point of the layer — the node is
179
+ # preparing what it can safely show. A name that says "checking" describes an
180
+ # inspection and undersells the thing the product actually does for you.
181
+ PRIVACY_STAGE_REDACT = "filtering private information"
182
+ PRIVACY_STAGE_NSFW = "checking for sensitive content"
183
+
184
+ # How many records to send per call. NOT a throughput choice: both engine
185
+ # backends (redact_privacy_batch, classify_nsfw_batch) loop over `items` one at
186
+ # a time, so grouping 32 records buys no batched inference -- it is purely
187
+ # transport. The only thing the group size decides is how often progress can
188
+ # move. Measured on a live import: ~3.75s per record on CPU, so a group of 32
189
+ # meant the bar stepped once every two minutes and read as frozen; at 4 it
190
+ # moves about every fifteen seconds. The per-call overhead is a dict and a
191
+ # thread hop against ~15s of model work.
192
+ PRIVACY_PROGRESS_CHUNK = 4
193
+
194
+
172
195
  async def run_privacy_disclosure_layer(
173
196
  conn,
174
197
  canonical_messages: List[Dict[str, Any]],
175
198
  *,
176
199
  source_group: Optional[str] = None,
177
200
  client: Optional[PrivacyLayerClient] = None,
178
- progress_callback: Optional[Callable[[int, int], None]] = None,
201
+ progress_callback: Optional[Callable[[int, int, str], None]] = None,
179
202
  nsfw_only: bool = False,
180
203
  ) -> Dict[str, Any]:
181
204
  """Mandatory post-canonical Platform Privacy Layer: PII disclosure + NSFW tags.
@@ -242,7 +265,7 @@ async def run_privacy_disclosure_layer(
242
265
  table = canonical_table_for_message(msg, source_group=source_group)
243
266
  if not table:
244
267
  if progress_callback:
245
- progress_callback(idx + 1, total)
268
+ progress_callback(idx + 1, total, PRIVACY_STAGE_REDACT)
246
269
  continue
247
270
  record_id = (
248
271
  msg.get("message_id")
@@ -252,7 +275,7 @@ async def run_privacy_disclosure_layer(
252
275
  )
253
276
  if not record_id:
254
277
  if progress_callback:
255
- progress_callback(idx + 1, total)
278
+ progress_callback(idx + 1, total, PRIVACY_STAGE_REDACT)
256
279
  continue
257
280
  record_id = str(record_id)
258
281
  for field in fields_for_table(table):
@@ -284,10 +307,24 @@ async def run_privacy_disclosure_layer(
284
307
 
285
308
  from ..sanitization.privacy_filter import PRIVACY_DISCLOSE_MAX_BATCH
286
309
 
287
- for i in range(0, len(flat_pending), PRIVACY_DISCLOSE_MAX_BATCH):
288
- batch = flat_pending[i : i + PRIVACY_DISCLOSE_MAX_BATCH]
310
+ # Report against the batched work, not the message list: this loop is
311
+ # where the model time goes, and the old callback fired only on the
312
+ # branches that SKIP a message -- so a run with nothing to skip
313
+ # reported nothing at all, for its entire duration.
314
+ _redact_total = len(flat_pending)
315
+ _redact_done = 0
316
+ _redact_chunk = min(PRIVACY_DISCLOSE_MAX_BATCH, PRIVACY_PROGRESS_CHUNK)
317
+ for i in range(0, len(flat_pending), _redact_chunk):
318
+ batch = flat_pending[i : i + _redact_chunk]
289
319
  items = [{"id": e["batch_key"], "text": e["raw"]} for e in batch]
320
+ if progress_callback:
321
+ progress_callback(_redact_done, _redact_total, PRIVACY_STAGE_REDACT)
290
322
  result = await privacy_client.redact_batch(items)
323
+ _redact_done += len(batch)
324
+ # Also after: without this the final group never reports, and the
325
+ # stage appears to stop one group short of its own total.
326
+ if progress_callback:
327
+ progress_callback(_redact_done, _redact_total, PRIVACY_STAGE_REDACT)
291
328
  if result.get("status") in ("unavailable", "failed"):
292
329
  failed_batches += 1
293
330
  logger.warning(
@@ -349,10 +386,18 @@ async def run_privacy_disclosure_layer(
349
386
  from ..sanitization.nsfw_classifier import NSFW_CLASSIFY_MAX_BATCH
350
387
 
351
388
  nsfw_items = list(nsfw_pending.items())
352
- for i in range(0, len(nsfw_items), NSFW_CLASSIFY_MAX_BATCH):
353
- batch = nsfw_items[i : i + NSFW_CLASSIFY_MAX_BATCH]
389
+ _nsfw_total = len(nsfw_items)
390
+ _nsfw_done = 0
391
+ _nsfw_chunk = min(NSFW_CLASSIFY_MAX_BATCH, PRIVACY_PROGRESS_CHUNK)
392
+ for i in range(0, len(nsfw_items), _nsfw_chunk):
393
+ batch = nsfw_items[i : i + _nsfw_chunk]
354
394
  items = [{"id": key, "text": entry["text"]} for key, entry in batch]
395
+ if progress_callback:
396
+ progress_callback(_nsfw_done, _nsfw_total, PRIVACY_STAGE_NSFW)
355
397
  nsfw_result = await privacy_client.classify_nsfw_batch(items)
398
+ _nsfw_done += len(batch)
399
+ if progress_callback:
400
+ progress_callback(_nsfw_done, _nsfw_total, PRIVACY_STAGE_NSFW)
356
401
  if nsfw_result.get("status") in ("failed",):
357
402
  nsfw_failed_batches += 1
358
403
  continue