topos-node 1.3.24__tar.gz → 1.3.26__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 (712) hide show
  1. {topos_node-1.3.24 → topos_node-1.3.26}/MANIFEST.in +1 -0
  2. {topos_node-1.3.24/topos_node.egg-info → topos_node-1.3.26}/PKG-INFO +1 -1
  3. {topos_node-1.3.24 → topos_node-1.3.26}/pyproject.toml +1 -1
  4. {topos_node-1.3.24 → topos_node-1.3.26}/topos/__version__.py +2 -2
  5. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/enrichment.py +115 -7
  6. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/signal.py +51 -0
  7. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/settings.py +21 -0
  8. {topos_node-1.3.24 → topos_node-1.3.26}/topos/control_plane_client.py +3 -0
  9. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/__init__.py +1 -0
  10. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/config.py +62 -0
  11. topos_node-1.3.26/topos/core/handlers/derivation.py +79 -0
  12. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/routines.py +51 -0
  13. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/signal_features.py +1 -0
  14. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/__init__.py +3 -0
  15. topos_node-1.3.26/topos/enrichment/jobs/canonical/derivation_job.py +208 -0
  16. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/models/mvp_defaults.py +1 -0
  17. topos_node-1.3.26/topos/features/derivation/bundled_packs/_scales.yaml +17 -0
  18. topos_node-1.3.26/topos/features/derivation/bundled_packs/admin.legal.yaml +124 -0
  19. topos_node-1.3.26/topos/features/derivation/bundled_packs/aspirations.goals.yaml +92 -0
  20. topos_node-1.3.26/topos/features/derivation/bundled_packs/behavior.habits.yaml +112 -0
  21. topos_node-1.3.26/topos/features/derivation/bundled_packs/behavior.preferences.yaml +95 -0
  22. topos_node-1.3.26/topos/features/derivation/bundled_packs/beliefs.civic.yaml +99 -0
  23. topos_node-1.3.26/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +86 -0
  24. topos_node-1.3.26/topos/features/derivation/bundled_packs/communication.style.yaml +84 -0
  25. topos_node-1.3.26/topos/features/derivation/bundled_packs/community.membership.yaml +83 -0
  26. topos_node-1.3.26/topos/features/derivation/bundled_packs/craft.tooling.yaml +93 -0
  27. topos_node-1.3.26/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +88 -0
  28. topos_node-1.3.26/topos/features/derivation/bundled_packs/finances.economics.yaml +86 -0
  29. topos_node-1.3.26/topos/features/derivation/bundled_packs/health.lifestyle.yaml +81 -0
  30. topos_node-1.3.26/topos/features/derivation/bundled_packs/health.mental.yaml +72 -0
  31. topos_node-1.3.26/topos/features/derivation/bundled_packs/health.physical.yaml +94 -0
  32. topos_node-1.3.26/topos/features/derivation/bundled_packs/household.pets.yaml +92 -0
  33. topos_node-1.3.26/topos/features/derivation/bundled_packs/identity.core.yaml +81 -0
  34. topos_node-1.3.26/topos/features/derivation/bundled_packs/interests.taste.yaml +109 -0
  35. topos_node-1.3.26/topos/features/derivation/bundled_packs/life.events.yaml +71 -0
  36. topos_node-1.3.26/topos/features/derivation/bundled_packs/narrative.self.yaml +121 -0
  37. topos_node-1.3.26/topos/features/derivation/bundled_packs/personality.traits.yaml +88 -0
  38. topos_node-1.3.26/topos/features/derivation/bundled_packs/places.mobility.yaml +92 -0
  39. topos_node-1.3.26/topos/features/derivation/bundled_packs/possessions.assets.yaml +88 -0
  40. topos_node-1.3.26/topos/features/derivation/bundled_packs/relationships.social.yaml +106 -0
  41. topos_node-1.3.26/topos/features/derivation/bundled_packs/values.motivation.yaml +97 -0
  42. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +160 -0
  43. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/expertise.yaml +365 -0
  44. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/habits.yaml +86 -0
  45. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/interests.yaml +364 -0
  46. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/preferences.yaml +49 -0
  47. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/stances.yaml +70 -0
  48. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/tools.yaml +118 -0
  49. topos_node-1.3.26/topos/features/derivation/bundled_packs/vocab/values.yaml +62 -0
  50. topos_node-1.3.26/topos/features/derivation/bundled_packs/work.career.yaml +151 -0
  51. topos_node-1.3.26/topos/features/derivation/candidates.py +58 -0
  52. topos_node-1.3.26/topos/features/derivation/guard.py +51 -0
  53. topos_node-1.3.26/topos/features/derivation/packs.py +162 -0
  54. topos_node-1.3.26/topos/features/derivation/prefilter.py +58 -0
  55. topos_node-1.3.26/topos/features/derivation/registry.py +62 -0
  56. topos_node-1.3.26/topos/features/derivation/surfaces.py +83 -0
  57. topos_node-1.3.26/topos/features/derivation/synthesize.py +109 -0
  58. topos_node-1.3.26/topos/features/derivation/template.py +356 -0
  59. topos_node-1.3.26/topos/features/derivation/verify.py +121 -0
  60. topos_node-1.3.26/topos/features/derivation/writer.py +442 -0
  61. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/resolver.py +54 -3
  62. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/facts/llm_extract.py +13 -12
  63. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/facts/reads.py +19 -1
  64. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/service.py +8 -1
  65. {topos_node-1.3.24 → topos_node-1.3.26}/topos/protocol/handled_message_types.json +9 -0
  66. topos_node-1.3.26/topos/query/facts_direct.py +144 -0
  67. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/fingerprint.py +2 -1
  68. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/inference.py +55 -7
  69. topos_node-1.3.26/topos/query/packet_resolution.py +82 -0
  70. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/pipeline.py +41 -4
  71. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/retrieval.py +58 -11
  72. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/session_utils.py +8 -1
  73. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/types.py +4 -0
  74. {topos_node-1.3.24 → topos_node-1.3.26}/topos/routines/store.py +58 -0
  75. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/registry.py +13 -1
  76. topos_node-1.3.26/topos/storage/adapters/sqlite/__init__.py +0 -0
  77. topos_node-1.3.26/topos/storage/db/migrations/derivation_provenance_v1.py +81 -0
  78. topos_node-1.3.26/topos/storage/db/migrations/enrichment_record_progress_v1.py +64 -0
  79. topos_node-1.3.26/topos/storage/db/migrations/pack_registry_v1.py +65 -0
  80. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/registry.py +20 -0
  81. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/registry_checksums.json +3 -0
  82. {topos_node-1.3.24 → topos_node-1.3.26}/topos/upgrades/manifests.json +19 -0
  83. {topos_node-1.3.24 → topos_node-1.3.26/topos_node.egg-info}/PKG-INFO +1 -1
  84. {topos_node-1.3.24 → topos_node-1.3.26}/topos_node.egg-info/SOURCES.txt +52 -0
  85. {topos_node-1.3.24 → topos_node-1.3.26}/LICENSE +0 -0
  86. {topos_node-1.3.24 → topos_node-1.3.26}/README.md +0 -0
  87. {topos_node-1.3.24 → topos_node-1.3.26}/setup.cfg +0 -0
  88. {topos_node-1.3.24 → topos_node-1.3.26}/shared/__init__.py +0 -0
  89. {topos_node-1.3.24 → topos_node-1.3.26}/shared/filtering.py +0 -0
  90. {topos_node-1.3.24 → topos_node-1.3.26}/shared/schema_registry.py +0 -0
  91. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_active_database_binding.py +0 -0
  92. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_active_ingestion_binding.py +0 -0
  93. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_extensions.py +0 -0
  94. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_gate_leg_hermeticity.py +0 -0
  95. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_llm_integrations_storage.py +0 -0
  96. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_local_gate_composition.py +0 -0
  97. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_owner_database_hermeticity.py +0 -0
  98. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_prewarm_first_run.py +0 -0
  99. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_profile_hygiene.py +0 -0
  100. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_profiles.py +0 -0
  101. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_protocol_handled_types.py +0 -0
  102. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_query_field_contract.py +0 -0
  103. {topos_node-1.3.24 → topos_node-1.3.26}/tests/test_system_computer_name.py +0 -0
  104. {topos_node-1.3.24 → topos_node-1.3.26}/topos/__init__.py +0 -0
  105. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/__init__.py +0 -0
  106. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/duckdb_adapter.py +0 -0
  107. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/messenger_communities.py +0 -0
  108. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/messenger_graph.py +0 -0
  109. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/messenger_labels.py +0 -0
  110. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/profiles.py +0 -0
  111. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/query_engine.py +0 -0
  112. {topos_node-1.3.24 → topos_node-1.3.26}/topos/analytics/raw_queries.py +0 -0
  113. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/__init__.py +0 -0
  114. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/analytics.py +0 -0
  115. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/app_registry.py +0 -0
  116. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/backup.py +0 -0
  117. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/compute_remote.py +0 -0
  118. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/conversation_context.py +0 -0
  119. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/data_commit.py +0 -0
  120. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/data_explorer_table_prefs.py +0 -0
  121. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/database_explorer.py +0 -0
  122. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/db.py +0 -0
  123. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/device.py +0 -0
  124. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/engine_run.py +0 -0
  125. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/enrichment_lab.py +0 -0
  126. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/facts_llm_config.py +0 -0
  127. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/filter_lab.py +0 -0
  128. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/health.py +0 -0
  129. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/home_chat.py +0 -0
  130. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/ingestion_api.py +0 -0
  131. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/ingestion_compat.py +0 -0
  132. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/ingestion_sources.py +0 -0
  133. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/intelligence_lifecycle.py +0 -0
  134. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/llm.py +0 -0
  135. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/local_mcp.py +0 -0
  136. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/messenger_analytics.py +0 -0
  137. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/privacy_disclose.py +0 -0
  138. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/query_api.py +0 -0
  139. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/runtime_bootstrap.py +0 -0
  140. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/sanitization_ollama_config.py +0 -0
  141. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/shell.py +0 -0
  142. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/signal_extraction_config.py +0 -0
  143. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/source_install.py +0 -0
  144. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/source_scrub.py +0 -0
  145. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/sources.py +0 -0
  146. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/sources_overview.py +0 -0
  147. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/sync.py +0 -0
  148. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/tool_index.py +0 -0
  149. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/ui_config.py +0 -0
  150. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/uma_data.py +0 -0
  151. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/upgrades.py +0 -0
  152. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/usage.py +0 -0
  153. {topos_node-1.3.24 → topos_node-1.3.26}/topos/api/user_identity.py +0 -0
  154. {topos_node-1.3.24 → topos_node-1.3.26}/topos/app.py +0 -0
  155. {topos_node-1.3.24 → topos_node-1.3.26}/topos/auth.py +0 -0
  156. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/__init__.py +0 -0
  157. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/declared_field_map.py +0 -0
  158. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/__init__.py +0 -0
  159. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/base.py +0 -0
  160. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  161. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  162. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  163. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  164. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  165. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  166. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  167. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  168. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/models.py +0 -0
  169. {topos_node-1.3.24 → topos_node-1.3.26}/topos/canonicalization/resolver.py +0 -0
  170. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/__init__.py +0 -0
  171. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/__main__.py +0 -0
  172. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/assets/topos_blk_rounded.png +0 -0
  173. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/assets/topos_white.png +0 -0
  174. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/commands.py +0 -0
  175. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/profile_cmd.py +0 -0
  176. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/reprocess_cmd.py +0 -0
  177. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/setup_models_cmd.py +0 -0
  178. {topos_node-1.3.24 → topos_node-1.3.26}/topos/cli/tray.py +0 -0
  179. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/__init__.py +0 -0
  180. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/conversation_context_llm.py +0 -0
  181. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/facts_llm.py +0 -0
  182. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/local_model_builds.py +0 -0
  183. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/model_packs.py +0 -0
  184. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/node_function_providers.py +0 -0
  185. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/sanitization_ollama.py +0 -0
  186. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/signal_extraction.py +0 -0
  187. {topos_node-1.3.24 → topos_node-1.3.26}/topos/config/uvicorn_logging.json +0 -0
  188. {topos_node-1.3.24 → topos_node-1.3.26}/topos/contacts/__init__.py +0 -0
  189. {topos_node-1.3.24 → topos_node-1.3.26}/topos/contacts/identity.py +0 -0
  190. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/__init__.py +0 -0
  191. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/api_models.py +0 -0
  192. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/connection_resilience.py +0 -0
  193. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/db_health.py +0 -0
  194. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/device_helpers.py +0 -0
  195. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/errors.py +0 -0
  196. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/events.py +0 -0
  197. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/common.py +0 -0
  198. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/complexity.py +0 -0
  199. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/contacts_import.py +0 -0
  200. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/database_explorer.py +0 -0
  201. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/device.py +0 -0
  202. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/enrichment.py +0 -0
  203. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/enrichment_lab.py +0 -0
  204. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/filter_lab.py +0 -0
  205. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/graph_query.py +0 -0
  206. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/home_chat.py +0 -0
  207. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/ingest.py +0 -0
  208. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/messages.py +0 -0
  209. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/messenger_analytics.py +0 -0
  210. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/query.py +0 -0
  211. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/registry.py +0 -0
  212. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/sources.py +0 -0
  213. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/timeline_daily.py +0 -0
  214. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/tool_index.py +0 -0
  215. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/handlers/uma.py +0 -0
  216. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/logging.py +0 -0
  217. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/metrics.py +0 -0
  218. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/routine_access.py +0 -0
  219. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/startup_banner.py +0 -0
  220. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/state.py +0 -0
  221. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/table_layers.py +0 -0
  222. {topos_node-1.3.24 → topos_node-1.3.26}/topos/core/types.py +0 -0
  223. {topos_node-1.3.24 → topos_node-1.3.26}/topos/data_explorer_row_delete.py +0 -0
  224. {topos_node-1.3.24 → topos_node-1.3.26}/topos/data_explorer_table_prefs.py +0 -0
  225. {topos_node-1.3.24 → topos_node-1.3.26}/topos/data_explorer_tables.py +0 -0
  226. {topos_node-1.3.24 → topos_node-1.3.26}/topos/disclosure/__init__.py +0 -0
  227. {topos_node-1.3.24 → topos_node-1.3.26}/topos/disclosure/canonical_writer.py +0 -0
  228. {topos_node-1.3.24 → topos_node-1.3.26}/topos/disclosure/content_policy.py +0 -0
  229. {topos_node-1.3.24 → topos_node-1.3.26}/topos/disclosure/field_registry.py +0 -0
  230. {topos_node-1.3.24 → topos_node-1.3.26}/topos/disclosure/privacy_layer.py +0 -0
  231. {topos_node-1.3.24 → topos_node-1.3.26}/topos/disclosure/tier.py +0 -0
  232. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/__init__.py +0 -0
  233. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/__init__.py +0 -0
  234. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/base.py +0 -0
  235. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/generative_prompts.py +0 -0
  236. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/generative_response.py +0 -0
  237. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/huggingface.py +0 -0
  238. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/ollama.py +0 -0
  239. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/openai.py +0 -0
  240. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/openai_compatible.py +0 -0
  241. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/redpill.py +0 -0
  242. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/backends/stub.py +0 -0
  243. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/client.py +0 -0
  244. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/disk_space.py +0 -0
  245. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/engine.py +0 -0
  246. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/intake.py +0 -0
  247. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/memory_utils.py +0 -0
  248. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/model_cache.py +0 -0
  249. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/ollama_install.py +0 -0
  250. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/ollama_pull.py +0 -0
  251. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/ollama_setup_guidance.py +0 -0
  252. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/pipeline_memory.py +0 -0
  253. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/queue_manager.py +0 -0
  254. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/registration.py +0 -0
  255. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/result_formatter.py +0 -0
  256. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/router.py +0 -0
  257. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/scoped_token.py +0 -0
  258. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/tasks.py +0 -0
  259. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/torch_runtime.py +0 -0
  260. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/transport.py +0 -0
  261. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/usage_guard.py +0 -0
  262. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/usage_observation.py +0 -0
  263. {topos_node-1.3.24 → topos_node-1.3.26}/topos/engine/validator.py +0 -0
  264. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/__init__.py +0 -0
  265. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/catalog.py +0 -0
  266. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/derivation_recovery.py +0 -0
  267. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/derived_tables.py +0 -0
  268. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/job_readiness.py +0 -0
  269. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/job_writer.py +0 -0
  270. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/base.py +0 -0
  271. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  272. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  273. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  274. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  275. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  276. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  277. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
  278. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  279. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  280. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  281. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  282. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  283. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  284. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  285. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  286. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  287. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  288. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  289. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  290. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  291. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/raw/__init__.py +0 -0
  292. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  293. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/raw/language_job.py +0 -0
  294. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  295. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  296. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/model_overrides.py +0 -0
  297. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/models/__init__.py +0 -0
  298. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/models/manager.py +0 -0
  299. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/models/registry.py +0 -0
  300. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/models/versioning.py +0 -0
  301. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/orchestrator.py +0 -0
  302. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/pipeline_activity.py +0 -0
  303. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/processor.py +0 -0
  304. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/progress_bar.py +0 -0
  305. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/registry_contract.py +0 -0
  306. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/signal_derivation_config.json +0 -0
  307. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment/source_overrides.py +0 -0
  308. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment_lab/__init__.py +0 -0
  309. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment_lab/bundles.py +0 -0
  310. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment_lab/model_resolve.py +0 -0
  311. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment_lab/schema.py +0 -0
  312. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment_lab/service.py +0 -0
  313. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment_lab/store.py +0 -0
  314. {topos_node-1.3.24 → topos_node-1.3.26}/topos/enrichment_lab/worker.py +0 -0
  315. {topos_node-1.3.24 → topos_node-1.3.26}/topos/evals/__init__.py +0 -0
  316. {topos_node-1.3.24 → topos_node-1.3.26}/topos/evals/enrichment_eval.py +0 -0
  317. {topos_node-1.3.24 → topos_node-1.3.26}/topos/extensions.py +0 -0
  318. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/__init__.py +0 -0
  319. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/canonical.py +0 -0
  320. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/engine.py +0 -0
  321. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/entropy.py +0 -0
  322. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/focus.py +0 -0
  323. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/graph_metrics.py +0 -0
  324. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/influence.py +0 -0
  325. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/projection.py +0 -0
  326. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/snapshots.py +0 -0
  327. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/store.py +0 -0
  328. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/topic_merge.py +0 -0
  329. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/topics.py +0 -0
  330. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/topics_daily.py +0 -0
  331. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/complexity/volatility.py +0 -0
  332. {topos_node-1.3.24/topos/features/signal → topos_node-1.3.26/topos/features/derivation}/__init__.py +0 -0
  333. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/__init__.py +0 -0
  334. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/affinity.py +0 -0
  335. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/affinity_owner.py +0 -0
  336. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/affinity_quality.py +0 -0
  337. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/consolidation.py +0 -0
  338. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/context_vectors.py +0 -0
  339. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/cypher.py +0 -0
  340. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/declared_mappings.py +0 -0
  341. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/dossier.py +0 -0
  342. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/edges.py +0 -0
  343. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/fact_materializer.py +0 -0
  344. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/graph_enrichers.py +0 -0
  345. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/graph_refresh.py +0 -0
  346. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/graph_search.py +0 -0
  347. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/linking.py +0 -0
  348. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/maintenance.py +0 -0
  349. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/reads.py +0 -0
  350. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/entities/rebuild_subprocess.py +0 -0
  351. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/facts/__init__.py +0 -0
  352. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/facts/extract.py +0 -0
  353. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/facts/store.py +0 -0
  354. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/facts/verdicts.py +0 -0
  355. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/fit/evaluator.py +0 -0
  356. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/fit/opportunity_types.json +0 -0
  357. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/__init__.py +0 -0
  358. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/blackhole.py +0 -0
  359. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/blackhole_guard.py +0 -0
  360. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/blackhole_llm.py +0 -0
  361. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
  362. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/derived_scrub.py +0 -0
  363. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/exclusions.py +0 -0
  364. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/lifecycle/gc.py +0 -0
  365. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/provenance/__init__.py +0 -0
  366. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/provenance/posture.py +0 -0
  367. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/provenance/roles.py +0 -0
  368. {topos_node-1.3.24/topos/protocol → topos_node-1.3.26/topos/features/signal}/__init__.py +0 -0
  369. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/brief_canonical_loader.py +0 -0
  370. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/brief_ontology.py +0 -0
  371. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/brief_renderer.py +0 -0
  372. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/brief_schemas.py +0 -0
  373. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/chunking.py +0 -0
  374. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/cluster_labels.py +0 -0
  375. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/conversation_context.py +0 -0
  376. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/data_health.py +0 -0
  377. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  378. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/intentions.json +0 -0
  379. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/interests.json +0 -0
  380. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/memory.json +0 -0
  381. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/places.json +0 -0
  382. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/profile.json +0 -0
  383. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/relationships.json +0 -0
  384. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/resources.json +0 -0
  385. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  386. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/time.json +0 -0
  387. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/wellbeing.json +0 -0
  388. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/definitions/work.json +0 -0
  389. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/derived_spec.py +0 -0
  390. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/dimension_briefs.py +0 -0
  391. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/dimension_definition_loader.py +0 -0
  392. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/dimension_profiles.py +0 -0
  393. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/dimension_registry.py +0 -0
  394. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/embed_context.py +0 -0
  395. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/extraction/artifact_router.py +0 -0
  396. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/extraction/artifact_store.py +0 -0
  397. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/extraction/rule_extractors.py +0 -0
  398. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/graph_sanitize.py +0 -0
  399. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/hybrid_search.py +0 -0
  400. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/incremental_clustering.py +0 -0
  401. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/model_recommendations.py +0 -0
  402. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/query_embed_cache.py +0 -0
  403. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/schemas.py +0 -0
  404. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/signal_object_store.py +0 -0
  405. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/source_hydration.py +0 -0
  406. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/structured_signal.py +0 -0
  407. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/tool_index.py +0 -0
  408. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/topic_clustering.py +0 -0
  409. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/typed_stores/aggregates.py +0 -0
  410. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/typed_stores/commitments.py +0 -0
  411. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/typed_stores/rhythm.py +0 -0
  412. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  413. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/vector_codec.py +0 -0
  414. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/vector_math.py +0 -0
  415. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/signal/vector_settings.py +0 -0
  416. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/stats/__init__.py +0 -0
  417. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/stats/definitions.py +0 -0
  418. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/stats/engine.py +0 -0
  419. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/stats/fold.py +0 -0
  420. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/stats/insights.py +0 -0
  421. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/timeline_projection.py +0 -0
  422. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/timeline_rollup.py +0 -0
  423. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/triage/__init__.py +0 -0
  424. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/triage/badges.py +0 -0
  425. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/triage/daily.py +0 -0
  426. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/triage/dashboard.py +0 -0
  427. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/triage/instruments.py +0 -0
  428. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/triage/intents.py +0 -0
  429. {topos_node-1.3.24 → topos_node-1.3.26}/topos/features/triage/readiness.py +0 -0
  430. {topos_node-1.3.24 → topos_node-1.3.26}/topos/filter_lab/__init__.py +0 -0
  431. {topos_node-1.3.24 → topos_node-1.3.26}/topos/filter_lab/bundles.py +0 -0
  432. {topos_node-1.3.24 → topos_node-1.3.26}/topos/filter_lab/schema.py +0 -0
  433. {topos_node-1.3.24 → topos_node-1.3.26}/topos/filter_lab/service.py +0 -0
  434. {topos_node-1.3.24 → topos_node-1.3.26}/topos/filter_lab/store.py +0 -0
  435. {topos_node-1.3.24 → topos_node-1.3.26}/topos/filter_lab/worker.py +0 -0
  436. {topos_node-1.3.24 → topos_node-1.3.26}/topos/home_chat/__init__.py +0 -0
  437. {topos_node-1.3.24 → topos_node-1.3.26}/topos/home_chat/schema.py +0 -0
  438. {topos_node-1.3.24 → topos_node-1.3.26}/topos/home_chat/store.py +0 -0
  439. {topos_node-1.3.24 → topos_node-1.3.26}/topos/hosted_pool_lease.py +0 -0
  440. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/__init__.py +0 -0
  441. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/canonical_pipeline.py +0 -0
  442. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/checkpoints/__init__.py +0 -0
  443. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  444. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  445. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/inbox_crypto.py +0 -0
  446. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/inbox_drain.py +0 -0
  447. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/ingest_helpers.py +0 -0
  448. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/jobs.py +0 -0
  449. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/journal_location_fanout.py +0 -0
  450. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/journal_time_log_normalize.py +0 -0
  451. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/local_sync.py +0 -0
  452. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/log_preview.py +0 -0
  453. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/manager.py +0 -0
  454. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parser.py +0 -0
  455. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/__init__.py +0 -0
  456. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/base.py +0 -0
  457. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/browser_parser.py +0 -0
  458. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/calendar_parser.py +0 -0
  459. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  460. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  461. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  462. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/documents_parser.py +0 -0
  463. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  464. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  465. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/grok_parser.py +0 -0
  466. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/messenger_parser.py +0 -0
  467. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  468. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/progress.py +0 -0
  469. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/reprocess.py +0 -0
  470. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/__init__.py +0 -0
  471. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/base.py +0 -0
  472. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/calendar.py +0 -0
  473. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/chatgpt.py +0 -0
  474. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/contact_importers.py +0 -0
  475. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/grok.py +0 -0
  476. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/imessage_reader.py +0 -0
  477. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/signal_export_parser.py +0 -0
  478. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/sources/signal_reader.py +0 -0
  479. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/state_machine.py +0 -0
  480. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/triggers/__init__.py +0 -0
  481. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/triggers/file_trigger.py +0 -0
  482. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  483. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  484. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/validation/__init__.py +0 -0
  485. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/validation/base.py +0 -0
  486. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/validation/schema_registry.py +0 -0
  487. {topos_node-1.3.24 → topos_node-1.3.26}/topos/ingestion/validation/schema_validator.py +0 -0
  488. {topos_node-1.3.24 → topos_node-1.3.26}/topos/lineage/__init__.py +0 -0
  489. {topos_node-1.3.24 → topos_node-1.3.26}/topos/lineage/provenance.py +0 -0
  490. {topos_node-1.3.24 → topos_node-1.3.26}/topos/lineage/tracker.py +0 -0
  491. {topos_node-1.3.24 → topos_node-1.3.26}/topos/llm_integrations_storage.py +0 -0
  492. {topos_node-1.3.24 → topos_node-1.3.26}/topos/mcp_stdio_proxy.py +0 -0
  493. {topos_node-1.3.24 → topos_node-1.3.26}/topos/observability/__init__.py +0 -0
  494. {topos_node-1.3.24 → topos_node-1.3.26}/topos/observability/alerts.py +0 -0
  495. {topos_node-1.3.24 → topos_node-1.3.26}/topos/observability/metrics.py +0 -0
  496. {topos_node-1.3.24 → topos_node-1.3.26}/topos/observability/tracing.py +0 -0
  497. {topos_node-1.3.24 → topos_node-1.3.26}/topos/openai_client.py +0 -0
  498. {topos_node-1.3.24 → topos_node-1.3.26}/topos/pipeline/__init__.py +0 -0
  499. {topos_node-1.3.24 → topos_node-1.3.26}/topos/pipeline/audit.py +0 -0
  500. {topos_node-1.3.24 → topos_node-1.3.26}/topos/pipeline/envelope.py +0 -0
  501. {topos_node-1.3.24 → topos_node-1.3.26}/topos/pipeline/job_runner.py +0 -0
  502. {topos_node-1.3.24 → topos_node-1.3.26}/topos/pipeline/job_store.py +0 -0
  503. {topos_node-1.3.24 → topos_node-1.3.26}/topos/pipeline/stages.py +0 -0
  504. {topos_node-1.3.24 → topos_node-1.3.26}/topos/pipeline/stub_enqueue.py +0 -0
  505. {topos_node-1.3.24 → topos_node-1.3.26}/topos/profiles.py +0 -0
  506. {topos_node-1.3.24 → topos_node-1.3.26}/topos/projections/__init__.py +0 -0
  507. {topos_node-1.3.24 → topos_node-1.3.26}/topos/projections/vector_index/__init__.py +0 -0
  508. {topos_node-1.3.24 → topos_node-1.3.26}/topos/projections/vector_index/base.py +0 -0
  509. {topos_node-1.3.24 → topos_node-1.3.26}/topos/projections/vector_index/builders.py +0 -0
  510. {topos_node-1.3.24 → topos_node-1.3.26}/topos/projections/vector_index/health_checks.py +0 -0
  511. {topos_node-1.3.24/topos/storage/adapters/sqlite → topos_node-1.3.26/topos/protocol}/__init__.py +0 -0
  512. {topos_node-1.3.24 → topos_node-1.3.26}/topos/protocol/narrowing_vocabulary.json +0 -0
  513. {topos_node-1.3.24 → topos_node-1.3.26}/topos/protocol/query_field_contract.json +0 -0
  514. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/__init__.py +0 -0
  515. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/audit.py +0 -0
  516. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/cohort_resolvers.py +0 -0
  517. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/ddr.py +0 -0
  518. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/disclosure.py +0 -0
  519. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/entity_window.py +0 -0
  520. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/exclusion.py +0 -0
  521. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/game_layer.py +0 -0
  522. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/grant_cache.py +0 -0
  523. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/intent.py +0 -0
  524. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/manifest.py +0 -0
  525. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/manifest_validation.py +0 -0
  526. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/minimizer.py +0 -0
  527. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/narrowing.py +0 -0
  528. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/negotiation.py +0 -0
  529. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/planner.py +0 -0
  530. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/runtime.py +0 -0
  531. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/scope_arbiter.py +0 -0
  532. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/scope_classifier.py +0 -0
  533. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/scope_head.py +0 -0
  534. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/scope_registry.json +0 -0
  535. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/scope_registry_loader.py +0 -0
  536. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/scope_shadow.py +0 -0
  537. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/session.py +0 -0
  538. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/source_generation.py +0 -0
  539. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/truth_facts.py +0 -0
  540. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/truth_prompts.py +0 -0
  541. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/turn_classifier.py +0 -0
  542. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/verify.py +0 -0
  543. {topos_node-1.3.24 → topos_node-1.3.26}/topos/query/verify_modes.py +0 -0
  544. {topos_node-1.3.24 → topos_node-1.3.26}/topos/rate_limit.py +0 -0
  545. {topos_node-1.3.24 → topos_node-1.3.26}/topos/routines/__init__.py +0 -0
  546. {topos_node-1.3.24 → topos_node-1.3.26}/topos/routines/schema.py +0 -0
  547. {topos_node-1.3.24 → topos_node-1.3.26}/topos/runtime_housekeeping.py +0 -0
  548. {topos_node-1.3.24 → topos_node-1.3.26}/topos/runtime_shutdown.py +0 -0
  549. {topos_node-1.3.24 → topos_node-1.3.26}/topos/runtime_update.py +0 -0
  550. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sanitization/__init__.py +0 -0
  551. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sanitization/nsfw_classifier.py +0 -0
  552. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sanitization/ollama_transforms.py +0 -0
  553. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sanitization/prewarm.py +0 -0
  554. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sanitization/privacy_filter.py +0 -0
  555. {topos_node-1.3.24 → topos_node-1.3.26}/topos/scope_resolution.py +0 -0
  556. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/__init__.py +0 -0
  557. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/container.py +0 -0
  558. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/embeddings/__init__.py +0 -0
  559. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/embeddings/base.py +0 -0
  560. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/embeddings/local.py +0 -0
  561. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/embeddings/remote.py +0 -0
  562. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/interfaces.py +0 -0
  563. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/llm/__init__.py +0 -0
  564. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/llm/base.py +0 -0
  565. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/llm/openai.py +0 -0
  566. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/local.py +0 -0
  567. {topos_node-1.3.24 → topos_node-1.3.26}/topos/services/postgres.py +0 -0
  568. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/__init__.py +0 -0
  569. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/bundled_canonical_triples.py +0 -0
  570. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/canonical_signal_defaults.py +0 -0
  571. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/declared_field_map_spec.py +0 -0
  572. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/definitions.py +0 -0
  573. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/install_service.py +0 -0
  574. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/runtime_install.py +0 -0
  575. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/scrub_attribution.py +0 -0
  576. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sources/scrub_service.py +0 -0
  577. {topos_node-1.3.24 → topos_node-1.3.26}/topos/startup_banner.py +0 -0
  578. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/__init__.py +0 -0
  579. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/adapters/__init__.py +0 -0
  580. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/adapters/factory.py +0 -0
  581. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/adapters/fakes.py +0 -0
  582. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/adapters/postgres/stores.py +0 -0
  583. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/adapters/protocols.py +0 -0
  584. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/adapters/sqlite/stores.py +0 -0
  585. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  586. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/__init__.py +0 -0
  587. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/activity_tables.py +0 -0
  588. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  589. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  590. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  591. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/ai_chat/model.py +0 -0
  592. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/ai_chat/tables.py +0 -0
  593. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  594. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/canonical_store.py +0 -0
  595. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/conversations_tables.py +0 -0
  596. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/journal_repair.py +0 -0
  597. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/mapping_store.py +0 -0
  598. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/canonical/postgres.py +0 -0
  599. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/__init__.py +0 -0
  600. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/client.py +0 -0
  601. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/connection_tuning.py +0 -0
  602. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/__init__.py +0 -0
  603. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  604. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  605. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
  606. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  607. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  608. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/backup.py +0 -0
  609. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  610. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  611. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  612. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  613. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/complexity_v1.py +0 -0
  614. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  615. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  616. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/documents_v1.py +0 -0
  617. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
  618. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
  619. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
  620. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
  621. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
  622. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  623. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
  624. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
  625. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
  626. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
  627. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/episodes_v1.py +0 -0
  628. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  629. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  630. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  631. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  632. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  633. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  634. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
  635. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
  636. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
  637. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  638. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
  639. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  640. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
  641. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  642. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  643. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  644. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/signal_objects.py +0 -0
  645. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  646. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  647. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
  648. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  649. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  650. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  651. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  652. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  653. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  654. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  655. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  656. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  657. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  658. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  659. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  660. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  661. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  662. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  663. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  664. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  665. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  666. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  667. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/paths.py +0 -0
  668. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/postgres.py +0 -0
  669. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/schema.py +0 -0
  670. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/schema_probe.py +0 -0
  671. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/storage_breakdown.py +0 -0
  672. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/db/write_gate.py +0 -0
  673. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/enrichment/__init__.py +0 -0
  674. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  675. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  676. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/normalized/__init__.py +0 -0
  677. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/normalized/normalized_store.py +0 -0
  678. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/oplog/__init__.py +0 -0
  679. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/oplog/decision.py +0 -0
  680. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/oplog/oplog_store.py +0 -0
  681. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/oplog/postgres.py +0 -0
  682. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/person/identity_resolver.py +0 -0
  683. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/projections/__init__.py +0 -0
  684. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/projections/index_ops_store.py +0 -0
  685. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/projections/vector_index_store.py +0 -0
  686. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/raw/__init__.py +0 -0
  687. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/raw/browser_flat_tables.py +0 -0
  688. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/raw/file_store.py +0 -0
  689. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/raw/raw_store.py +0 -0
  690. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/raw/raw_tables_manager.py +0 -0
  691. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/raw/sqlite_raw_store.py +0 -0
  692. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/security/encryption.py +0 -0
  693. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/signal_identity.py +0 -0
  694. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/source_settings.py +0 -0
  695. {topos_node-1.3.24 → topos_node-1.3.26}/topos/storage/user_identity.py +0 -0
  696. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sync/__init__.py +0 -0
  697. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sync/client.py +0 -0
  698. {topos_node-1.3.24 → topos_node-1.3.26}/topos/sync_handlers.py +0 -0
  699. {topos_node-1.3.24 → topos_node-1.3.26}/topos/testing/__init__.py +0 -0
  700. {topos_node-1.3.24 → topos_node-1.3.26}/topos/testing/lifespan.py +0 -0
  701. {topos_node-1.3.24 → topos_node-1.3.26}/topos/uma_contact_enrichment.py +0 -0
  702. {topos_node-1.3.24 → topos_node-1.3.26}/topos/uma_filters.py +0 -0
  703. {topos_node-1.3.24 → topos_node-1.3.26}/topos/uma_resource_id.py +0 -0
  704. {topos_node-1.3.24 → topos_node-1.3.26}/topos/uma_rpt.py +0 -0
  705. {topos_node-1.3.24 → topos_node-1.3.26}/topos/upgrades/__init__.py +0 -0
  706. {topos_node-1.3.24 → topos_node-1.3.26}/topos/upgrades/runner.py +0 -0
  707. {topos_node-1.3.24 → topos_node-1.3.26}/topos/utils/base_object.py +0 -0
  708. {topos_node-1.3.24 → topos_node-1.3.26}/topos/websocket_client.py +0 -0
  709. {topos_node-1.3.24 → topos_node-1.3.26}/topos_node.egg-info/dependency_links.txt +0 -0
  710. {topos_node-1.3.24 → topos_node-1.3.26}/topos_node.egg-info/entry_points.txt +0 -0
  711. {topos_node-1.3.24 → topos_node-1.3.26}/topos_node.egg-info/requires.txt +0 -0
  712. {topos_node-1.3.24 → topos_node-1.3.26}/topos_node.egg-info/top_level.txt +0 -0
@@ -5,3 +5,4 @@ recursive-include topos *.json
5
5
  recursive-include shared *.json
6
6
  # Tray icon glyphs (topos/cli/assets) — without them the tray cannot render.
7
7
  recursive-include topos *.png
8
+ recursive-include topos/features/derivation/bundled_packs *.yaml
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 1.3.24
3
+ Version: 1.3.26
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "topos-node"
7
- version = "1.3.24"
7
+ version = "1.3.26"
8
8
  description = "Topos personal AI engine (FastAPI): local data, sync, control plane WebSocket client"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -1,6 +1,6 @@
1
1
  """Topos Control Plane Version Information."""
2
2
 
3
- __version__ = "1.3.24"
4
- __version_info__ = (1, 3, 24)
3
+ __version__ = "1.3.26"
4
+ __version_info__ = (1, 3, 26)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -73,6 +73,67 @@ def _record_identifier(record: Dict[str, Any]) -> Optional[str]:
73
73
  return None
74
74
 
75
75
 
76
+ def _processed_record_ids(conn, source_id: str, job_id: str, min_spec: int) -> set[str]:
77
+ """Ids this job has already run over, at or above ``min_spec``.
78
+
79
+ Distinct from coverage: coverage witnesses OUTPUT, this witnesses the RUN.
80
+ Returns empty on any failure — the caller then falls back to coverage-only
81
+ behaviour, which over-scans rather than skipping work that never happened.
82
+ """
83
+ if not conn:
84
+ return set()
85
+ try:
86
+ if not _table_exists(conn, "enrichment_record_progress"):
87
+ return set()
88
+ rows = conn.execute(
89
+ "SELECT record_id FROM enrichment_record_progress "
90
+ "WHERE source_id=? AND job_id=? AND COALESCE(spec_version, 0) >= ?",
91
+ (source_id, job_id, int(min_spec or 0)),
92
+ ).fetchall()
93
+ return {str(row[0]) for row in rows if row and row[0]}
94
+ except Exception as exc: # noqa: BLE001 — a marker read must never fail a backfill
95
+ logger.warning("enrichment_record_progress read failed for %s/%s: %s", source_id, job_id, exc)
96
+ return set()
97
+
98
+
99
+ def _mark_records_processed(
100
+ conn, source_id: str, job_id: str, records: List[Dict[str, Any]], spec_version: int
101
+ ) -> int:
102
+ """Record that this job ran over these records, whatever it produced.
103
+
104
+ Best-effort by design: the enrichment already happened and its output is
105
+ committed, so a failure here costs a future re-scan, never correctness.
106
+ """
107
+ if not conn or not records:
108
+ return 0
109
+ ids = [rid for rid in (_record_identifier(r) for r in records) if rid]
110
+ if not ids:
111
+ return 0
112
+ try:
113
+ if not _table_exists(conn, "enrichment_record_progress"):
114
+ return 0
115
+ from ..storage.db.write_gate import batched_writes
116
+
117
+ # `batched_writes` holds the write gate across the statements AND the
118
+ # commit. Doing the executemany bare and only calling commit_connection
119
+ # takes SQLite's write lock ungated, which the gate detects and warns
120
+ # about — it can deadlock-until-busy_timeout against whoever holds the
121
+ # gate, and this runs right after a long enrichment batch, when that is
122
+ # most likely.
123
+ with batched_writes(conn):
124
+ conn.executemany(
125
+ "INSERT INTO enrichment_record_progress "
126
+ "(source_id, job_id, record_id, spec_version) VALUES (?,?,?,?) "
127
+ "ON CONFLICT(source_id, job_id, record_id) DO UPDATE SET "
128
+ "spec_version=excluded.spec_version, processed_at=datetime('now')",
129
+ [(source_id, job_id, rid, int(spec_version or 0)) for rid in ids],
130
+ )
131
+ return len(ids)
132
+ except Exception as exc: # noqa: BLE001
133
+ logger.warning("enrichment_record_progress write failed for %s/%s: %s", source_id, job_id, exc)
134
+ return 0
135
+
136
+
76
137
  def _table_exists(conn, table: str) -> bool:
77
138
  try:
78
139
  row = conn.execute(
@@ -395,7 +456,11 @@ async def _generic_backfill_core(
395
456
  """
396
457
  import uuid as _uuid
397
458
 
398
- from ..enrichment.catalog import coverage_table_for_job, jobs_configured_for_source
459
+ from ..enrichment.catalog import (
460
+ catalog_spec_version,
461
+ coverage_table_for_job,
462
+ jobs_configured_for_source,
463
+ )
399
464
  from ..ingestion.canonical_pipeline import (
400
465
  load_canonical_records_for_signal,
401
466
  run_post_canonical_pipeline,
@@ -453,6 +518,18 @@ async def _generic_backfill_core(
453
518
  }
454
519
  records = [r for r in records if _record_identifier(r) not in done]
455
520
 
521
+ # Records this job has already RUN over, whatever it produced.
522
+ # Coverage tables only witness output, so without this a record
523
+ # that correctly yields nothing is re-scanned by every backfill
524
+ # forever (see enrichment_record_progress_v1). Computed once —
525
+ # this set is read per record, so building it inside the filter
526
+ # would issue one query per row.
527
+ already_run = _processed_record_ids(
528
+ db_conn, source_id, job_name, catalog_spec_version(job_name)
529
+ )
530
+ if already_run:
531
+ records = [r for r in records if _record_identifier(r) not in already_run]
532
+
456
533
  if isinstance(limit, int) and limit > 0:
457
534
  records = records[:limit]
458
535
 
@@ -507,11 +584,20 @@ async def _generic_backfill_core(
507
584
  processed = sum((result.get("records_created") or {}).values())
508
585
  errors = list(result.get("errors") or [])
509
586
 
587
+ # Every record in `records` was attempted, so every one is marked — that is
588
+ # the whole point, since `processed` above counts OUTPUT ROWS CREATED, not
589
+ # records attempted, and the two differ by exactly the empty results this
590
+ # marker exists to stop re-scanning.
591
+ marked = _mark_records_processed(
592
+ db_conn, source_id, job_name, records, catalog_spec_version(job_name)
593
+ )
594
+
510
595
  return {
511
596
  "rows_scanned": scanned,
512
597
  "rows_processed": int(processed),
513
598
  "rows_skipped": max(scanned - len(records), 0),
514
599
  "rows_failed": len(errors),
600
+ "rows_marked": marked,
515
601
  "errors": errors[:100],
516
602
  }
517
603
 
@@ -1115,7 +1201,23 @@ async def _get_enrichment_status_core(
1115
1201
  source_def = REGISTRY.get(source_id)
1116
1202
  if not source_def:
1117
1203
  raise ValueError(f"Source {source_id} not found")
1118
-
1204
+
1205
+ # Report what will ACTUALLY run, not the static definition.
1206
+ #
1207
+ # Every execution path resolves canonical jobs through
1208
+ # `effective_canonical_enrichment_jobs` (canonical_pipeline, ingestion
1209
+ # manager, the WS handler and `process_enrichment` all do), so a status
1210
+ # surface that reads `source_def.canonical_enrichment_jobs` directly
1211
+ # reports a DIFFERENT list than the engine runs the moment a per-source
1212
+ # override exists. Measured 2026-08-25: with `entities` enabled for
1213
+ # imessage via `PATCH /v1/sources/imessage/enrichments/entities`, the
1214
+ # override-aware lanes said `['canonical','signal']` while this endpoint
1215
+ # still said `['emo_27']` — which reads as "entity extraction is off"
1216
+ # when it is on, and cost real time diagnosing exactly that.
1217
+ from ..enrichment.source_overrides import effective_canonical_enrichment_jobs
1218
+
1219
+ effective_jobs = effective_canonical_enrichment_jobs(source_def)
1220
+
1119
1221
  # Get database connection
1120
1222
  db_conn = get_db_connection()
1121
1223
  if not db_conn:
@@ -1125,7 +1227,7 @@ async def _get_enrichment_status_core(
1125
1227
  "total_messages": 0,
1126
1228
  "processed_messages": 0,
1127
1229
  "unprocessed_messages": 0,
1128
- "enrichment_jobs": source_def.canonical_enrichment_jobs,
1230
+ "enrichment_jobs": effective_jobs,
1129
1231
  "enrichment_trigger": getattr(source_def, "enrichment_trigger", "automatic"),
1130
1232
  "message": "Database connection not available",
1131
1233
  }
@@ -1144,7 +1246,7 @@ async def _get_enrichment_status_core(
1144
1246
  "total_messages": 0,
1145
1247
  "processed_messages": 0,
1146
1248
  "unprocessed_messages": 0,
1147
- "enrichment_jobs": source_def.canonical_enrichment_jobs,
1249
+ "enrichment_jobs": effective_jobs,
1148
1250
  "enrichment_trigger": getattr(source_def, "enrichment_trigger", "automatic"),
1149
1251
  "message": "Canonical table does not exist yet",
1150
1252
  }
@@ -1182,7 +1284,7 @@ async def _get_enrichment_status_core(
1182
1284
  "total_messages": 0,
1183
1285
  "processed_messages": 0,
1184
1286
  "unprocessed_messages": 0,
1185
- "enrichment_jobs": source_def.canonical_enrichment_jobs,
1287
+ "enrichment_jobs": effective_jobs,
1186
1288
  "enrichment_trigger": getattr(source_def, "enrichment_trigger", "automatic"),
1187
1289
  "message": f"Error reading canonical table: {e}",
1188
1290
  }
@@ -1198,7 +1300,7 @@ async def _get_enrichment_status_core(
1198
1300
  "total_messages": total,
1199
1301
  "processed_messages": processed_count,
1200
1302
  "unprocessed_messages": unprocessed_count,
1201
- "enrichment_jobs": source_def.canonical_enrichment_jobs,
1303
+ "enrichment_jobs": effective_jobs,
1202
1304
  "enrichment_trigger": getattr(source_def, "enrichment_trigger", "automatic"),
1203
1305
  }
1204
1306
 
@@ -1266,7 +1368,13 @@ def _list_source_enrichments_core(source_id: str) -> Dict[str, Any]:
1266
1368
  raise ValueError(f"Source {source_id} not found")
1267
1369
 
1268
1370
  raw_jobs = list(getattr(source_def, "raw_enrichment_jobs", []) or [])
1269
- canonical_jobs = list(getattr(source_def, "canonical_enrichment_jobs", []) or [])
1371
+ # Override-aware, for the same reason as `_get_enrichment_status_core`:
1372
+ # this field named the static definition while `enrichments[].lanes`
1373
+ # (built from `jobs_configured_for_source` below) named the effective one,
1374
+ # so one response could disagree with itself about whether a job runs.
1375
+ from ..enrichment.source_overrides import effective_canonical_enrichment_jobs
1376
+
1377
+ canonical_jobs = effective_canonical_enrichment_jobs(source_def)
1270
1378
  implemented_backfills = sorted(
1271
1379
  enrichment_name
1272
1380
  for sid, enrichment_name in _RAW_SOURCE_BACKFILL_HANDLERS
@@ -709,6 +709,7 @@ async def dismiss_blackhole_notification(
709
709
  async def list_facts(
710
710
  predicate: Optional[str] = Query(default=None, max_length=80),
711
711
  dimension: Optional[str] = Query(default=None, max_length=40),
712
+ pack: Optional[str] = Query(default=None, max_length=60),
712
713
  include_closed: bool = Query(default=False),
713
714
  limit: int = Query(default=100, ge=1, le=500),
714
715
  offset: int = Query(default=0, ge=0),
@@ -724,6 +725,7 @@ async def list_facts(
724
725
  guard=owner_ui_guard(conn),
725
726
  predicate=predicate,
726
727
  dimension=dimension,
728
+ pack=pack,
727
729
  include_closed=include_closed,
728
730
  limit=limit,
729
731
  offset=offset,
@@ -1034,3 +1036,52 @@ async def complexity_influence(
1034
1036
  window_days=window_days,
1035
1037
  target=target,
1036
1038
  )
1039
+
1040
+
1041
+ @router.get("/derivation/packs")
1042
+ async def get_derivation_packs(_api_key: str = Depends(require_api_key)):
1043
+ """Lens catalog (W4.3): registry rows + live fact + quarantine counts."""
1044
+ from ..features.derivation.surfaces import list_packs
1045
+
1046
+ return list_packs(_entities_conn())
1047
+
1048
+
1049
+ @router.put("/derivation/packs/{pack_id}")
1050
+ async def put_derivation_pack(
1051
+ pack_id: str,
1052
+ enabled: bool = Body(..., embed=True),
1053
+ _api_key: str = Depends(require_api_key),
1054
+ ):
1055
+ from ..features.derivation.surfaces import set_pack_enabled
1056
+
1057
+ if not set_pack_enabled(_entities_conn(), pack_id, enabled):
1058
+ raise HTTPException(status_code=404, detail=f"unknown pack {pack_id}")
1059
+ return {"pack_id": pack_id, "enabled": enabled}
1060
+
1061
+
1062
+ @router.get("/facts/conflicts")
1063
+ async def get_fact_conflicts(
1064
+ limit: int = Query(default=100, ge=1, le=500),
1065
+ _api_key: str = Depends(require_api_key),
1066
+ ):
1067
+ """The A3 quarantine + Tier-2 conflict review queue (W4.2)."""
1068
+ from ..features.derivation.surfaces import list_conflicts
1069
+
1070
+ return {"conflicts": list_conflicts(_entities_conn(), limit=limit)}
1071
+
1072
+
1073
+ @router.post("/facts/conflicts/resolve")
1074
+ async def post_fact_conflict_resolution(
1075
+ conflict_id: str = Body(...),
1076
+ status: str = Body(..., description="dismissed | accepted"),
1077
+ _api_key: str = Depends(require_api_key),
1078
+ ):
1079
+ from ..features.derivation.surfaces import resolve_conflict
1080
+
1081
+ try:
1082
+ ok = resolve_conflict(_entities_conn(), conflict_id, status)
1083
+ except ValueError as exc:
1084
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
1085
+ if not ok:
1086
+ raise HTTPException(status_code=404, detail=f"unknown conflict {conflict_id}")
1087
+ return {"conflict_id": conflict_id, "status": status}
@@ -183,6 +183,9 @@ class Settings(BaseSettings):
183
183
  topos_engine_service_url: Optional[str] = Field(None)
184
184
 
185
185
  topos_database_path: Optional[str] = Field(None)
186
+ # Packet resolution (PLAN_DERIVATION_LAYER.md): env default only; the per-database
187
+ # engine_config value overrides. Validated against RESOLUTIONS at read time.
188
+ topos_packet_resolution: str = Field("scores_only")
186
189
  topos_database_mode: str = Field("local")
187
190
  topos_database_service_url: Optional[str] = Field(None)
188
191
  topos_postgres_dsn: Optional[str] = Field(None)
@@ -400,6 +403,7 @@ settings = Settings()
400
403
  # --- P1.5 exposure-profile visibility (PLAN_PROVENANCE_SPLIT) -------------------------
401
404
  # Frozen engine_config key the UI toggle writes; a per-node bool the owner sets.
402
405
  ENGINE_CONFIG_KEY_EXPOSURE_PROFILE_VISIBLE = "exposure_profile_visible"
406
+ ENGINE_CONFIG_KEY_PACKET_RESOLUTION = "packet_resolution"
403
407
 
404
408
  _TRUE_STRINGS = frozenset({"1", "true", "t", "yes", "y", "on"})
405
409
  _FALSE_STRINGS = frozenset({"0", "false", "f", "no", "n", "off"})
@@ -458,6 +462,23 @@ def resolve_exposure_profile_visible(settings_obj: "Settings", conn=None) -> boo
458
462
  return _coerce_bool(raw, default)
459
463
 
460
464
 
465
+ def resolve_packet_resolution(settings_obj: "Settings", conn=None) -> str:
466
+ """Effective packet-resolution SETTING (before interlocks): the per-database
467
+ engine_config value ("packet_resolution") when set and valid, else the
468
+ env/settings default ("scores_only"). Interlocks (owner floor, model locality)
469
+ live in query.packet_resolution.effective_packet_resolution — this returns
470
+ only what the owner asked for."""
471
+ valid = ("scores_only", "facts", "facts_all")
472
+ default = str(getattr(settings_obj, "topos_packet_resolution", "") or "scores_only").strip().lower()
473
+ if default not in valid:
474
+ default = "scores_only"
475
+ raw = _read_engine_config_value(conn, ENGINE_CONFIG_KEY_PACKET_RESOLUTION)
476
+ if raw is None:
477
+ return default
478
+ value = str(raw).strip().lower()
479
+ return value if value in valid else default
480
+
481
+
461
482
  def exposure_profile_visible(conn=None) -> bool:
462
483
  """Module-level convenience: resolve against the global settings singleton
463
484
  and (when not passed) the process DB connection. Retrieval passes its own
@@ -59,6 +59,9 @@ _FAST_INBOUND_MESSAGE_TYPES = frozenset(
59
59
  "connection_info",
60
60
  "check_inbox_write",
61
61
  "list_waiting_routine_runs",
62
+ "list_active_routine_runs",
63
+ "list_expired_routine_runs",
64
+ "delete_routine_runs",
62
65
  "list_due_routines",
63
66
  "routine_has_active_run",
64
67
  "update_routine_run",
@@ -148,6 +148,7 @@ from .common import logger
148
148
  from .registry import HANDLERS, OWNER_ONLY_MESSAGE_TYPES, handles # noqa: F401
149
149
  from . import ( # noqa: F401 (imported for handler registration side effects)
150
150
  config,
151
+ derivation,
151
152
  sources,
152
153
  filter_lab,
153
154
  enrichment_lab,
@@ -565,3 +565,65 @@ async def handle_put_exposure_profile_config(message: Dict[str, Any]) -> Optiona
565
565
  }
566
566
  except Exception as exc: # noqa: BLE001
567
567
  return {"id": req_id, "status": "error", "error": str(exc)}
568
+
569
+
570
+ @handles("get_packet_resolution_config")
571
+ async def handle_get_packet_resolution_config(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
572
+ """Packet resolution (PLAN_DERIVATION_LAYER.md): the owner's setting PLUS the
573
+ effective state after interlocks, and the model that receives the packet — the
574
+ settings UI shows all three so the coupling is legible at the moment of decision."""
575
+ req_id = message.get("id")
576
+ conn = hub.get_db_connection()
577
+ if not conn:
578
+ return {"id": req_id, "status": "error", "error": "Database not available"}
579
+ try:
580
+ from ...query.packet_resolution import RESOLUTIONS, effective_packet_resolution
581
+
582
+ info = effective_packet_resolution(conn, requester_id="owner", disclosure_tier="owner_raw")
583
+ return {"id": req_id, "status": "ok",
584
+ "payload": {"status": "ok", "options": list(RESOLUTIONS), **info}}
585
+ except Exception as exc: # noqa: BLE001
586
+ return {"id": req_id, "status": "error", "error": str(exc)}
587
+
588
+
589
+ @handles("put_packet_resolution_config")
590
+ async def handle_put_packet_resolution_config(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
591
+ """Set packet resolution. On a DOWNGRADE, cached query artifacts are expired
592
+ immediately: the cache key isolates resolutions going forward, but artifacts
593
+ minted under the higher resolution still HOLD that content — "I turned it off"
594
+ must mean off now, not after a TTL."""
595
+ req_id = message.get("id")
596
+ conn = hub.get_db_connection()
597
+ if not conn:
598
+ return {"id": req_id, "status": "error", "error": "Database not available"}
599
+ payload = message.get("payload") or {}
600
+ value = str(payload.get("packet_resolution") or "").strip().lower()
601
+ try:
602
+ from ...config.settings import (
603
+ ENGINE_CONFIG_KEY_PACKET_RESOLUTION,
604
+ resolve_packet_resolution,
605
+ )
606
+ from ...query.packet_resolution import (
607
+ RESOLUTIONS,
608
+ effective_packet_resolution,
609
+ resolution_order,
610
+ )
611
+
612
+ if value not in RESOLUTIONS:
613
+ return {"id": req_id, "status": "error",
614
+ "error": f"packet_resolution must be one of {list(RESOLUTIONS)}"}
615
+ previous = resolve_packet_resolution(settings, conn)
616
+ set_engine_config_value(conn, ENGINE_CONFIG_KEY_PACKET_RESOLUTION, value)
617
+ expired = 0
618
+ if resolution_order(value) < resolution_order(previous):
619
+ from ...storage.db.write_gate import commit_connection, with_db_write
620
+
621
+ with with_db_write():
622
+ cur = conn.execute("DELETE FROM query_artifacts")
623
+ expired = cur.rowcount if cur.rowcount is not None else 0
624
+ commit_connection(conn)
625
+ info = effective_packet_resolution(conn, requester_id="owner", disclosure_tier="owner_raw")
626
+ return {"id": req_id, "status": "ok",
627
+ "payload": {"status": "ok", "previous": previous, "expired_artifacts": expired, **info}}
628
+ except Exception as exc: # noqa: BLE001
629
+ return {"id": req_id, "status": "error", "error": str(exc)}
@@ -0,0 +1,79 @@
1
+ """Derivation-layer handlers (W4 surfaces) — thin delegates over
2
+ features/derivation/surfaces.py (shared with the HTTP routes in api/signal.py)."""
3
+
4
+ from __future__ import annotations
5
+
6
+ from typing import Any, Dict, Optional
7
+
8
+ import topos.core.handlers as hub
9
+ from .registry import handles
10
+
11
+
12
+ @handles("get_derivation_packs")
13
+ async def handle_get_derivation_packs(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
14
+ req_id = message.get("id")
15
+ conn = hub.get_db_connection()
16
+ if not conn:
17
+ return {"id": req_id, "status": "error", "error": "Database not available"}
18
+ try:
19
+ from ...features.derivation.surfaces import list_packs
20
+ return {"id": req_id, "status": "ok", "payload": {"status": "ok", **list_packs(conn)}}
21
+ except Exception as exc: # noqa: BLE001
22
+ return {"id": req_id, "status": "error", "error": str(exc)}
23
+
24
+
25
+ @handles("put_derivation_pack")
26
+ async def handle_put_derivation_pack(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
27
+ req_id = message.get("id")
28
+ conn = hub.get_db_connection()
29
+ if not conn:
30
+ return {"id": req_id, "status": "error", "error": "Database not available"}
31
+ payload = message.get("payload") or {}
32
+ pack_id = str(payload.get("pack_id") or "").strip()
33
+ enabled = payload.get("enabled")
34
+ if not pack_id or not isinstance(enabled, bool):
35
+ return {"id": req_id, "status": "error", "error": "pack_id and enabled (bool) required"}
36
+ try:
37
+ from ...features.derivation.surfaces import set_pack_enabled
38
+ if not set_pack_enabled(conn, pack_id, enabled):
39
+ return {"id": req_id, "status": "error", "error": f"unknown pack {pack_id}"}
40
+ return {"id": req_id, "status": "ok",
41
+ "payload": {"status": "ok", "pack_id": pack_id, "enabled": enabled}}
42
+ except Exception as exc: # noqa: BLE001
43
+ return {"id": req_id, "status": "error", "error": str(exc)}
44
+
45
+
46
+ @handles("get_fact_conflicts")
47
+ async def handle_get_fact_conflicts(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
48
+ req_id = message.get("id")
49
+ conn = hub.get_db_connection()
50
+ if not conn:
51
+ return {"id": req_id, "status": "error", "error": "Database not available"}
52
+ payload = message.get("payload") or {}
53
+ try:
54
+ from ...features.derivation.surfaces import list_conflicts
55
+ rows = list_conflicts(conn, limit=int(payload.get("limit") or 100))
56
+ return {"id": req_id, "status": "ok", "payload": {"status": "ok", "conflicts": rows}}
57
+ except Exception as exc: # noqa: BLE001
58
+ return {"id": req_id, "status": "error", "error": str(exc)}
59
+
60
+
61
+ @handles("put_fact_conflict")
62
+ async def handle_put_fact_conflict(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
63
+ req_id = message.get("id")
64
+ conn = hub.get_db_connection()
65
+ if not conn:
66
+ return {"id": req_id, "status": "error", "error": "Database not available"}
67
+ payload = message.get("payload") or {}
68
+ cid = str(payload.get("conflict_id") or "").strip()
69
+ status = str(payload.get("status") or "").strip()
70
+ try:
71
+ from ...features.derivation.surfaces import resolve_conflict
72
+ if not resolve_conflict(conn, cid, status):
73
+ return {"id": req_id, "status": "error", "error": f"unknown conflict {cid}"}
74
+ return {"id": req_id, "status": "ok",
75
+ "payload": {"status": "ok", "conflict_id": cid, "new_status": status}}
76
+ except ValueError as exc:
77
+ return {"id": req_id, "status": "error", "error": str(exc)}
78
+ except Exception as exc: # noqa: BLE001
79
+ return {"id": req_id, "status": "error", "error": str(exc)}
@@ -297,6 +297,57 @@ async def handle_routine_has_active_run(message: Dict[str, Any]) -> Optional[Dic
297
297
  "payload": {"active": active},
298
298
  }
299
299
 
300
+ @handles("list_active_routine_runs")
301
+ async def handle_list_active_routine_runs(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
302
+ req_id = message.get("id")
303
+ from ...routines import store as routines_store
304
+
305
+ conn = hub.get_db_connection()
306
+ if not conn:
307
+ return {"id": req_id, "status": "error", "error": "Database not available"}
308
+ pl = message.get("payload") or {}
309
+ engine_id = str(pl.get("engine_id") or "").strip()
310
+ if not engine_id:
311
+ return {"id": req_id, "status": "error", "error": "engine_id required"}
312
+ rows = await run_db_read(routines_store.list_active_runs, engine_id=engine_id)
313
+ return {"id": req_id, "status": "ok", "payload": {"runs": rows}}
314
+
315
+ @handles("list_expired_routine_runs")
316
+ async def handle_list_expired_routine_runs(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
317
+ req_id = message.get("id")
318
+ from ...routines import store as routines_store
319
+
320
+ conn = hub.get_db_connection()
321
+ if not conn:
322
+ return {"id": req_id, "status": "error", "error": "Database not available"}
323
+ pl = message.get("payload") or {}
324
+ engine_id = str(pl.get("engine_id") or "").strip()
325
+ cutoff = str(pl.get("cutoff") or "").strip()
326
+ if not engine_id or not cutoff:
327
+ return {"id": req_id, "status": "error", "error": "engine_id and cutoff required"}
328
+ rows = await run_db_read(
329
+ routines_store.list_expired_runs,
330
+ engine_id=engine_id,
331
+ cutoff=cutoff,
332
+ limit=int(pl.get("limit") or 500),
333
+ )
334
+ return {"id": req_id, "status": "ok", "payload": {"runs": rows}}
335
+
336
+ @handles("delete_routine_runs")
337
+ async def handle_delete_routine_runs(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
338
+ req_id = message.get("id")
339
+ from ...routines import store as routines_store
340
+
341
+ conn = hub.get_db_connection()
342
+ if not conn:
343
+ return {"id": req_id, "status": "error", "error": "Database not available"}
344
+ pl = message.get("payload") or {}
345
+ run_ids = pl.get("run_ids")
346
+ if not isinstance(run_ids, list) or not run_ids:
347
+ return {"id": req_id, "status": "error", "error": "run_ids required"}
348
+ deleted = await run_db_write(routines_store.delete_runs, run_ids)
349
+ return {"id": req_id, "status": "ok", "payload": {"deleted": int(deleted or 0)}}
350
+
300
351
  @handles("advance_routine_next_run_at")
301
352
  async def handle_advance_routine_next_run_at(message: Dict[str, Any]) -> Optional[Dict[str, Any]]:
302
353
  req_id = message.get("id")
@@ -584,6 +584,7 @@ async def handle_signal_list_facts(message: Dict[str, Any]) -> Optional[Dict[str
584
584
  guard=guard_from_message(conn, message),
585
585
  predicate=payload.get("predicate"),
586
586
  dimension=payload.get("dimension"),
587
+ pack=payload.get("pack"),
587
588
  include_closed=bool(payload.get("include_closed")),
588
589
  limit=min(int(payload.get("limit") or 100), 500),
589
590
  offset=max(0, int(payload.get("offset") or 0)),
@@ -7,6 +7,7 @@ from .canonical.embeddings_job import EmbeddingsJob
7
7
  from .canonical.entities_job import EntitiesJob
8
8
  from .canonical.emo_27_job import Emo27Job
9
9
  from .canonical.fact_extraction_job import FactExtractionJob
10
+ from .canonical.derivation_job import DerivationJob
10
11
  from .canonical.goal_extraction_job import GoalExtractionJob
11
12
  from .canonical.relationship_edges_job import RelationshipEdgesJob
12
13
  from .canonical.sentiment_job import SentimentJob
@@ -30,6 +31,7 @@ CANONICAL_JOBS = [
30
31
  StatisticsJob(),
31
32
  FactExtractionJob(),
32
33
  TimelineJob(),
34
+ DerivationJob(), # W2.3: ontology-pack derivation (after entities/facts — needs the spine)
33
35
  ]
34
36
 
35
37
  SIGNAL_DERIVATION_JOBS = [
@@ -67,6 +69,7 @@ __all__ = [
67
69
  "AvailabilityScoresJob",
68
70
  "StatisticsJob",
69
71
  "FactExtractionJob",
72
+ "DerivationJob",
70
73
  "TimelineJob",
71
74
  "AttentionTriageJob",
72
75
  "TopicClusterJob",