topos-node 1.5.3__tar.gz → 1.5.4__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 (915) hide show
  1. {topos_node-1.5.3/topos_node.egg-info → topos_node-1.5.4}/PKG-INFO +1 -1
  2. {topos_node-1.5.3 → topos_node-1.5.4}/pyproject.toml +1 -1
  3. {topos_node-1.5.3 → topos_node-1.5.4}/topos/__version__.py +2 -2
  4. {topos_node-1.5.3 → topos_node-1.5.4}/topos/app.py +21 -7
  5. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/commands.py +4 -1
  6. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/tray.py +10 -1
  7. {topos_node-1.5.3 → topos_node-1.5.4}/topos/control_plane_client.py +31 -1
  8. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/registration.py +8 -2
  9. topos_node-1.5.4/topos/node_stop.py +272 -0
  10. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_generation.py +1 -1
  11. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_protocol.py +103 -5
  12. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_release.py +27 -7
  13. topos_node-1.5.4/topos/permissions_v2/common_given_names.py +105 -0
  14. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/entity_boundary.py +386 -13
  15. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/knowledge_contract.py +14 -4
  16. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/runtime.py +21 -1
  17. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_index.py +106 -8
  18. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_release.py +12 -5
  19. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/job_runner.py +58 -5
  20. {topos_node-1.5.3 → topos_node-1.5.4}/topos/runtime_shutdown.py +9 -4
  21. {topos_node-1.5.3 → topos_node-1.5.4}/topos/upgrades/manifests.json +11 -0
  22. {topos_node-1.5.3 → topos_node-1.5.4/topos_node.egg-info}/PKG-INFO +1 -1
  23. {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/SOURCES.txt +2 -0
  24. {topos_node-1.5.3 → topos_node-1.5.4}/LICENSE +0 -0
  25. {topos_node-1.5.3 → topos_node-1.5.4}/MANIFEST.in +0 -0
  26. {topos_node-1.5.3 → topos_node-1.5.4}/README.md +0 -0
  27. {topos_node-1.5.3 → topos_node-1.5.4}/setup.cfg +0 -0
  28. {topos_node-1.5.3 → topos_node-1.5.4}/shared/__init__.py +0 -0
  29. {topos_node-1.5.3 → topos_node-1.5.4}/shared/filtering.py +0 -0
  30. {topos_node-1.5.3 → topos_node-1.5.4}/shared/schema_registry.py +0 -0
  31. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_active_database_binding.py +0 -0
  32. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_active_ingestion_binding.py +0 -0
  33. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_app_relay_wiring.py +0 -0
  34. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_extensions.py +0 -0
  35. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_gate_leg_hermeticity.py +0 -0
  36. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_hub_pipeline_offline_first.py +0 -0
  37. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_lane_shards.py +0 -0
  38. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_llm_integrations_storage.py +0 -0
  39. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_local_gate_composition.py +0 -0
  40. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_owner_database_hermeticity.py +0 -0
  41. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_prewarm_first_run.py +0 -0
  42. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_profile_hygiene.py +0 -0
  43. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_profiles.py +0 -0
  44. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_protocol_handled_types.py +0 -0
  45. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_query_field_contract.py +0 -0
  46. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_sync_dep_pins.py +0 -0
  47. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_system_computer_name.py +0 -0
  48. {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_topos_home_hermeticity.py +0 -0
  49. {topos_node-1.5.3 → topos_node-1.5.4}/topos/__init__.py +0 -0
  50. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/__init__.py +0 -0
  51. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/dataset_resolution.py +0 -0
  52. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/duckdb_adapter.py +0 -0
  53. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/luck_surface.py +0 -0
  54. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_communities.py +0 -0
  55. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_directed.py +0 -0
  56. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_graph.py +0 -0
  57. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_labels.py +0 -0
  58. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/person_graph.py +0 -0
  59. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/person_overlay.py +0 -0
  60. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/profiles.py +0 -0
  61. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/query_engine.py +0 -0
  62. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/raw_queries.py +0 -0
  63. {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/relationship_reads.py +0 -0
  64. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/__init__.py +0 -0
  65. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/analytics.py +0 -0
  66. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/app_registry.py +0 -0
  67. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/backup.py +0 -0
  68. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/community_naming_config.py +0 -0
  69. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/compute_remote.py +0 -0
  70. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/connected_apps.py +0 -0
  71. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/conversation_context.py +0 -0
  72. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/data_commit.py +0 -0
  73. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/data_explorer_table_prefs.py +0 -0
  74. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/database_explorer.py +0 -0
  75. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/db.py +0 -0
  76. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/device.py +0 -0
  77. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/disk_space_config.py +0 -0
  78. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/engine_run.py +0 -0
  79. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/enrichment.py +0 -0
  80. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/enrichment_lab.py +0 -0
  81. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/facts_llm_config.py +0 -0
  82. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/filter_lab.py +0 -0
  83. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/health.py +0 -0
  84. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/home_chat.py +0 -0
  85. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ingestion_api.py +0 -0
  86. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ingestion_compat.py +0 -0
  87. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ingestion_sources.py +0 -0
  88. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/intelligence_lifecycle.py +0 -0
  89. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/llm.py +0 -0
  90. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/local_mcp.py +0 -0
  91. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/messenger_analytics.py +0 -0
  92. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/nsfw_maintenance.py +0 -0
  93. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_ai_chat_capture.py +0 -0
  94. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_capture_receipts.py +0 -0
  95. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_identity.py +0 -0
  96. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_ingestion.py +0 -0
  97. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_native_probe.py +0 -0
  98. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_search_maintenance.py +0 -0
  99. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_source_installs.py +0 -0
  100. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/privacy_disclose.py +0 -0
  101. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/query_api.py +0 -0
  102. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/runtime_bootstrap.py +0 -0
  103. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sanitization_ollama_config.py +0 -0
  104. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/shell.py +0 -0
  105. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/signal.py +0 -0
  106. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/signal_extraction_config.py +0 -0
  107. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/source_install.py +0 -0
  108. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/source_retention.py +0 -0
  109. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/source_scrub.py +0 -0
  110. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sources.py +0 -0
  111. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sources_overview.py +0 -0
  112. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sync.py +0 -0
  113. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/tool_index.py +0 -0
  114. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ui_config.py +0 -0
  115. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/upgrades.py +0 -0
  116. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/usage.py +0 -0
  117. {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/user_identity.py +0 -0
  118. {topos_node-1.5.3 → topos_node-1.5.4}/topos/auth.py +0 -0
  119. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/__init__.py +0 -0
  120. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/declared_field_map.py +0 -0
  121. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/__init__.py +0 -0
  122. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/base.py +0 -0
  123. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  124. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  125. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  126. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  127. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  128. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  129. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  130. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  131. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/transcript_mapper.py +0 -0
  132. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/models.py +0 -0
  133. {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/resolver.py +0 -0
  134. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/__init__.py +0 -0
  135. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/__main__.py +0 -0
  136. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/assets/topos_black.png +0 -0
  137. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/assets/topos_blk_rounded.png +0 -0
  138. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/assets/topos_white.png +0 -0
  139. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/profile_cmd.py +0 -0
  140. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/reprocess_cmd.py +0 -0
  141. {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/setup_models_cmd.py +0 -0
  142. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/__init__.py +0 -0
  143. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/conversation_context_llm.py +0 -0
  144. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/facts_llm.py +0 -0
  145. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/local_model_builds.py +0 -0
  146. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/model_packs.py +0 -0
  147. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/node_function_providers.py +0 -0
  148. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/sanitization_ollama.py +0 -0
  149. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/settings.py +0 -0
  150. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/signal_extraction.py +0 -0
  151. {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/uvicorn_logging.json +0 -0
  152. {topos_node-1.5.3 → topos_node-1.5.4}/topos/contacts/__init__.py +0 -0
  153. {topos_node-1.5.3 → topos_node-1.5.4}/topos/contacts/identity.py +0 -0
  154. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/__init__.py +0 -0
  155. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/api_models.py +0 -0
  156. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/connection_resilience.py +0 -0
  157. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/db_health.py +0 -0
  158. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/device_helpers.py +0 -0
  159. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/errors.py +0 -0
  160. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/events.py +0 -0
  161. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/__init__.py +0 -0
  162. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/aggregate.py +0 -0
  163. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/common.py +0 -0
  164. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/complexity.py +0 -0
  165. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/config.py +0 -0
  166. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/contacts_import.py +0 -0
  167. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/database_explorer.py +0 -0
  168. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/derivation.py +0 -0
  169. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/device.py +0 -0
  170. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/enrichment.py +0 -0
  171. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/enrichment_lab.py +0 -0
  172. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/filter_lab.py +0 -0
  173. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/graph_query.py +0 -0
  174. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/graph_summary.py +0 -0
  175. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/home_chat.py +0 -0
  176. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/ingest.py +0 -0
  177. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/mcp_client_elevations.py +0 -0
  178. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/mcp_clients.py +0 -0
  179. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/messages.py +0 -0
  180. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/messenger_analytics.py +0 -0
  181. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2.py +0 -0
  182. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_bind.py +0 -0
  183. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_identity.py +0 -0
  184. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_ingestion.py +0 -0
  185. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_owner.py +0 -0
  186. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_release.py +0 -0
  187. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/query.py +0 -0
  188. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/registry.py +0 -0
  189. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/routines.py +0 -0
  190. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/signal_features.py +0 -0
  191. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/sources.py +0 -0
  192. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/timeline_daily.py +0 -0
  193. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/tool_index.py +0 -0
  194. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/logging.py +0 -0
  195. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/metrics.py +0 -0
  196. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/routine_access.py +0 -0
  197. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/startup_banner.py +0 -0
  198. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/state.py +0 -0
  199. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/table_layers.py +0 -0
  200. {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/types.py +0 -0
  201. {topos_node-1.5.3 → topos_node-1.5.4}/topos/data_explorer_row_delete.py +0 -0
  202. {topos_node-1.5.3 → topos_node-1.5.4}/topos/data_explorer_table_prefs.py +0 -0
  203. {topos_node-1.5.3 → topos_node-1.5.4}/topos/data_explorer_tables.py +0 -0
  204. {topos_node-1.5.3 → topos_node-1.5.4}/topos/defaults.py +0 -0
  205. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/__init__.py +0 -0
  206. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/canonical_writer.py +0 -0
  207. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/content_policy.py +0 -0
  208. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/disclosure_sweep.py +0 -0
  209. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/field_registry.py +0 -0
  210. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/nsfw_tags.py +0 -0
  211. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/privacy_layer.py +0 -0
  212. {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/tier.py +0 -0
  213. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/__init__.py +0 -0
  214. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/__init__.py +0 -0
  215. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/base.py +0 -0
  216. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/generative_prompts.py +0 -0
  217. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/generative_response.py +0 -0
  218. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/huggingface.py +0 -0
  219. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/ollama.py +0 -0
  220. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/openai.py +0 -0
  221. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/openai_compatible.py +0 -0
  222. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/redpill.py +0 -0
  223. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/stub.py +0 -0
  224. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/client.py +0 -0
  225. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/disk_space.py +0 -0
  226. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/engine.py +0 -0
  227. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/hosted_llm_wallet.py +0 -0
  228. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/intake.py +0 -0
  229. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/memory_utils.py +0 -0
  230. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/model_cache.py +0 -0
  231. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/model_manager.py +0 -0
  232. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_install.py +0 -0
  233. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_pull.py +0 -0
  234. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_runtime.py +0 -0
  235. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_setup_guidance.py +0 -0
  236. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/pipeline_memory.py +0 -0
  237. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/queue_manager.py +0 -0
  238. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/result_formatter.py +0 -0
  239. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/router.py +0 -0
  240. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/scoped_token.py +0 -0
  241. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/tasks.py +0 -0
  242. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/torch_runtime.py +0 -0
  243. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/transport.py +0 -0
  244. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/usage_guard.py +0 -0
  245. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/usage_observation.py +0 -0
  246. {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/validator.py +0 -0
  247. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/__init__.py +0 -0
  248. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/catalog.py +0 -0
  249. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/derivation_recovery.py +0 -0
  250. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/derived_tables.py +0 -0
  251. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/job_readiness.py +0 -0
  252. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/job_writer.py +0 -0
  253. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/__init__.py +0 -0
  254. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/base.py +0 -0
  255. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  256. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  257. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  258. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  259. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  260. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  261. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
  262. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
  263. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/derived_object_embeddings_job.py +0 -0
  264. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  265. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  266. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  267. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  268. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  269. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  270. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  271. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  272. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  273. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  274. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  275. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  276. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  277. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/__init__.py +0 -0
  278. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  279. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/language_job.py +0 -0
  280. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  281. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  282. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/model_overrides.py +0 -0
  283. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/__init__.py +0 -0
  284. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/manager.py +0 -0
  285. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/mvp_defaults.py +0 -0
  286. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/registry.py +0 -0
  287. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/versioning.py +0 -0
  288. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/orchestrator.py +0 -0
  289. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/pipeline_activity.py +0 -0
  290. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/processor.py +0 -0
  291. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/progress_bar.py +0 -0
  292. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/record_progress.py +0 -0
  293. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/registry_contract.py +0 -0
  294. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/signal_derivation_config.json +0 -0
  295. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/source_overrides.py +0 -0
  296. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/__init__.py +0 -0
  297. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/bundles.py +0 -0
  298. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/model_resolve.py +0 -0
  299. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/schema.py +0 -0
  300. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/service.py +0 -0
  301. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/store.py +0 -0
  302. {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/worker.py +0 -0
  303. {topos_node-1.5.3 → topos_node-1.5.4}/topos/evals/__init__.py +0 -0
  304. {topos_node-1.5.3 → topos_node-1.5.4}/topos/evals/enrichment_eval.py +0 -0
  305. {topos_node-1.5.3 → topos_node-1.5.4}/topos/extensions.py +0 -0
  306. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/__init__.py +0 -0
  307. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/canonical.py +0 -0
  308. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/engine.py +0 -0
  309. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/entropy.py +0 -0
  310. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/focus.py +0 -0
  311. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/graph_metrics.py +0 -0
  312. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/influence.py +0 -0
  313. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/projection.py +0 -0
  314. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/snapshots.py +0 -0
  315. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/store.py +0 -0
  316. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/topic_merge.py +0 -0
  317. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/topics.py +0 -0
  318. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/topics_daily.py +0 -0
  319. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/volatility.py +0 -0
  320. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/__init__.py +0 -0
  321. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
  322. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
  323. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +0 -0
  324. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
  325. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
  326. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
  327. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
  328. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
  329. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
  330. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
  331. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
  332. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
  333. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
  334. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/health.mental.yaml +0 -0
  335. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
  336. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
  337. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
  338. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
  339. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
  340. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
  341. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/net.capability.yaml +0 -0
  342. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/net.character.yaml +0 -0
  343. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/obligations.commitments.yaml +0 -0
  344. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
  345. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/places.mobility.yaml +0 -0
  346. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
  347. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
  348. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
  349. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
  350. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
  351. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
  352. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
  353. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
  354. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
  355. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
  356. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
  357. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/work.career.yaml +0 -0
  358. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/candidates.py +0 -0
  359. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/commitments.py +0 -0
  360. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/guard.py +0 -0
  361. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/kernels.py +0 -0
  362. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/net_subject_policy.py +0 -0
  363. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/packs.py +0 -0
  364. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/person_bridge.py +0 -0
  365. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/person_reading.py +0 -0
  366. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/prefilter.py +0 -0
  367. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/registry.py +0 -0
  368. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/report_card.py +0 -0
  369. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/router.py +0 -0
  370. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/social_bench.py +0 -0
  371. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/social_kernels.py +0 -0
  372. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/surfaces.py +0 -0
  373. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/synthesize.py +0 -0
  374. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/template.py +0 -0
  375. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/verify.py +0 -0
  376. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/writer.py +0 -0
  377. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/__init__.py +0 -0
  378. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/affinity.py +0 -0
  379. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/affinity_owner.py +0 -0
  380. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/affinity_quality.py +0 -0
  381. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/chatgpt_declared.py +0 -0
  382. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/community_names.py +0 -0
  383. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/community_naming.py +0 -0
  384. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/consolidation.py +0 -0
  385. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/context_vectors.py +0 -0
  386. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/cypher.py +0 -0
  387. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/declared_mappings.py +0 -0
  388. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/discourse_graph.py +0 -0
  389. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/dossier.py +0 -0
  390. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/edges.py +0 -0
  391. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/fact_materializer.py +0 -0
  392. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_enrichers.py +0 -0
  393. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_inputs.py +0 -0
  394. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_refresh.py +0 -0
  395. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_search.py +0 -0
  396. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/linking.py +0 -0
  397. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/maintenance.py +0 -0
  398. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/mention_lineage.py +0 -0
  399. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/mention_lineage_lane.py +0 -0
  400. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/owner.py +0 -0
  401. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/reads.py +0 -0
  402. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/rebuild_subprocess.py +0 -0
  403. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/resolver.py +0 -0
  404. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/structured_fields.py +0 -0
  405. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/__init__.py +0 -0
  406. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/evidence_time.py +0 -0
  407. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/extract.py +0 -0
  408. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/llm_extract.py +0 -0
  409. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/reactions.py +0 -0
  410. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/reads.py +0 -0
  411. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/store.py +0 -0
  412. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/verdicts.py +0 -0
  413. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/fit/evaluator.py +0 -0
  414. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/fit/opportunity_types.json +0 -0
  415. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/__init__.py +0 -0
  416. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole.py +0 -0
  417. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole_guard.py +0 -0
  418. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole_llm.py +0 -0
  419. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
  420. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/carry_diagnosis.py +0 -0
  421. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/contact_excludes.py +0 -0
  422. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/derived_scrub.py +0 -0
  423. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/exclusions.py +0 -0
  424. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/gc.py +0 -0
  425. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/off_limits_list.py +0 -0
  426. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/off_limits_view.py +0 -0
  427. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/record_protection.py +0 -0
  428. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/__init__.py +0 -0
  429. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/posture.py +0 -0
  430. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/roles.py +0 -0
  431. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/writer_class.py +0 -0
  432. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/__init__.py +0 -0
  433. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_canonical_loader.py +0 -0
  434. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_ontology.py +0 -0
  435. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_renderer.py +0 -0
  436. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_schemas.py +0 -0
  437. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/chunking.py +0 -0
  438. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/cluster_labels.py +0 -0
  439. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/conversation_context.py +0 -0
  440. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/conversation_windows.py +0 -0
  441. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/data_health.py +0 -0
  442. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  443. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/intentions.json +0 -0
  444. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/interests.json +0 -0
  445. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/memory.json +0 -0
  446. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/places.json +0 -0
  447. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/profile.json +0 -0
  448. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/relationships.json +0 -0
  449. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/resources.json +0 -0
  450. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  451. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/time.json +0 -0
  452. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/wellbeing.json +0 -0
  453. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/work.json +0 -0
  454. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/derived_index.py +0 -0
  455. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/derived_spec.py +0 -0
  456. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_briefs.py +0 -0
  457. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_definition_loader.py +0 -0
  458. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_profiles.py +0 -0
  459. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_registry.py +0 -0
  460. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/embed_context.py +0 -0
  461. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/extraction/artifact_router.py +0 -0
  462. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/extraction/artifact_store.py +0 -0
  463. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/extraction/rule_extractors.py +0 -0
  464. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/graph_sanitize.py +0 -0
  465. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/hybrid_search.py +0 -0
  466. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/incremental_clustering.py +0 -0
  467. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/model_recommendations.py +0 -0
  468. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/query_embed_cache.py +0 -0
  469. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/schemas.py +0 -0
  470. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/service.py +0 -0
  471. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/signal_object_store.py +0 -0
  472. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/source_hydration.py +0 -0
  473. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/structured_signal.py +0 -0
  474. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/tool_index.py +0 -0
  475. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/topic_clustering.py +0 -0
  476. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/aggregates.py +0 -0
  477. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/commitments.py +0 -0
  478. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/rhythm.py +0 -0
  479. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  480. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/vector_codec.py +0 -0
  481. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/vector_math.py +0 -0
  482. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/vector_settings.py +0 -0
  483. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/__init__.py +0 -0
  484. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/definitions.py +0 -0
  485. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/engine.py +0 -0
  486. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/fold.py +0 -0
  487. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/insights.py +0 -0
  488. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/temporal/__init__.py +0 -0
  489. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/temporal/points.py +0 -0
  490. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/temporal/records.py +0 -0
  491. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/timeline_projection.py +0 -0
  492. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/timeline_rollup.py +0 -0
  493. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/__init__.py +0 -0
  494. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/badges.py +0 -0
  495. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/daily.py +0 -0
  496. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/dashboard.py +0 -0
  497. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/instruments.py +0 -0
  498. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/intents.py +0 -0
  499. {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/readiness.py +0 -0
  500. {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/__init__.py +0 -0
  501. {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/bundles.py +0 -0
  502. {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/schema.py +0 -0
  503. {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/service.py +0 -0
  504. {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/store.py +0 -0
  505. {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/worker.py +0 -0
  506. {topos_node-1.5.3 → topos_node-1.5.4}/topos/home_chat/__init__.py +0 -0
  507. {topos_node-1.5.3 → topos_node-1.5.4}/topos/home_chat/schema.py +0 -0
  508. {topos_node-1.5.3 → topos_node-1.5.4}/topos/home_chat/store.py +0 -0
  509. {topos_node-1.5.3 → topos_node-1.5.4}/topos/hosted_pool_lease.py +0 -0
  510. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/__init__.py +0 -0
  511. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/canonical_pipeline.py +0 -0
  512. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/chatgpt_owner_snapshot.py +0 -0
  513. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/checkpoints/__init__.py +0 -0
  514. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  515. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  516. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/imessage_attributed_text.py +0 -0
  517. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/inbox_crypto.py +0 -0
  518. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/inbox_drain.py +0 -0
  519. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/ingest_helpers.py +0 -0
  520. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/jobs.py +0 -0
  521. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/journal_location_fanout.py +0 -0
  522. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/journal_time_log_normalize.py +0 -0
  523. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_exports.py +0 -0
  524. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_sync.py +0 -0
  525. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_sync_jobs.py +0 -0
  526. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_sync_schedule.py +0 -0
  527. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/log_preview.py +0 -0
  528. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/manager.py +0 -0
  529. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/owner_snapshot.py +0 -0
  530. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parser.py +0 -0
  531. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/__init__.py +0 -0
  532. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/base.py +0 -0
  533. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/browser_parser.py +0 -0
  534. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/calendar_parser.py +0 -0
  535. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  536. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/chatgpt_export.py +0 -0
  537. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  538. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  539. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/documents_parser.py +0 -0
  540. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  541. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  542. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/grok_parser.py +0 -0
  543. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/messenger_parser.py +0 -0
  544. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/transcript_parser.py +0 -0
  545. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  546. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/progress.py +0 -0
  547. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/reprocess.py +0 -0
  548. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/__init__.py +0 -0
  549. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/base.py +0 -0
  550. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/calendar.py +0 -0
  551. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/chatgpt.py +0 -0
  552. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/contact_importers.py +0 -0
  553. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/grok.py +0 -0
  554. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/imessage_reader.py +0 -0
  555. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/signal_export_parser.py +0 -0
  556. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/signal_reader.py +0 -0
  557. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/state_machine.py +0 -0
  558. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/triggers/__init__.py +0 -0
  559. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/triggers/file_trigger.py +0 -0
  560. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  561. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  562. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/__init__.py +0 -0
  563. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/base.py +0 -0
  564. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/schema_registry.py +0 -0
  565. {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/schema_validator.py +0 -0
  566. {topos_node-1.5.3 → topos_node-1.5.4}/topos/lineage/__init__.py +0 -0
  567. {topos_node-1.5.3 → topos_node-1.5.4}/topos/lineage/provenance.py +0 -0
  568. {topos_node-1.5.3 → topos_node-1.5.4}/topos/lineage/tracker.py +0 -0
  569. {topos_node-1.5.3 → topos_node-1.5.4}/topos/llm_integrations_storage.py +0 -0
  570. {topos_node-1.5.3 → topos_node-1.5.4}/topos/mcp_clients.py +0 -0
  571. {topos_node-1.5.3 → topos_node-1.5.4}/topos/mcp_stdio_proxy.py +0 -0
  572. {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/__init__.py +0 -0
  573. {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/alerts.py +0 -0
  574. {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/metrics.py +0 -0
  575. {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/tracing.py +0 -0
  576. {topos_node-1.5.3 → topos_node-1.5.4}/topos/openai_client.py +0 -0
  577. {topos_node-1.5.3 → topos_node-1.5.4}/topos/owner_key.py +0 -0
  578. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/__init__.py +0 -0
  579. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ai_chat_capture.py +0 -0
  580. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_checks.py +0 -0
  581. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_gate.py +0 -0
  582. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_transport.py +0 -0
  583. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/automatic_message_review.py +0 -0
  584. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/automatic_review_worker.py +0 -0
  585. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/bind_protocol.py +0 -0
  586. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/canonical.py +0 -0
  587. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/canonical_floor.py +0 -0
  588. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/capture_receipts.py +0 -0
  589. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/chatgpt_coverage.py +0 -0
  590. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/checking_model.py +0 -0
  591. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/contract.py +0 -0
  592. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/english_short_words.py +0 -0
  593. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/entailment_grounding.py +0 -0
  594. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence.py +0 -0
  595. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_families.py +0 -0
  596. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_review_runtime.py +0 -0
  597. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_reviews.py +0 -0
  598. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_time.py +0 -0
  599. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/exclusion_floor.py +0 -0
  600. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_contract.py +0 -0
  601. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_eligibility.py +0 -0
  602. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_policy.py +0 -0
  603. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_projection.py +0 -0
  604. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/forwarding.py +0 -0
  605. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity.py +0 -0
  606. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity_attestation.py +0 -0
  607. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity_dispatch.py +0 -0
  608. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity_protocol.py +0 -0
  609. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/imessage_reconciliation.py +0 -0
  610. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/imessage_standing.py +0 -0
  611. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/index_rebuilds.py +0 -0
  612. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/index_review_guard.py +0 -0
  613. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/inferred_facts.py +0 -0
  614. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_dispatch.py +0 -0
  615. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_protocol.py +0 -0
  616. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_provenance.py +0 -0
  617. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_snapshot_facts.py +0 -0
  618. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_family.py +0 -0
  619. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_index.py +0 -0
  620. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_relabel.py +0 -0
  621. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_review.py +0 -0
  622. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/journal_goal_field.py +0 -0
  623. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/knowledge_projections.py +0 -0
  624. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ledger.py +0 -0
  625. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ledger_retention.py +0 -0
  626. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/message_evidence.py +0 -0
  627. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/message_review_contract.py +0 -0
  628. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/native_claim_grounding.py +0 -0
  629. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/native_imessage_probe.py +0 -0
  630. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/node_protocol.py +0 -0
  631. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/opaque_ids.py +0 -0
  632. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ownership.py +0 -0
  633. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/permitted_derivation.py +0 -0
  634. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/predicate_classes.py +0 -0
  635. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/projection_review_runtime.py +0 -0
  636. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/projection_reviews.py +0 -0
  637. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/protection_clock.py +0 -0
  638. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/protection_doorbell.py +0 -0
  639. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/protocol.py +0 -0
  640. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/reconciliation_facts.py +0 -0
  641. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/reconciliation_provenance.py +0 -0
  642. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/refresh_loop.py +0 -0
  643. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/registry.py +0 -0
  644. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/release.py +0 -0
  645. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_contract.py +0 -0
  646. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_lanes.py +0 -0
  647. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_timing.py +0 -0
  648. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_transport.py +0 -0
  649. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/self_bind.py +0 -0
  650. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/shadow_labeler_local.py +0 -0
  651. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/shadow_rubric.pinned.md +0 -0
  652. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_catalog.py +0 -0
  653. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_counts.py +0 -0
  654. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_kinds.py +0 -0
  655. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_week.py +0 -0
  656. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/signing.py +0 -0
  657. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/snapshot_message_facts.py +0 -0
  658. {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/switches.py +0 -0
  659. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/__init__.py +0 -0
  660. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/audit.py +0 -0
  661. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/envelope.py +0 -0
  662. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/job_secrets.py +0 -0
  663. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/job_store.py +0 -0
  664. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/stages.py +0 -0
  665. {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/stub_enqueue.py +0 -0
  666. {topos_node-1.5.3 → topos_node-1.5.4}/topos/principal.py +0 -0
  667. {topos_node-1.5.3 → topos_node-1.5.4}/topos/profiles.py +0 -0
  668. {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/__init__.py +0 -0
  669. {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/__init__.py +0 -0
  670. {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/base.py +0 -0
  671. {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/builders.py +0 -0
  672. {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/health_checks.py +0 -0
  673. {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/__init__.py +0 -0
  674. {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/handled_message_types.json +0 -0
  675. {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/narrowing_vocabulary.json +0 -0
  676. {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/query_field_contract.json +0 -0
  677. {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/retrieval_text_contract.json +0 -0
  678. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/__init__.py +0 -0
  679. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/aggregate.py +0 -0
  680. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/audit.py +0 -0
  681. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/closeness.py +0 -0
  682. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/collaborators.py +0 -0
  683. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/ddr.py +0 -0
  684. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/disclosure.py +0 -0
  685. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/entity_window.py +0 -0
  686. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/exclusion.py +0 -0
  687. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/facts_direct.py +0 -0
  688. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/fingerprint.py +0 -0
  689. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/game_layer.py +0 -0
  690. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/graph_lane.py +0 -0
  691. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/inference.py +0 -0
  692. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/intent.py +0 -0
  693. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/journal_event_lane.py +0 -0
  694. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/manifest.py +0 -0
  695. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/manifest_validation.py +0 -0
  696. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/narrowing.py +0 -0
  697. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/overheard.py +0 -0
  698. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/packet_resolution.py +0 -0
  699. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/pipeline.py +0 -0
  700. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/planner.py +0 -0
  701. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/retrieval.py +0 -0
  702. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/runtime.py +0 -0
  703. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_arbiter.py +0 -0
  704. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_classifier.py +0 -0
  705. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_head.py +0 -0
  706. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_registry.json +0 -0
  707. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_registry_loader.py +0 -0
  708. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_shadow.py +0 -0
  709. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/session.py +0 -0
  710. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/session_utils.py +0 -0
  711. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/source_generation.py +0 -0
  712. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/truth_door.py +0 -0
  713. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/truth_facts.py +0 -0
  714. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/truth_prompts.py +0 -0
  715. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/turn_classifier.py +0 -0
  716. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/types.py +0 -0
  717. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/verify.py +0 -0
  718. {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/verify_modes.py +0 -0
  719. {topos_node-1.5.3 → topos_node-1.5.4}/topos/rate_limit.py +0 -0
  720. {topos_node-1.5.3 → topos_node-1.5.4}/topos/relay_stamp.py +0 -0
  721. {topos_node-1.5.3 → topos_node-1.5.4}/topos/routines/__init__.py +0 -0
  722. {topos_node-1.5.3 → topos_node-1.5.4}/topos/routines/schema.py +0 -0
  723. {topos_node-1.5.3 → topos_node-1.5.4}/topos/routines/store.py +0 -0
  724. {topos_node-1.5.3 → topos_node-1.5.4}/topos/runtime_housekeeping.py +0 -0
  725. {topos_node-1.5.3 → topos_node-1.5.4}/topos/runtime_update.py +0 -0
  726. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/__init__.py +0 -0
  727. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/explicit_wording.py +0 -0
  728. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/hub_pipeline.py +0 -0
  729. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/nsfw_classifier.py +0 -0
  730. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/ollama_transforms.py +0 -0
  731. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/prewarm.py +0 -0
  732. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/privacy_filter.py +0 -0
  733. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/__init__.py +0 -0
  734. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/container.py +0 -0
  735. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/__init__.py +0 -0
  736. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/base.py +0 -0
  737. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/local.py +0 -0
  738. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/remote.py +0 -0
  739. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/interfaces.py +0 -0
  740. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/llm/__init__.py +0 -0
  741. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/llm/base.py +0 -0
  742. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/llm/openai.py +0 -0
  743. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/local.py +0 -0
  744. {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/postgres.py +0 -0
  745. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/__init__.py +0 -0
  746. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/bundled_canonical_triples.py +0 -0
  747. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/canonical_signal_defaults.py +0 -0
  748. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/declared_field_map_spec.py +0 -0
  749. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/definitions.py +0 -0
  750. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/install_authority.py +0 -0
  751. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/install_maintenance.py +0 -0
  752. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/install_service.py +0 -0
  753. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/registry.py +0 -0
  754. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/retention.py +0 -0
  755. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/runtime_install.py +0 -0
  756. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/scrub_attribution.py +0 -0
  757. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/scrub_service.py +0 -0
  758. {topos_node-1.5.3 → topos_node-1.5.4}/topos/startup_banner.py +0 -0
  759. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/__init__.py +0 -0
  760. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/__init__.py +0 -0
  761. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/factory.py +0 -0
  762. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/fakes.py +0 -0
  763. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/postgres/stores.py +0 -0
  764. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/protocols.py +0 -0
  765. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/sqlite/__init__.py +0 -0
  766. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/sqlite/stores.py +0 -0
  767. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  768. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/__init__.py +0 -0
  769. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/activity_tables.py +0 -0
  770. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  771. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  772. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  773. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/model.py +0 -0
  774. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/tables.py +0 -0
  775. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  776. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/canonical_store.py +0 -0
  777. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/conversations_tables.py +0 -0
  778. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/journal_repair.py +0 -0
  779. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/mapping_store.py +0 -0
  780. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/postgres.py +0 -0
  781. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/__init__.py +0 -0
  782. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/client.py +0 -0
  783. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/connection_tuning.py +0 -0
  784. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/__init__.py +0 -0
  785. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  786. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/activity_writer_columns_v1.py +0 -0
  787. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  788. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
  789. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  790. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  791. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/backup.py +0 -0
  792. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/backup_custody.py +0 -0
  793. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  794. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  795. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  796. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  797. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/community_names_v1.py +0 -0
  798. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/complexity_v1.py +0 -0
  799. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/conflict_provenance_v1.py +0 -0
  800. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  801. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
  802. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  803. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
  804. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derived_row_identity_v1.py +0 -0
  805. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/documents_v1.py +0 -0
  806. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
  807. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
  808. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
  809. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
  810. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
  811. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
  812. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  813. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
  814. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
  815. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
  816. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
  817. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/episodes_v1.py +0 -0
  818. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  819. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/fact_dimension_by_entity_type_v1.py +0 -0
  820. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  821. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  822. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  823. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  824. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  825. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
  826. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/mention_table_stamp_backfill_v1.py +0 -0
  827. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
  828. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
  829. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/net_subject_policy_v1.py +0 -0
  830. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/off_limits_carried_waiting_v1.py +0 -0
  831. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/owner_only_records_v1.py +0 -0
  832. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
  833. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/permissions_fact_lineage_keys_v1.py +0 -0
  834. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/permissions_message_context_indexes_v1.py +0 -0
  835. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/permissions_read_path_indexes_v1.py +0 -0
  836. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  837. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
  838. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/registry.py +0 -0
  839. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/registry_checksums.json +0 -0
  840. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  841. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
  842. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  843. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  844. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  845. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_objects.py +0 -0
  846. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  847. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  848. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
  849. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  850. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/temporal_fields_v1.py +0 -0
  851. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/transcripts_v1.py +0 -0
  852. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  853. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  854. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  855. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  856. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  857. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  858. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  859. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  860. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  861. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  862. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  863. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  864. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  865. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  866. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  867. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  868. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  869. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  870. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/paths.py +0 -0
  871. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/postgres.py +0 -0
  872. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/schema.py +0 -0
  873. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/schema_probe.py +0 -0
  874. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/storage_breakdown.py +0 -0
  875. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/write_gate.py +0 -0
  876. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/derived_row_identity.py +0 -0
  877. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/enrichment/__init__.py +0 -0
  878. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  879. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  880. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/normalized/__init__.py +0 -0
  881. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/normalized/normalized_store.py +0 -0
  882. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/__init__.py +0 -0
  883. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/decision.py +0 -0
  884. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/oplog_store.py +0 -0
  885. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/postgres.py +0 -0
  886. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/person/identity_resolver.py +0 -0
  887. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/projections/__init__.py +0 -0
  888. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/projections/index_ops_store.py +0 -0
  889. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/projections/vector_index_store.py +0 -0
  890. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/__init__.py +0 -0
  891. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/browser_flat_tables.py +0 -0
  892. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/file_store.py +0 -0
  893. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/raw_store.py +0 -0
  894. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/raw_tables_manager.py +0 -0
  895. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/sqlite_raw_store.py +0 -0
  896. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/security/encryption.py +0 -0
  897. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/signal_identity.py +0 -0
  898. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/source_settings.py +0 -0
  899. {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/user_identity.py +0 -0
  900. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sync/__init__.py +0 -0
  901. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sync/client.py +0 -0
  902. {topos_node-1.5.3 → topos_node-1.5.4}/topos/sync_handlers.py +0 -0
  903. {topos_node-1.5.3 → topos_node-1.5.4}/topos/testing/__init__.py +0 -0
  904. {topos_node-1.5.3 → topos_node-1.5.4}/topos/testing/lifespan.py +0 -0
  905. {topos_node-1.5.3 → topos_node-1.5.4}/topos/uds.py +0 -0
  906. {topos_node-1.5.3 → topos_node-1.5.4}/topos/uma_contact_enrichment.py +0 -0
  907. {topos_node-1.5.3 → topos_node-1.5.4}/topos/uma_filters.py +0 -0
  908. {topos_node-1.5.3 → topos_node-1.5.4}/topos/upgrades/__init__.py +0 -0
  909. {topos_node-1.5.3 → topos_node-1.5.4}/topos/upgrades/runner.py +0 -0
  910. {topos_node-1.5.3 → topos_node-1.5.4}/topos/utils/base_object.py +0 -0
  911. {topos_node-1.5.3 → topos_node-1.5.4}/topos/websocket_client.py +0 -0
  912. {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/dependency_links.txt +0 -0
  913. {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/entry_points.txt +0 -0
  914. {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/requires.txt +0 -0
  915. {topos_node-1.5.3 → topos_node-1.5.4}/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.5.3
3
+ Version: 1.5.4
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
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
9
9
 
10
10
  [project]
11
11
  name = "topos-node"
12
- version = "1.5.3"
12
+ version = "1.5.4"
13
13
  description = "Topos personal AI engine (FastAPI): local data, sync, control plane WebSocket client"
14
14
  readme = "README.md"
15
15
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  """Topos Control Plane Version Information."""
2
2
 
3
- __version__ = "1.5.3"
4
- __version_info__ = (1, 5, 3)
3
+ __version__ = "1.5.4"
4
+ __version_info__ = (1, 5, 4)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -287,6 +287,13 @@ async def startup_event() -> None:
287
287
 
288
288
  allow_rebuild_children()
289
289
  add_shutdown_listener(signal_rebuild_children)
290
+ # BL-168: the stop's own steps (control-plane client first, the ingestion queue parked, the permissions
291
+ # runtime's background work stopped) start at the signal, not when uvicorn's drain reaches shutdown_event.
292
+ from . import node_stop
293
+
294
+ node_stop.bind_loop(asyncio.get_running_loop())
295
+ node_stop.set_background_reaper(_reap_background_tasks)
296
+ add_shutdown_listener(node_stop.begin_stop)
290
297
  # This process holds the database, so its backups are the ones the model
291
298
  # manager may spend before it evicts a model. The disk floor never resolves
292
299
  # that directory for itself — on a split node it runs beside the models, on
@@ -706,11 +713,19 @@ async def startup_event() -> None:
706
713
 
707
714
  @app.on_event("shutdown")
708
715
  async def shutdown_event() -> None:
716
+ from . import node_stop
709
717
  from .pipeline.job_runner import stop_pipeline_worker
710
- from .runtime_shutdown import end_runtime
718
+ from .runtime_shutdown import current_generation, end_runtime
711
719
 
712
720
  # Wake cooperative workers (fact_llm / Ollama threads) before awaiting
713
721
  # network teardown so Ctrl+C does not wait out a full enrichment batch.
722
+ run = current_generation()
723
+ run.request_stop("app_shutdown")
724
+ # BL-168: the control-plane client closes first, then the ingestion queue
725
+ # is parked (the held job requeued) and the permissions runtime's background
726
+ # work stopped. The same task when a signal or the tray already began it.
727
+ # Before end_runtime, so the queue is parked under THIS run's generation.
728
+ await node_stop.stop_now(run)
714
729
  # end_runtime retires THIS run's generation — its workers stop for good —
715
730
  # and installs a fresh one, so anything that runs later in this process
716
731
  # (another app run, a CLI command, the next test) does not inherit a
@@ -723,10 +738,10 @@ async def shutdown_event() -> None:
723
738
  # Reaped before the network teardown below, because these are the writers.
724
739
  if state.upgrade_runner_stop is not None:
725
740
  state.upgrade_runner_stop.set()
726
- # First, because it unblocks the rest: a background task awaiting a rebuild
727
- # through asyncio.to_thread is stuck until the child dies, however it is
728
- # cancelled.
729
- await _reap_rebuild_children()
741
+ # Rebuild children were stopped first inside stop_now (after the control-
742
+ # plane client), because it unblocks the rest: a background task awaiting a
743
+ # rebuild through asyncio.to_thread is stuck until the child dies, however
744
+ # it is cancelled.
730
745
  await _reap_background_tasks()
731
746
  await stop_pipeline_worker()
732
747
  await _reap_upgrade_runner()
@@ -738,8 +753,7 @@ async def shutdown_event() -> None:
738
753
  except asyncio.CancelledError:
739
754
  pass
740
755
  state.engine_presence_task = None
741
- if state.control_plane_client:
742
- await state.control_plane_client.stop()
756
+ # The control-plane client was stopped first, by node_stop.stop_now above.
743
757
  # The first-pin thread waits between tries; tell it the app is gone (never blocks).
744
758
  from .relay_stamp import stop_first_pin
745
759
 
@@ -419,7 +419,10 @@ def main(
419
419
  log_path=get_log_file_path(),
420
420
  )
421
421
  else:
422
- uvicorn.run(app, host=host, port=port, log_config=get_uvicorn_log_config())
422
+ from topos import node_stop
423
+
424
+ node_stop.enable_exit_deadline()
425
+ uvicorn.run(app, host=host, port=port, log_config=get_uvicorn_log_config(), **node_stop.uvicorn_options())
423
426
 
424
427
 
425
428
  from topos.cli.reprocess_cmd import reprocess_command # noqa: E402
@@ -823,8 +823,11 @@ def serve_with_tray(
823
823
  """
824
824
  import uvicorn
825
825
 
826
- config = uvicorn.Config(app, host=host, port=port, log_config=log_config)
826
+ from topos import node_stop
827
+
828
+ config = uvicorn.Config(app, host=host, port=port, log_config=log_config, **node_stop.uvicorn_options())
827
829
  server = uvicorn.Server(config)
830
+ node_stop.enable_exit_deadline()
828
831
 
829
832
  def stop_server() -> None:
830
833
  # Every tray exit comes through here (Quit, Select Topos, Ctrl+C). None
@@ -838,6 +841,12 @@ def serve_with_tray(
838
841
  signal_rebuild_children()
839
842
  except Exception as exc: # noqa: BLE001 — never let this cost the exit itself
840
843
  print(f"Could not stop graph rebuild children ({exc}); quitting anyway.")
844
+ try:
845
+ # BL-168: the control-plane client, the ingestion queue and the
846
+ # permissions runtime's background work stop now, not after the drain.
847
+ node_stop.begin_stop("tray_quit")
848
+ except Exception as exc: # noqa: BLE001
849
+ print(f"Could not begin the node's stop ({exc}); quitting anyway.")
841
850
  finally:
842
851
  server.should_exit = True
843
852
 
@@ -46,6 +46,11 @@ logger = logging.getLogger("topos.control_plane_client")
46
46
  #: reconnects itself rather than being evicted.
47
47
  PING_INTERVAL_SECONDS = 30.0
48
48
  PING_TIMEOUT_SECONDS = 90.0
49
+ #: R-N154 M2: at a stop, how long the asks already being handled get to send their replies before the socket closes.
50
+ #: Inside node_stop's 12 s bound for the client's whole stop.
51
+ INBOUND_DRAIN_SECONDS = 5.0
52
+ #: What an ask that arrives while the node is stopping is answered with, at once.
53
+ STOPPING_ERROR = "Engine is stopping. Retry shortly."
49
54
 
50
55
  _FAST_INBOUND_MESSAGE_TYPES = frozenset(
51
56
  {
@@ -145,6 +150,9 @@ class ControlPlaneClient:
145
150
  self._inbound_semaphore = asyncio.Semaphore(self._inbound_concurrency_limit)
146
151
  self._inbound_tasks: set[asyncio.Task] = set()
147
152
  self._inbound_lock = asyncio.Lock()
153
+ # R-N154 M2: set at the start of a stop; new asks are refused while the ones in hand finish.
154
+ self._draining = False
155
+ self._inbound_drain_seconds = INBOUND_DRAIN_SECONDS
148
156
 
149
157
  self._presence_outbox_size = max(1, int(settings.control_plane_presence_outbox_size))
150
158
  self._presence_outbox: deque[dict[str, Any]] = deque(maxlen=self._presence_outbox_size)
@@ -188,6 +196,7 @@ class ControlPlaneClient:
188
196
  if self._task and not self._task.done():
189
197
  return
190
198
  self._stop_requested = False
199
+ self._draining = False
191
200
  try:
192
201
  # Engine handlers run here — the loop the app lives on.
193
202
  self._handler_loop = asyncio.get_running_loop()
@@ -277,6 +286,8 @@ class ControlPlaneClient:
277
286
  await asyncio.to_thread(self._thread.join, 10.0)
278
287
  self._thread = None
279
288
  else:
289
+ self._draining = True
290
+ await self._drain_inbound_tasks(self._inbound_drain_seconds)
280
291
  self._stop.set()
281
292
  if self._ws:
282
293
  try:
@@ -302,7 +313,14 @@ class ControlPlaneClient:
302
313
  self._set_state("idle")
303
314
 
304
315
  async def _shutdown_on_client_loop(self) -> None:
305
- """Runs on the client thread's loop; unblocks _run so the thread exits."""
316
+ """Runs on the client thread's loop; unblocks _run so the thread exits.
317
+
318
+ Two phases (R-N154 M2). First the asks already being handled get up to ``_inbound_drain_seconds`` to send
319
+ their replies while every new ask is refused at once with ``STOPPING_ERROR``: a search past its checkpoint
320
+ has written its receipt and spent its share's allowance, and an admitted answer has its id, so closing under
321
+ them lost the reply the node had already paid for. Then the socket closes and what is left is cancelled."""
322
+ self._draining = True
323
+ await self._drain_inbound_tasks(self._inbound_drain_seconds)
306
324
  self._stop.set()
307
325
  if self._ws:
308
326
  try:
@@ -311,6 +329,12 @@ class ControlPlaneClient:
311
329
  pass
312
330
  await self._cancel_inbound_tasks()
313
331
 
332
+ async def _drain_inbound_tasks(self, timeout_s: float) -> None:
333
+ async with self._inbound_lock:
334
+ pending = [task for task in self._inbound_tasks if not task.done()]
335
+ if pending and timeout_s > 0:
336
+ await asyncio.wait(pending, timeout=timeout_s)
337
+
314
338
  async def _cancel_inbound_tasks(self) -> None:
315
339
  async with self._inbound_lock:
316
340
  pending = list(self._inbound_tasks)
@@ -420,6 +444,12 @@ class ControlPlaneClient:
420
444
 
421
445
  async def _schedule_inbound_message(self, ws, data: Dict[str, Any]) -> None:
422
446
  msg_type = str(data.get("type") or "")
447
+ if self._draining and msg_type not in _FAST_INBOUND_MESSAGE_TYPES and msg_type != "ping":
448
+ # R-N154 M2: the node is stopping. Refuse at once, so the asker hears now rather than at a timeout.
449
+ request_id = data.get("id")
450
+ if request_id:
451
+ await self._send_ws_json(ws, {"id": request_id, "status": "error", "error": STOPPING_ERROR})
452
+ return
423
453
  if msg_type in _FAST_INBOUND_MESSAGE_TYPES:
424
454
  task = asyncio.create_task(self._handle_message(ws, data))
425
455
  self._inbound_tasks.add(task)
@@ -70,11 +70,17 @@ def _search_batch_version() -> int:
70
70
  return 0
71
71
 
72
72
 
73
+ # The answer protocol this node serves, 0 when answers are off: 1 wrote answers (1.5.0); 2 also carries the writer
74
+ # a policy's `writer_disclosure` releases (A2A-4 amendment 9). The control plane offers the sharer that choice only
75
+ # to a node advertising 2, because an older node refuses a policy naming the field.
76
+ ANSWER_VERSION = 2
77
+
78
+
73
79
  def _answer_version() -> int:
74
80
  try:
75
81
  from ..permissions_v2 import switches
76
- return int(switches.is_bound() and switches.on(switches.MESSAGE_SEARCH)
77
- and switches.on(switches.ANSWERS))
82
+ return ANSWER_VERSION if (switches.is_bound() and switches.on(switches.MESSAGE_SEARCH)
83
+ and switches.on(switches.ANSWERS)) else 0
78
84
  except Exception:
79
85
  return 0
80
86
 
@@ -0,0 +1,272 @@
1
+ """What a stop does the moment it is asked for (BL-168).
2
+
3
+ A node told to stop used to do almost nothing until uvicorn reached the app's
4
+ lifespan shutdown, and uvicorn reaches it only after every in-flight request
5
+ has finished: with no ``timeout_graceful_shutdown`` that wait has no bound. On
6
+ 10 Oct 2026 (1.5.3) the port closed at the SIGTERM, then the node ran on for 14
7
+ minutes: its pipeline worker kept running the job it held, nothing stopped the
8
+ permissions runtime's background threads (the catch-up assessment pass, the
9
+ share refresh loop, the index rebuild queue), and the control-plane client,
10
+ which ``shutdown_event`` stops last of all, stayed connected and kept taking
11
+ relayed asks it could no longer answer ("Dropping inbound request due to
12
+ saturation", ~150). It exited when that work happened to end.
13
+
14
+ Now a stop has three parts:
15
+
16
+ 1. **At the signal** (``begin_stop``, a ``runtime_shutdown`` listener; the
17
+ tray's Quit calls it too). It only schedules work and starts a timer, as a
18
+ signal handler must. On the app loop, in this order (``stop_now``):
19
+ close the control-plane client, so the control plane stops relaying asks
20
+ to a node that is going away and answers the asker at once; stop any graph
21
+ rebuild child (what a held job may be waiting on); park the
22
+ ingestion queue (``job_runner.park_pipeline_worker``: the job a worker
23
+ holds goes back to the queue, and no worker claims or starts again in
24
+ this run); stop the permissions runtime's background work
25
+ (``runtime.stop_background_work``: catch-up passes, refresh loop, rebuild
26
+ queue, answer jobs; assessments are durable checkpoints and a pass a stop
27
+ cuts short is planned again at the next start). Then the app's own
28
+ background tasks.
29
+ 2. **The drain is bounded.** uvicorn waits ``drain_seconds()`` for in-flight
30
+ requests and then cancels them (``uvicorn_options``), so lifespan shutdown
31
+ always runs; ``shutdown_event`` runs ``stop_now`` again first (it is the
32
+ same task when the signal already started it).
33
+ 3. **The process is bounded.** Cancelling a coroutine never stops the thread it
34
+ awaits, and on Python 3.10 ``asyncio.run`` and the interpreter join every
35
+ executor thread with no timeout. ``exit_deadline_seconds()`` after the stop
36
+ began, a process still alive logs the threads it was waiting on (names only)
37
+ and exits. SQLite rolls an interrupted transaction back at the next open; a
38
+ claimed job whose requeue never landed is recovered at the next start
39
+ (``recover_pipeline_jobs``).
40
+ """
41
+
42
+ from __future__ import annotations
43
+
44
+ import asyncio
45
+ import logging
46
+ import os
47
+ import threading
48
+ import time
49
+ from typing import Any, Callable, Optional
50
+
51
+ logger = logging.getLogger("topos.node_stop")
52
+
53
+ #: How long uvicorn lets in-flight requests finish before it cancels them.
54
+ DEFAULT_DRAIN_SECONDS = 10.0
55
+ #: From the stop request to a forced exit, if the process is still alive then.
56
+ DEFAULT_EXIT_DEADLINE_SECONDS = 60.0
57
+ #: The control-plane client's own stop waits up to 10 s for its close handshake
58
+ #: and 10 s for its thread; one bound over both.
59
+ CONTROL_PLANE_STOP_SECONDS = 12.0
60
+ #: Parking hands the held job back under the write gate (bounded to 2 s inside).
61
+ PARK_SECONDS = 5.0
62
+ #: The permissions runtime's stops only set events; the bound is for the gate.
63
+ PERMISSIONS_STOP_SECONDS = 5.0
64
+ BACKGROUND_REAP_SECONDS = 5.0
65
+
66
+
67
+ def _env_seconds(name: str, default: float) -> float:
68
+ raw = os.environ.get(name, "").strip()
69
+ if not raw:
70
+ return default
71
+ try:
72
+ value = float(raw)
73
+ except ValueError:
74
+ return default
75
+ return max(0.0, value)
76
+
77
+
78
+ def drain_seconds() -> float:
79
+ """uvicorn's ``timeout_graceful_shutdown``: ``TOPOS_SHUTDOWN_DRAIN_SECONDS``, default 10."""
80
+ return _env_seconds("TOPOS_SHUTDOWN_DRAIN_SECONDS", DEFAULT_DRAIN_SECONDS)
81
+
82
+
83
+ def exit_deadline_seconds() -> float:
84
+ """``TOPOS_SHUTDOWN_EXIT_DEADLINE_SECONDS``, default 60; 0 turns the forced exit off."""
85
+ return _env_seconds("TOPOS_SHUTDOWN_EXIT_DEADLINE_SECONDS", DEFAULT_EXIT_DEADLINE_SECONDS)
86
+
87
+
88
+ def uvicorn_options() -> dict:
89
+ """Keyword arguments every node uvicorn server is built with (CLI and tray)."""
90
+ return {"timeout_graceful_shutdown": max(1, int(round(drain_seconds())))}
91
+
92
+
93
+ _lock = threading.Lock()
94
+ _loop: Optional[asyncio.AbstractEventLoop] = None
95
+ _task: Optional[asyncio.Task] = None
96
+ _begun = False
97
+
98
+
99
+ def bind_loop(loop: asyncio.AbstractEventLoop) -> None:
100
+ """App startup: the loop ``begin_stop`` schedules on. A new run starts with no stop begun."""
101
+ global _loop, _task, _begun
102
+ with _lock:
103
+ _loop = loop
104
+ _task = None
105
+ _begun = False
106
+
107
+
108
+ def begin_stop(reason: str = "signal") -> bool:
109
+ """Start the stop now. Safe inside a signal handler and from any thread.
110
+
111
+ Blocks on no lock the interrupted main thread could be holding: this
112
+ module's ``_lock`` is only tried (a busy lock means a stop is being begun or
113
+ joined already); ``current_generation`` reads without a lock; the
114
+ generation's own lock is reentrant; ``Event.set`` and
115
+ ``call_soon_threadsafe`` take only locks no main-thread code here holds
116
+ across a call out. Idempotent per run. Returns True when this call began it."""
117
+ global _begun
118
+ from .runtime_shutdown import current_generation
119
+
120
+ if not _lock.acquire(blocking=False):
121
+ return False
122
+ try:
123
+ if _begun:
124
+ return False
125
+ _begun = True
126
+ loop = _loop
127
+ finally:
128
+ _lock.release()
129
+ generation = current_generation()
130
+ if not generation.is_stop_requested():
131
+ # The tray's Quit is no signal; the run is stopping all the same.
132
+ generation.request_stop(reason)
133
+ _arm_exit_deadline()
134
+ if loop is not None and not loop.is_closed():
135
+ try:
136
+ loop.call_soon_threadsafe(_spawn_on_loop, generation)
137
+ except RuntimeError: # the loop closed between the check and the call
138
+ pass
139
+ return True
140
+
141
+
142
+ def _spawn_on_loop(generation: Any) -> None:
143
+ global _task
144
+ with _lock:
145
+ if _task is None:
146
+ _task = asyncio.get_running_loop().create_task(_stop_steps(generation), name="node-stop")
147
+
148
+
149
+ async def stop_now(generation: Any = None) -> None:
150
+ """Run the stop's steps once per run (``shutdown_event``; the signal's task when it already began)."""
151
+ global _task, _begun
152
+ from .runtime_shutdown import current_generation
153
+
154
+ with _lock:
155
+ _begun = True
156
+ task = _task
157
+ if task is None or task.get_loop() is not asyncio.get_running_loop():
158
+ task = asyncio.get_running_loop().create_task(
159
+ _stop_steps(generation if generation is not None else current_generation()), name="node-stop"
160
+ )
161
+ _task = task
162
+ await asyncio.shield(task)
163
+
164
+
165
+ async def _bounded(name: str, step: Callable[[], Any], seconds: float) -> None:
166
+ started = time.monotonic()
167
+ try:
168
+ await asyncio.wait_for(step(), timeout=seconds)
169
+ except asyncio.TimeoutError:
170
+ logger.warning("node stop: %s did not finish within %.0fs; going on", name, seconds)
171
+ except Exception as exc: # noqa: BLE001 — a stop step never stops the stop
172
+ logger.warning("node stop: %s failed (%s)", name, type(exc).__name__)
173
+ else:
174
+ logger.info("node stop: %s done in %.1fs", name, time.monotonic() - started)
175
+
176
+
177
+ async def _stop_steps(generation: Any) -> None:
178
+ from .core import state
179
+ from .pipeline.job_runner import park_pipeline_worker
180
+
181
+ client = getattr(state, "control_plane_client", None)
182
+ if client is not None:
183
+ await _bounded("control-plane client", client.stop, CONTROL_PLANE_STOP_SECONDS)
184
+ # Before the tasks and workers it unblocks: cancelling a task never stops the thread it awaits, and a job
185
+ # waiting on a rebuild child waits until the child dies (the signal listener has usually stopped it already).
186
+ await _bounded("graph rebuild children", _stop_rebuild_children, REBUILD_STOP_SECONDS)
187
+ await _bounded("ingestion queue", lambda: park_pipeline_worker(generation), PARK_SECONDS)
188
+
189
+ def _permissions() -> Any:
190
+ from .permissions_v2.runtime import stop_background_work
191
+
192
+ return asyncio.to_thread(stop_background_work)
193
+
194
+ await _bounded("permissions background work", _permissions, PERMISSIONS_STOP_SECONDS)
195
+ reap = _background_reaper
196
+ if reap is not None:
197
+ await _bounded("background tasks", reap, BACKGROUND_REAP_SECONDS)
198
+
199
+
200
+ REBUILD_STOP_SECONDS = 5.0
201
+
202
+
203
+ def _stop_rebuild_children() -> Any:
204
+ from .features.entities import rebuild_subprocess
205
+
206
+ return asyncio.to_thread(rebuild_subprocess.stop_rebuild_children, 2.0)
207
+
208
+
209
+ #: ``app._reap_background_tasks``, set at startup (this module never imports the app).
210
+ _background_reaper: Optional[Callable[[], Any]] = None
211
+
212
+
213
+ def set_background_reaper(reap: Optional[Callable[[], Any]]) -> None:
214
+ global _background_reaper
215
+ _background_reaper = reap
216
+
217
+
218
+ _stop_begun = threading.Event()
219
+ _deadline_thread: Optional[threading.Thread] = None
220
+
221
+
222
+ def enable_exit_deadline() -> bool:
223
+ """Serving entry points only (``topos-node`` and its tray), before uvicorn starts: arm the forced exit.
224
+
225
+ The timer thread starts here, not at the stop: starting a thread inside a signal handler can deadlock on
226
+ ``threading``'s own lock when the signal lands while the main thread is starting one (asyncio's executor
227
+ does, on the loop thread). A process that never calls this (tests, CLI commands) never force-exits."""
228
+ global _deadline_thread
229
+ seconds = exit_deadline_seconds()
230
+ if seconds <= 0:
231
+ return False
232
+ with _lock:
233
+ if _deadline_thread is not None and _deadline_thread.is_alive():
234
+ return True
235
+ _deadline_thread = threading.Thread(
236
+ target=_exit_after_stop, args=(seconds,), name="topos-exit-deadline", daemon=True
237
+ )
238
+ _deadline_thread.start()
239
+ return True
240
+
241
+
242
+ def _arm_exit_deadline() -> None:
243
+ _stop_begun.set()
244
+
245
+
246
+ def _exit_after_stop(seconds: float) -> None:
247
+ _stop_begun.wait()
248
+ _exit_after(seconds)
249
+
250
+
251
+ def _still_running() -> list[str]:
252
+ me = threading.current_thread()
253
+ return sorted(
254
+ t.name for t in threading.enumerate() if t is not me and t.is_alive() and t is not threading.main_thread()
255
+ )
256
+
257
+
258
+ def _exit_after(seconds: float, *, exit: Callable[[int], Any] = os._exit, sleep: Callable[[float], Any] = time.sleep) -> None:
259
+ sleep(seconds)
260
+ names = _still_running()
261
+ logger.warning(
262
+ "node stop: still running %.0fs after the stop was asked for; exiting now (%d thread(s): %s)",
263
+ seconds,
264
+ len(names),
265
+ ", ".join(names[:16]) or "-",
266
+ )
267
+ for handler in logging.getLogger().handlers + logger.handlers:
268
+ try:
269
+ handler.flush()
270
+ except Exception: # noqa: BLE001
271
+ pass
272
+ exit(0)
@@ -325,7 +325,7 @@ DOMAIN_FOLDS = frozenset(_stem(word) for domain, words in CATEGORY_TOPICS.items(
325
325
  # the walk are unchanged. A family word in a question is a label of the share, never a person's name (`_name_terms`).
326
326
  SOURCE_FAMILIES = ("imessage", "chatgpt", "journal", "whatsapp", "signal", "telegram", "gmail", "slack", "discord")
327
327
  # AR152 class Q, per-item carriage: on when shipped; a pinned constant so a measurement may run both ways.
328
- PER_ITEM_CARRIAGE = True # 1.5.3 ships it on (review R-RULES); the owner may turn it off in 1.5.4 once lending is measured on live receipts
328
+ PER_ITEM_CARRIAGE = False # off from 1.5.4 (owner, 11 Oct, BL-163): on the rig it cost 6 of 84 answerable questions with must-abstain 0/60 either way; R-RULES F2's steer fix makes off a precision cost only
329
329
  _COORDINATORS = frozenset({"and", "or"})
330
330
  _SUBJECT_TOKEN = re.compile(r"[^\W_]+|[,&/]", re.UNICODE)
331
331