topos-node 1.3.29__tar.gz → 1.3.31__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 (720) hide show
  1. {topos_node-1.3.29/topos_node.egg-info → topos_node-1.3.31}/PKG-INFO +1 -1
  2. {topos_node-1.3.29 → topos_node-1.3.31}/pyproject.toml +1 -1
  3. {topos_node-1.3.29 → topos_node-1.3.31}/topos/__version__.py +2 -2
  4. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/signal.py +50 -0
  5. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/model_packs.py +6 -1
  6. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/derivation.py +55 -0
  7. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +2 -2
  8. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/health.mental.yaml +3 -3
  9. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/places.mobility.yaml +2 -2
  10. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/work.career.yaml +4 -4
  11. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/surfaces.py +189 -3
  12. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/template.py +2 -2
  13. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/writer.py +31 -13
  14. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/maintenance.py +7 -2
  15. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/facts/reads.py +3 -0
  16. {topos_node-1.3.29 → topos_node-1.3.31}/topos/protocol/handled_message_types.json +3 -0
  17. {topos_node-1.3.29 → topos_node-1.3.31}/topos/protocol/narrowing_vocabulary.json +1 -0
  18. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/facts_direct.py +18 -0
  19. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/game_layer.py +17 -0
  20. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/narrowing.py +1 -0
  21. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/packet_resolution.py +17 -2
  22. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/pipeline.py +2 -1
  23. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/retrieval.py +38 -1
  24. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/sqlite/stores.py +41 -9
  25. topos_node-1.3.31/topos/storage/db/migrations/conflict_provenance_v1.py +35 -0
  26. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/registry.py +5 -0
  27. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/registry_checksums.json +1 -0
  28. {topos_node-1.3.29 → topos_node-1.3.31}/topos/upgrades/manifests.json +12 -0
  29. {topos_node-1.3.29 → topos_node-1.3.31/topos_node.egg-info}/PKG-INFO +1 -1
  30. {topos_node-1.3.29 → topos_node-1.3.31}/topos_node.egg-info/SOURCES.txt +1 -0
  31. {topos_node-1.3.29 → topos_node-1.3.31}/LICENSE +0 -0
  32. {topos_node-1.3.29 → topos_node-1.3.31}/MANIFEST.in +0 -0
  33. {topos_node-1.3.29 → topos_node-1.3.31}/README.md +0 -0
  34. {topos_node-1.3.29 → topos_node-1.3.31}/setup.cfg +0 -0
  35. {topos_node-1.3.29 → topos_node-1.3.31}/shared/__init__.py +0 -0
  36. {topos_node-1.3.29 → topos_node-1.3.31}/shared/filtering.py +0 -0
  37. {topos_node-1.3.29 → topos_node-1.3.31}/shared/schema_registry.py +0 -0
  38. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_active_database_binding.py +0 -0
  39. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_active_ingestion_binding.py +0 -0
  40. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_extensions.py +0 -0
  41. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_gate_leg_hermeticity.py +0 -0
  42. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_llm_integrations_storage.py +0 -0
  43. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_local_gate_composition.py +0 -0
  44. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_owner_database_hermeticity.py +0 -0
  45. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_prewarm_first_run.py +0 -0
  46. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_profile_hygiene.py +0 -0
  47. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_profiles.py +0 -0
  48. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_protocol_handled_types.py +0 -0
  49. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_query_field_contract.py +0 -0
  50. {topos_node-1.3.29 → topos_node-1.3.31}/tests/test_system_computer_name.py +0 -0
  51. {topos_node-1.3.29 → topos_node-1.3.31}/topos/__init__.py +0 -0
  52. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/__init__.py +0 -0
  53. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/duckdb_adapter.py +0 -0
  54. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/messenger_communities.py +0 -0
  55. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/messenger_graph.py +0 -0
  56. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/messenger_labels.py +0 -0
  57. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/profiles.py +0 -0
  58. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/query_engine.py +0 -0
  59. {topos_node-1.3.29 → topos_node-1.3.31}/topos/analytics/raw_queries.py +0 -0
  60. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/__init__.py +0 -0
  61. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/analytics.py +0 -0
  62. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/app_registry.py +0 -0
  63. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/backup.py +0 -0
  64. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/community_naming_config.py +0 -0
  65. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/compute_remote.py +0 -0
  66. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/conversation_context.py +0 -0
  67. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/data_commit.py +0 -0
  68. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/data_explorer_table_prefs.py +0 -0
  69. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/database_explorer.py +0 -0
  70. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/db.py +0 -0
  71. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/device.py +0 -0
  72. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/engine_run.py +0 -0
  73. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/enrichment.py +0 -0
  74. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/enrichment_lab.py +0 -0
  75. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/facts_llm_config.py +0 -0
  76. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/filter_lab.py +0 -0
  77. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/health.py +0 -0
  78. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/home_chat.py +0 -0
  79. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/ingestion_api.py +0 -0
  80. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/ingestion_compat.py +0 -0
  81. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/ingestion_sources.py +0 -0
  82. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/intelligence_lifecycle.py +0 -0
  83. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/llm.py +0 -0
  84. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/local_mcp.py +0 -0
  85. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/messenger_analytics.py +0 -0
  86. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/privacy_disclose.py +0 -0
  87. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/query_api.py +0 -0
  88. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/runtime_bootstrap.py +0 -0
  89. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/sanitization_ollama_config.py +0 -0
  90. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/shell.py +0 -0
  91. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/signal_extraction_config.py +0 -0
  92. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/source_install.py +0 -0
  93. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/source_scrub.py +0 -0
  94. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/sources.py +0 -0
  95. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/sources_overview.py +0 -0
  96. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/sync.py +0 -0
  97. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/tool_index.py +0 -0
  98. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/ui_config.py +0 -0
  99. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/uma_data.py +0 -0
  100. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/upgrades.py +0 -0
  101. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/usage.py +0 -0
  102. {topos_node-1.3.29 → topos_node-1.3.31}/topos/api/user_identity.py +0 -0
  103. {topos_node-1.3.29 → topos_node-1.3.31}/topos/app.py +0 -0
  104. {topos_node-1.3.29 → topos_node-1.3.31}/topos/auth.py +0 -0
  105. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/__init__.py +0 -0
  106. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/declared_field_map.py +0 -0
  107. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/__init__.py +0 -0
  108. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/base.py +0 -0
  109. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
  110. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
  111. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/demo_mappers.py +0 -0
  112. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/documents_mapper.py +0 -0
  113. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
  114. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
  115. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/grok_mapper.py +0 -0
  116. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
  117. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/models.py +0 -0
  118. {topos_node-1.3.29 → topos_node-1.3.31}/topos/canonicalization/resolver.py +0 -0
  119. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/__init__.py +0 -0
  120. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/__main__.py +0 -0
  121. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/assets/topos_blk_rounded.png +0 -0
  122. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/assets/topos_white.png +0 -0
  123. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/commands.py +0 -0
  124. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/profile_cmd.py +0 -0
  125. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/reprocess_cmd.py +0 -0
  126. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/setup_models_cmd.py +0 -0
  127. {topos_node-1.3.29 → topos_node-1.3.31}/topos/cli/tray.py +0 -0
  128. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/__init__.py +0 -0
  129. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/conversation_context_llm.py +0 -0
  130. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/facts_llm.py +0 -0
  131. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/local_model_builds.py +0 -0
  132. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/node_function_providers.py +0 -0
  133. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/sanitization_ollama.py +0 -0
  134. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/settings.py +0 -0
  135. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/signal_extraction.py +0 -0
  136. {topos_node-1.3.29 → topos_node-1.3.31}/topos/config/uvicorn_logging.json +0 -0
  137. {topos_node-1.3.29 → topos_node-1.3.31}/topos/contacts/__init__.py +0 -0
  138. {topos_node-1.3.29 → topos_node-1.3.31}/topos/contacts/identity.py +0 -0
  139. {topos_node-1.3.29 → topos_node-1.3.31}/topos/control_plane_client.py +0 -0
  140. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/__init__.py +0 -0
  141. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/api_models.py +0 -0
  142. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/connection_resilience.py +0 -0
  143. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/db_health.py +0 -0
  144. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/device_helpers.py +0 -0
  145. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/errors.py +0 -0
  146. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/events.py +0 -0
  147. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/__init__.py +0 -0
  148. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/common.py +0 -0
  149. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/complexity.py +0 -0
  150. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/config.py +0 -0
  151. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/contacts_import.py +0 -0
  152. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/database_explorer.py +0 -0
  153. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/device.py +0 -0
  154. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/enrichment.py +0 -0
  155. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/enrichment_lab.py +0 -0
  156. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/filter_lab.py +0 -0
  157. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/graph_query.py +0 -0
  158. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/home_chat.py +0 -0
  159. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/ingest.py +0 -0
  160. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/messages.py +0 -0
  161. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/messenger_analytics.py +0 -0
  162. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/query.py +0 -0
  163. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/registry.py +0 -0
  164. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/routines.py +0 -0
  165. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/signal_features.py +0 -0
  166. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/sources.py +0 -0
  167. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/timeline_daily.py +0 -0
  168. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/tool_index.py +0 -0
  169. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/handlers/uma.py +0 -0
  170. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/logging.py +0 -0
  171. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/metrics.py +0 -0
  172. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/routine_access.py +0 -0
  173. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/startup_banner.py +0 -0
  174. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/state.py +0 -0
  175. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/table_layers.py +0 -0
  176. {topos_node-1.3.29 → topos_node-1.3.31}/topos/core/types.py +0 -0
  177. {topos_node-1.3.29 → topos_node-1.3.31}/topos/data_explorer_row_delete.py +0 -0
  178. {topos_node-1.3.29 → topos_node-1.3.31}/topos/data_explorer_table_prefs.py +0 -0
  179. {topos_node-1.3.29 → topos_node-1.3.31}/topos/data_explorer_tables.py +0 -0
  180. {topos_node-1.3.29 → topos_node-1.3.31}/topos/disclosure/__init__.py +0 -0
  181. {topos_node-1.3.29 → topos_node-1.3.31}/topos/disclosure/canonical_writer.py +0 -0
  182. {topos_node-1.3.29 → topos_node-1.3.31}/topos/disclosure/content_policy.py +0 -0
  183. {topos_node-1.3.29 → topos_node-1.3.31}/topos/disclosure/field_registry.py +0 -0
  184. {topos_node-1.3.29 → topos_node-1.3.31}/topos/disclosure/privacy_layer.py +0 -0
  185. {topos_node-1.3.29 → topos_node-1.3.31}/topos/disclosure/tier.py +0 -0
  186. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/__init__.py +0 -0
  187. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/__init__.py +0 -0
  188. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/base.py +0 -0
  189. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/generative_prompts.py +0 -0
  190. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/generative_response.py +0 -0
  191. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/huggingface.py +0 -0
  192. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/ollama.py +0 -0
  193. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/openai.py +0 -0
  194. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/openai_compatible.py +0 -0
  195. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/redpill.py +0 -0
  196. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/backends/stub.py +0 -0
  197. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/client.py +0 -0
  198. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/disk_space.py +0 -0
  199. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/engine.py +0 -0
  200. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/intake.py +0 -0
  201. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/memory_utils.py +0 -0
  202. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/model_cache.py +0 -0
  203. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/ollama_install.py +0 -0
  204. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/ollama_pull.py +0 -0
  205. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/ollama_setup_guidance.py +0 -0
  206. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/pipeline_memory.py +0 -0
  207. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/queue_manager.py +0 -0
  208. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/registration.py +0 -0
  209. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/result_formatter.py +0 -0
  210. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/router.py +0 -0
  211. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/scoped_token.py +0 -0
  212. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/tasks.py +0 -0
  213. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/torch_runtime.py +0 -0
  214. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/transport.py +0 -0
  215. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/usage_guard.py +0 -0
  216. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/usage_observation.py +0 -0
  217. {topos_node-1.3.29 → topos_node-1.3.31}/topos/engine/validator.py +0 -0
  218. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/__init__.py +0 -0
  219. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/catalog.py +0 -0
  220. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/derivation_recovery.py +0 -0
  221. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/derived_tables.py +0 -0
  222. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/job_readiness.py +0 -0
  223. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/job_writer.py +0 -0
  224. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/__init__.py +0 -0
  225. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/base.py +0 -0
  226. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/__init__.py +0 -0
  227. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
  228. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
  229. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
  230. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
  231. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
  232. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
  233. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
  234. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
  235. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
  236. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
  237. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
  238. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
  239. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
  240. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
  241. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
  242. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
  243. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
  244. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
  245. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
  246. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
  247. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/raw/__init__.py +0 -0
  248. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
  249. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/raw/language_job.py +0 -0
  250. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
  251. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
  252. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/model_overrides.py +0 -0
  253. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/models/__init__.py +0 -0
  254. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/models/manager.py +0 -0
  255. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/models/mvp_defaults.py +0 -0
  256. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/models/registry.py +0 -0
  257. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/models/versioning.py +0 -0
  258. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/orchestrator.py +0 -0
  259. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/pipeline_activity.py +0 -0
  260. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/processor.py +0 -0
  261. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/progress_bar.py +0 -0
  262. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/registry_contract.py +0 -0
  263. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/signal_derivation_config.json +0 -0
  264. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment/source_overrides.py +0 -0
  265. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment_lab/__init__.py +0 -0
  266. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment_lab/bundles.py +0 -0
  267. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment_lab/model_resolve.py +0 -0
  268. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment_lab/schema.py +0 -0
  269. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment_lab/service.py +0 -0
  270. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment_lab/store.py +0 -0
  271. {topos_node-1.3.29 → topos_node-1.3.31}/topos/enrichment_lab/worker.py +0 -0
  272. {topos_node-1.3.29 → topos_node-1.3.31}/topos/evals/__init__.py +0 -0
  273. {topos_node-1.3.29 → topos_node-1.3.31}/topos/evals/enrichment_eval.py +0 -0
  274. {topos_node-1.3.29 → topos_node-1.3.31}/topos/extensions.py +0 -0
  275. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/__init__.py +0 -0
  276. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/canonical.py +0 -0
  277. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/engine.py +0 -0
  278. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/entropy.py +0 -0
  279. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/focus.py +0 -0
  280. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/graph_metrics.py +0 -0
  281. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/influence.py +0 -0
  282. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/projection.py +0 -0
  283. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/snapshots.py +0 -0
  284. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/store.py +0 -0
  285. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/topic_merge.py +0 -0
  286. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/topics.py +0 -0
  287. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/topics_daily.py +0 -0
  288. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/complexity/volatility.py +0 -0
  289. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/__init__.py +0 -0
  290. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
  291. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
  292. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
  293. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
  294. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
  295. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
  296. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
  297. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
  298. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
  299. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
  300. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
  301. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
  302. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
  303. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
  304. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
  305. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
  306. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
  307. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
  308. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
  309. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
  310. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
  311. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
  312. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
  313. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
  314. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
  315. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
  316. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
  317. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
  318. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
  319. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
  320. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/candidates.py +0 -0
  321. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/guard.py +0 -0
  322. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/packs.py +0 -0
  323. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/prefilter.py +0 -0
  324. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/registry.py +0 -0
  325. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/report_card.py +0 -0
  326. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/router.py +0 -0
  327. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/synthesize.py +0 -0
  328. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/derivation/verify.py +0 -0
  329. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/__init__.py +0 -0
  330. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/affinity.py +0 -0
  331. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/affinity_owner.py +0 -0
  332. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/affinity_quality.py +0 -0
  333. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/community_names.py +0 -0
  334. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/community_naming.py +0 -0
  335. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/consolidation.py +0 -0
  336. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/context_vectors.py +0 -0
  337. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/cypher.py +0 -0
  338. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/declared_mappings.py +0 -0
  339. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/dossier.py +0 -0
  340. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/edges.py +0 -0
  341. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/fact_materializer.py +0 -0
  342. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/graph_enrichers.py +0 -0
  343. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/graph_refresh.py +0 -0
  344. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/graph_search.py +0 -0
  345. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/linking.py +0 -0
  346. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/reads.py +0 -0
  347. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/rebuild_subprocess.py +0 -0
  348. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/entities/resolver.py +0 -0
  349. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/facts/__init__.py +0 -0
  350. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/facts/extract.py +0 -0
  351. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/facts/llm_extract.py +0 -0
  352. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/facts/store.py +0 -0
  353. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/facts/verdicts.py +0 -0
  354. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/fit/evaluator.py +0 -0
  355. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/fit/opportunity_types.json +0 -0
  356. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/__init__.py +0 -0
  357. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/blackhole.py +0 -0
  358. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/blackhole_guard.py +0 -0
  359. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/blackhole_llm.py +0 -0
  360. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
  361. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/derived_scrub.py +0 -0
  362. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/exclusions.py +0 -0
  363. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/lifecycle/gc.py +0 -0
  364. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/provenance/__init__.py +0 -0
  365. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/provenance/posture.py +0 -0
  366. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/provenance/roles.py +0 -0
  367. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/__init__.py +0 -0
  368. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/brief_canonical_loader.py +0 -0
  369. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/brief_ontology.py +0 -0
  370. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/brief_renderer.py +0 -0
  371. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/brief_schemas.py +0 -0
  372. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/chunking.py +0 -0
  373. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/cluster_labels.py +0 -0
  374. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/conversation_context.py +0 -0
  375. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/data_health.py +0 -0
  376. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/brief_ontologies.json +0 -0
  377. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/intentions.json +0 -0
  378. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/interests.json +0 -0
  379. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/memory.json +0 -0
  380. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/places.json +0 -0
  381. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/profile.json +0 -0
  382. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/relationships.json +0 -0
  383. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/resources.json +0 -0
  384. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
  385. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/time.json +0 -0
  386. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/wellbeing.json +0 -0
  387. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/definitions/work.json +0 -0
  388. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/derived_spec.py +0 -0
  389. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/dimension_briefs.py +0 -0
  390. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/dimension_definition_loader.py +0 -0
  391. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/dimension_profiles.py +0 -0
  392. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/dimension_registry.py +0 -0
  393. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/embed_context.py +0 -0
  394. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/extraction/artifact_router.py +0 -0
  395. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/extraction/artifact_store.py +0 -0
  396. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/extraction/rule_extractors.py +0 -0
  397. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/graph_sanitize.py +0 -0
  398. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/hybrid_search.py +0 -0
  399. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/incremental_clustering.py +0 -0
  400. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/model_recommendations.py +0 -0
  401. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/query_embed_cache.py +0 -0
  402. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/schemas.py +0 -0
  403. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/service.py +0 -0
  404. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/signal_object_store.py +0 -0
  405. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/source_hydration.py +0 -0
  406. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/structured_signal.py +0 -0
  407. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/tool_index.py +0 -0
  408. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/topic_clustering.py +0 -0
  409. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/typed_stores/aggregates.py +0 -0
  410. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/typed_stores/commitments.py +0 -0
  411. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/typed_stores/rhythm.py +0 -0
  412. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
  413. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/vector_codec.py +0 -0
  414. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/vector_math.py +0 -0
  415. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/signal/vector_settings.py +0 -0
  416. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/stats/__init__.py +0 -0
  417. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/stats/definitions.py +0 -0
  418. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/stats/engine.py +0 -0
  419. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/stats/fold.py +0 -0
  420. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/stats/insights.py +0 -0
  421. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/timeline_projection.py +0 -0
  422. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/timeline_rollup.py +0 -0
  423. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/triage/__init__.py +0 -0
  424. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/triage/badges.py +0 -0
  425. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/triage/daily.py +0 -0
  426. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/triage/dashboard.py +0 -0
  427. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/triage/instruments.py +0 -0
  428. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/triage/intents.py +0 -0
  429. {topos_node-1.3.29 → topos_node-1.3.31}/topos/features/triage/readiness.py +0 -0
  430. {topos_node-1.3.29 → topos_node-1.3.31}/topos/filter_lab/__init__.py +0 -0
  431. {topos_node-1.3.29 → topos_node-1.3.31}/topos/filter_lab/bundles.py +0 -0
  432. {topos_node-1.3.29 → topos_node-1.3.31}/topos/filter_lab/schema.py +0 -0
  433. {topos_node-1.3.29 → topos_node-1.3.31}/topos/filter_lab/service.py +0 -0
  434. {topos_node-1.3.29 → topos_node-1.3.31}/topos/filter_lab/store.py +0 -0
  435. {topos_node-1.3.29 → topos_node-1.3.31}/topos/filter_lab/worker.py +0 -0
  436. {topos_node-1.3.29 → topos_node-1.3.31}/topos/home_chat/__init__.py +0 -0
  437. {topos_node-1.3.29 → topos_node-1.3.31}/topos/home_chat/schema.py +0 -0
  438. {topos_node-1.3.29 → topos_node-1.3.31}/topos/home_chat/store.py +0 -0
  439. {topos_node-1.3.29 → topos_node-1.3.31}/topos/hosted_pool_lease.py +0 -0
  440. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/__init__.py +0 -0
  441. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/canonical_pipeline.py +0 -0
  442. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/checkpoints/__init__.py +0 -0
  443. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
  444. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
  445. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/inbox_crypto.py +0 -0
  446. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/inbox_drain.py +0 -0
  447. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/ingest_helpers.py +0 -0
  448. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/jobs.py +0 -0
  449. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/journal_location_fanout.py +0 -0
  450. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/journal_time_log_normalize.py +0 -0
  451. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/local_sync.py +0 -0
  452. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/log_preview.py +0 -0
  453. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/manager.py +0 -0
  454. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parser.py +0 -0
  455. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/__init__.py +0 -0
  456. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/base.py +0 -0
  457. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/browser_parser.py +0 -0
  458. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/calendar_parser.py +0 -0
  459. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
  460. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
  461. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
  462. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/documents_parser.py +0 -0
  463. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/github_activity_parser.py +0 -0
  464. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
  465. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/grok_parser.py +0 -0
  466. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/messenger_parser.py +0 -0
  467. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/parsers/voxterm_parser.py +0 -0
  468. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/progress.py +0 -0
  469. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/reprocess.py +0 -0
  470. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/__init__.py +0 -0
  471. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/base.py +0 -0
  472. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/calendar.py +0 -0
  473. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/chatgpt.py +0 -0
  474. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/contact_importers.py +0 -0
  475. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/grok.py +0 -0
  476. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/imessage_reader.py +0 -0
  477. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/signal_export_parser.py +0 -0
  478. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/sources/signal_reader.py +0 -0
  479. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/state_machine.py +0 -0
  480. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/triggers/__init__.py +0 -0
  481. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/triggers/file_trigger.py +0 -0
  482. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
  483. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/usage_inbox_dedupe.py +0 -0
  484. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/validation/__init__.py +0 -0
  485. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/validation/base.py +0 -0
  486. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/validation/schema_registry.py +0 -0
  487. {topos_node-1.3.29 → topos_node-1.3.31}/topos/ingestion/validation/schema_validator.py +0 -0
  488. {topos_node-1.3.29 → topos_node-1.3.31}/topos/lineage/__init__.py +0 -0
  489. {topos_node-1.3.29 → topos_node-1.3.31}/topos/lineage/provenance.py +0 -0
  490. {topos_node-1.3.29 → topos_node-1.3.31}/topos/lineage/tracker.py +0 -0
  491. {topos_node-1.3.29 → topos_node-1.3.31}/topos/llm_integrations_storage.py +0 -0
  492. {topos_node-1.3.29 → topos_node-1.3.31}/topos/mcp_stdio_proxy.py +0 -0
  493. {topos_node-1.3.29 → topos_node-1.3.31}/topos/observability/__init__.py +0 -0
  494. {topos_node-1.3.29 → topos_node-1.3.31}/topos/observability/alerts.py +0 -0
  495. {topos_node-1.3.29 → topos_node-1.3.31}/topos/observability/metrics.py +0 -0
  496. {topos_node-1.3.29 → topos_node-1.3.31}/topos/observability/tracing.py +0 -0
  497. {topos_node-1.3.29 → topos_node-1.3.31}/topos/openai_client.py +0 -0
  498. {topos_node-1.3.29 → topos_node-1.3.31}/topos/pipeline/__init__.py +0 -0
  499. {topos_node-1.3.29 → topos_node-1.3.31}/topos/pipeline/audit.py +0 -0
  500. {topos_node-1.3.29 → topos_node-1.3.31}/topos/pipeline/envelope.py +0 -0
  501. {topos_node-1.3.29 → topos_node-1.3.31}/topos/pipeline/job_runner.py +0 -0
  502. {topos_node-1.3.29 → topos_node-1.3.31}/topos/pipeline/job_store.py +0 -0
  503. {topos_node-1.3.29 → topos_node-1.3.31}/topos/pipeline/stages.py +0 -0
  504. {topos_node-1.3.29 → topos_node-1.3.31}/topos/pipeline/stub_enqueue.py +0 -0
  505. {topos_node-1.3.29 → topos_node-1.3.31}/topos/profiles.py +0 -0
  506. {topos_node-1.3.29 → topos_node-1.3.31}/topos/projections/__init__.py +0 -0
  507. {topos_node-1.3.29 → topos_node-1.3.31}/topos/projections/vector_index/__init__.py +0 -0
  508. {topos_node-1.3.29 → topos_node-1.3.31}/topos/projections/vector_index/base.py +0 -0
  509. {topos_node-1.3.29 → topos_node-1.3.31}/topos/projections/vector_index/builders.py +0 -0
  510. {topos_node-1.3.29 → topos_node-1.3.31}/topos/projections/vector_index/health_checks.py +0 -0
  511. {topos_node-1.3.29 → topos_node-1.3.31}/topos/protocol/__init__.py +0 -0
  512. {topos_node-1.3.29 → topos_node-1.3.31}/topos/protocol/query_field_contract.json +0 -0
  513. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/__init__.py +0 -0
  514. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/audit.py +0 -0
  515. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/cohort_resolvers.py +0 -0
  516. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/ddr.py +0 -0
  517. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/disclosure.py +0 -0
  518. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/entity_window.py +0 -0
  519. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/exclusion.py +0 -0
  520. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/fingerprint.py +0 -0
  521. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/grant_cache.py +0 -0
  522. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/inference.py +0 -0
  523. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/intent.py +0 -0
  524. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/manifest.py +0 -0
  525. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/manifest_validation.py +0 -0
  526. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/minimizer.py +0 -0
  527. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/negotiation.py +0 -0
  528. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/planner.py +0 -0
  529. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/runtime.py +0 -0
  530. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/scope_arbiter.py +0 -0
  531. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/scope_classifier.py +0 -0
  532. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/scope_head.py +0 -0
  533. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/scope_registry.json +0 -0
  534. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/scope_registry_loader.py +0 -0
  535. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/scope_shadow.py +0 -0
  536. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/session.py +0 -0
  537. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/session_utils.py +0 -0
  538. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/source_generation.py +0 -0
  539. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/truth_facts.py +0 -0
  540. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/truth_prompts.py +0 -0
  541. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/turn_classifier.py +0 -0
  542. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/types.py +0 -0
  543. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/verify.py +0 -0
  544. {topos_node-1.3.29 → topos_node-1.3.31}/topos/query/verify_modes.py +0 -0
  545. {topos_node-1.3.29 → topos_node-1.3.31}/topos/rate_limit.py +0 -0
  546. {topos_node-1.3.29 → topos_node-1.3.31}/topos/routines/__init__.py +0 -0
  547. {topos_node-1.3.29 → topos_node-1.3.31}/topos/routines/schema.py +0 -0
  548. {topos_node-1.3.29 → topos_node-1.3.31}/topos/routines/store.py +0 -0
  549. {topos_node-1.3.29 → topos_node-1.3.31}/topos/runtime_housekeeping.py +0 -0
  550. {topos_node-1.3.29 → topos_node-1.3.31}/topos/runtime_shutdown.py +0 -0
  551. {topos_node-1.3.29 → topos_node-1.3.31}/topos/runtime_update.py +0 -0
  552. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sanitization/__init__.py +0 -0
  553. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sanitization/nsfw_classifier.py +0 -0
  554. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sanitization/ollama_transforms.py +0 -0
  555. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sanitization/prewarm.py +0 -0
  556. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sanitization/privacy_filter.py +0 -0
  557. {topos_node-1.3.29 → topos_node-1.3.31}/topos/scope_resolution.py +0 -0
  558. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/__init__.py +0 -0
  559. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/container.py +0 -0
  560. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/embeddings/__init__.py +0 -0
  561. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/embeddings/base.py +0 -0
  562. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/embeddings/local.py +0 -0
  563. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/embeddings/remote.py +0 -0
  564. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/interfaces.py +0 -0
  565. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/llm/__init__.py +0 -0
  566. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/llm/base.py +0 -0
  567. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/llm/openai.py +0 -0
  568. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/local.py +0 -0
  569. {topos_node-1.3.29 → topos_node-1.3.31}/topos/services/postgres.py +0 -0
  570. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/__init__.py +0 -0
  571. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/bundled_canonical_triples.py +0 -0
  572. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/canonical_signal_defaults.py +0 -0
  573. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/declared_field_map_spec.py +0 -0
  574. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/definitions.py +0 -0
  575. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/install_service.py +0 -0
  576. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/registry.py +0 -0
  577. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/runtime_install.py +0 -0
  578. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/scrub_attribution.py +0 -0
  579. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sources/scrub_service.py +0 -0
  580. {topos_node-1.3.29 → topos_node-1.3.31}/topos/startup_banner.py +0 -0
  581. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/__init__.py +0 -0
  582. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/__init__.py +0 -0
  583. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/factory.py +0 -0
  584. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/fakes.py +0 -0
  585. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/postgres/stores.py +0 -0
  586. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/protocols.py +0 -0
  587. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/sqlite/__init__.py +0 -0
  588. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/adapters/sqlite/vector_search.py +0 -0
  589. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/__init__.py +0 -0
  590. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/activity_tables.py +0 -0
  591. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/ai_chat/__init__.py +0 -0
  592. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
  593. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/ai_chat/mapper.py +0 -0
  594. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/ai_chat/model.py +0 -0
  595. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/ai_chat/tables.py +0 -0
  596. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
  597. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/canonical_store.py +0 -0
  598. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/conversations_tables.py +0 -0
  599. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/journal_repair.py +0 -0
  600. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/mapping_store.py +0 -0
  601. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/canonical/postgres.py +0 -0
  602. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/__init__.py +0 -0
  603. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/client.py +0 -0
  604. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/connection_tuning.py +0 -0
  605. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/__init__.py +0 -0
  606. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
  607. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/actor_role_v1.py +0 -0
  608. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
  609. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
  610. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
  611. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/backup.py +0 -0
  612. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
  613. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
  614. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
  615. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
  616. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/community_names_v1.py +0 -0
  617. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/complexity_v1.py +0 -0
  618. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
  619. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
  620. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
  621. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
  622. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/documents_v1.py +0 -0
  623. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
  624. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
  625. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
  626. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
  627. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
  628. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
  629. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
  630. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
  631. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
  632. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
  633. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
  634. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/episodes_v1.py +0 -0
  635. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
  636. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
  637. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
  638. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
  639. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
  640. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
  641. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
  642. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
  643. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
  644. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
  645. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
  646. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
  647. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/remediation_person_model.py +0 -0
  648. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
  649. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/scope_source_generation.py +0 -0
  650. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
  651. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
  652. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/signal_objects.py +0 -0
  653. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
  654. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
  655. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
  656. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
  657. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
  658. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
  659. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
  660. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
  661. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
  662. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
  663. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
  664. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
  665. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
  666. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
  667. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
  668. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
  669. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
  670. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
  671. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
  672. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
  673. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
  674. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
  675. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/paths.py +0 -0
  676. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/postgres.py +0 -0
  677. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/schema.py +0 -0
  678. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/schema_probe.py +0 -0
  679. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/storage_breakdown.py +0 -0
  680. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/db/write_gate.py +0 -0
  681. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/enrichment/__init__.py +0 -0
  682. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
  683. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
  684. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/normalized/__init__.py +0 -0
  685. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/normalized/normalized_store.py +0 -0
  686. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/oplog/__init__.py +0 -0
  687. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/oplog/decision.py +0 -0
  688. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/oplog/oplog_store.py +0 -0
  689. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/oplog/postgres.py +0 -0
  690. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/person/identity_resolver.py +0 -0
  691. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/projections/__init__.py +0 -0
  692. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/projections/index_ops_store.py +0 -0
  693. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/projections/vector_index_store.py +0 -0
  694. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/raw/__init__.py +0 -0
  695. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/raw/browser_flat_tables.py +0 -0
  696. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/raw/file_store.py +0 -0
  697. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/raw/raw_store.py +0 -0
  698. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/raw/raw_tables_manager.py +0 -0
  699. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/raw/sqlite_raw_store.py +0 -0
  700. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/security/encryption.py +0 -0
  701. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/signal_identity.py +0 -0
  702. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/source_settings.py +0 -0
  703. {topos_node-1.3.29 → topos_node-1.3.31}/topos/storage/user_identity.py +0 -0
  704. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sync/__init__.py +0 -0
  705. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sync/client.py +0 -0
  706. {topos_node-1.3.29 → topos_node-1.3.31}/topos/sync_handlers.py +0 -0
  707. {topos_node-1.3.29 → topos_node-1.3.31}/topos/testing/__init__.py +0 -0
  708. {topos_node-1.3.29 → topos_node-1.3.31}/topos/testing/lifespan.py +0 -0
  709. {topos_node-1.3.29 → topos_node-1.3.31}/topos/uma_contact_enrichment.py +0 -0
  710. {topos_node-1.3.29 → topos_node-1.3.31}/topos/uma_filters.py +0 -0
  711. {topos_node-1.3.29 → topos_node-1.3.31}/topos/uma_resource_id.py +0 -0
  712. {topos_node-1.3.29 → topos_node-1.3.31}/topos/uma_rpt.py +0 -0
  713. {topos_node-1.3.29 → topos_node-1.3.31}/topos/upgrades/__init__.py +0 -0
  714. {topos_node-1.3.29 → topos_node-1.3.31}/topos/upgrades/runner.py +0 -0
  715. {topos_node-1.3.29 → topos_node-1.3.31}/topos/utils/base_object.py +0 -0
  716. {topos_node-1.3.29 → topos_node-1.3.31}/topos/websocket_client.py +0 -0
  717. {topos_node-1.3.29 → topos_node-1.3.31}/topos_node.egg-info/dependency_links.txt +0 -0
  718. {topos_node-1.3.29 → topos_node-1.3.31}/topos_node.egg-info/entry_points.txt +0 -0
  719. {topos_node-1.3.29 → topos_node-1.3.31}/topos_node.egg-info/requires.txt +0 -0
  720. {topos_node-1.3.29 → topos_node-1.3.31}/topos_node.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: topos-node
3
- Version: 1.3.29
3
+ Version: 1.3.31
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.29"
7
+ version = "1.3.31"
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.29"
4
- __version_info__ = (1, 3, 29)
3
+ __version__ = "1.3.31"
4
+ __version_info__ = (1, 3, 31)
5
5
 
6
6
  __all__ = ["__version__", "__version_info__"]
@@ -1156,3 +1156,53 @@ async def put_community_name_route(
1156
1156
  )
1157
1157
  commit_connection(conn)
1158
1158
  return {"community_id": community_id, "name": name, "members": len(rows)}
1159
+
1160
+
1161
+ @router.get("/derivation/schema")
1162
+ async def get_derivation_schema(_api_key: str = Depends(require_api_key)):
1163
+ """Per-predicate field schemas for the Fact Editor (W4.6)."""
1164
+ from ..features.derivation.surfaces import predicate_schemas
1165
+
1166
+ return {"predicates": predicate_schemas(_entities_conn())}
1167
+
1168
+
1169
+ @router.post("/facts/conflicts/promote")
1170
+ async def post_conflict_promotion(
1171
+ conflict_id: str = Body(...),
1172
+ subject_entity_id: str = Body(""),
1173
+ new_person_name: str = Body(""),
1174
+ to_owner: bool = Body(False),
1175
+ value: Any = Body(None),
1176
+ _api_key: str = Depends(require_api_key),
1177
+ ):
1178
+ """Edit & add a quarantined extraction: the owner supplies the identity the
1179
+ machine refused to guess; ledgered as gold (W4.6)."""
1180
+ from ..features.derivation.surfaces import promote_conflict
1181
+
1182
+ try:
1183
+ return promote_conflict(_entities_conn(), conflict_id,
1184
+ subject_entity_id=subject_entity_id,
1185
+ new_person_name=new_person_name,
1186
+ value=value, to_owner=to_owner)
1187
+ except ValueError as exc:
1188
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
1189
+
1190
+
1191
+ @router.post("/facts/{object_id}/revise")
1192
+ async def post_fact_revision(
1193
+ object_id: str,
1194
+ value: Any = Body(None),
1195
+ subject_entity_id: str = Body(""),
1196
+ evidence_date: str = Body(""),
1197
+ asserted_by: str = Body(""),
1198
+ _api_key: str = Depends(require_api_key),
1199
+ ):
1200
+ """Owner revision of a live pack fact: field/subject/date, never its kind (W4.6)."""
1201
+ from ..features.derivation.surfaces import revise_fact
1202
+
1203
+ try:
1204
+ return revise_fact(_entities_conn(), object_id, value=value,
1205
+ subject_entity_id=subject_entity_id,
1206
+ evidence_date=evidence_date, asserted_by=asserted_by)
1207
+ except ValueError as exc:
1208
+ raise HTTPException(status_code=400, detail=str(exc)) from exc
@@ -271,7 +271,12 @@ def _as_binding(raw: Any) -> Optional[Dict[str, str]]:
271
271
  def _local_model_present(binding: Mapping[str, str], installed_local_models: Optional[Any]) -> bool:
272
272
  if installed_local_models is None:
273
273
  return True
274
- if str(binding.get("provider") or "").strip().lower() not in LOCAL_PROVIDERS:
274
+ provider = str(binding.get("provider") or "").strip().lower()
275
+ # Horos is local but not an Ollama tag; `default` must not look like a
276
+ # missing download. Mirrors control_plane.model_pack_resolution.
277
+ if provider == SCOPE_HEAD_PROVIDER:
278
+ return True
279
+ if provider not in LOCAL_PROVIDERS:
275
280
  return True
276
281
  installed = {str(name or "").strip().lower() for name in installed_local_models}
277
282
  wanted = str(binding.get("model") or "").strip().lower()
@@ -119,3 +119,58 @@ async def handle_run_pack_backfill(message):
119
119
  return {"id": req_id, "status": "error", "error": str(exc)}
120
120
  except Exception as exc: # noqa: BLE001
121
121
  return {"id": req_id, "status": "error", "error": str(exc)}
122
+
123
+
124
+ @handles("get_derivation_schema")
125
+ async def handle_get_derivation_schema(message):
126
+ req_id = message.get("id")
127
+ conn = hub.get_db_connection()
128
+ if not conn:
129
+ return {"id": req_id, "status": "error", "error": "Database not available"}
130
+ try:
131
+ from ...features.derivation.surfaces import predicate_schemas
132
+ return {"id": req_id, "status": "ok",
133
+ "payload": {"status": "ok", "predicates": predicate_schemas(conn)}}
134
+ except Exception as exc: # noqa: BLE001
135
+ return {"id": req_id, "status": "error", "error": str(exc)}
136
+
137
+
138
+ @handles("promote_fact_conflict")
139
+ async def handle_promote_fact_conflict(message):
140
+ req_id = message.get("id")
141
+ conn = hub.get_db_connection()
142
+ if not conn:
143
+ return {"id": req_id, "status": "error", "error": "Database not available"}
144
+ p = message.get("payload") or {}
145
+ try:
146
+ from ...features.derivation.surfaces import promote_conflict
147
+ out = promote_conflict(conn, str(p.get("conflict_id") or ""),
148
+ subject_entity_id=str(p.get("subject_entity_id") or ""),
149
+ new_person_name=str(p.get("new_person_name") or ""),
150
+ value=p.get("value"), to_owner=bool(p.get("to_owner")))
151
+ return {"id": req_id, "status": "ok", "payload": {"status": "ok", **out}}
152
+ except ValueError as exc:
153
+ return {"id": req_id, "status": "error", "error": str(exc)}
154
+ except Exception as exc: # noqa: BLE001
155
+ return {"id": req_id, "status": "error", "error": str(exc)}
156
+
157
+
158
+ @handles("revise_pack_fact")
159
+ async def handle_revise_pack_fact(message):
160
+ req_id = message.get("id")
161
+ conn = hub.get_db_connection()
162
+ if not conn:
163
+ return {"id": req_id, "status": "error", "error": "Database not available"}
164
+ p = message.get("payload") or {}
165
+ try:
166
+ from ...features.derivation.surfaces import revise_fact
167
+ out = revise_fact(conn, str(p.get("object_id") or ""),
168
+ value=p.get("value"),
169
+ subject_entity_id=str(p.get("subject_entity_id") or ""),
170
+ evidence_date=str(p.get("evidence_date") or ""),
171
+ asserted_by=str(p.get("asserted_by") or ""))
172
+ return {"id": req_id, "status": "ok", "payload": {"status": "ok", **out}}
173
+ except ValueError as exc:
174
+ return {"id": req_id, "status": "error", "error": str(exc)}
175
+ except Exception as exc: # noqa: BLE001
176
+ return {"id": req_id, "status": "error", "error": str(exc)}
@@ -73,8 +73,8 @@ guidance:
73
73
  - "Authored-only: an assigned OKR is work context, not a personal goal, unless the owner adopts it in their own words."
74
74
  - "Idle wishes ('would love to someday') are aspirations, never goals — the horizon field is load-bearing."
75
75
  - "v0.2.4 A goal is STATED INTENT in the owner's own words ('Goal:', 'I want to', 'I will').
76
- Wry observations, jokes and family lore ('this is the closest I can keep that pattern
77
- going') are never goals — if the owner would be surprised to see it on their goal list,
76
+ Wry observations, jokes and family lore ('guess the family streak continues through me
77
+ ') are never goals — if the owner would be surprised to see it on their goal list,
78
78
  extract nothing."
79
79
  - "v0.2.4 goal_ref is a NAME (a few words), not a sentence — a goal_ref longer than ~8 words
80
80
  means the goal was never really named; prefer the Goal: header's own phrasing."
@@ -31,7 +31,7 @@ predicates:
31
31
  v0.2.4 — a state report is a FELT-STATE statement about how the owner is/was
32
32
  ("I am exhausted", "slept 8 hours, wild dreams", "so nervous with the talk").
33
33
  An intention, aspiration, reflection or observation is NOT a state, whatever
34
- dimension it brushes: "I need to be talking to more intelligent people" is a
34
+ dimension it brushes: "I need to be around more ambitious builders" is a
35
35
  want, not an energy report; "the talk motivated me to write" is a reflection,
36
36
  not a focus report. If the words don't describe how the owner FEELS or FELT,
37
37
  extract nothing.
@@ -70,9 +70,9 @@ eval:
70
70
  - {text: "Third week straight of terrible sleep, I'm running on fumes", role: authored,
71
71
  expect: [{predicate: mind.self_reported_state, value: {dimension: sleep_quality}}]}
72
72
  negative_controls:
73
- - {text: "I need to be talking to more intelligent people. To go out of my way to speak with people.", role: authored,
73
+ - {text: "I need to be around more ambitious builders. To go out of my way to find them.", role: authored,
74
74
  expect_not: [{predicate: mind.self_reported_state}], note: "v0.2.4 measured junk: a want is not an energy state"}
75
- - {text: "The talk at the end motivated me to write my own thought on coordination tools.", role: authored,
75
+ - {text: "The workshop at the end inspired me to draft my own essay on collaboration tools.", role: authored,
76
76
  expect_not: [{predicate: mind.self_reported_state}], note: "v0.2.4 measured junk: a reflection is not a focus state"}
77
77
  - {text: "Podcast episode about burnout culture in tech", role: ambient, expect: []}
78
78
  - {text: "My brother finally started therapy, proud of him", role: authored, expect: [], note: "third party"}
@@ -81,8 +81,8 @@ decisions:
81
81
  - >
82
82
  2026-08-26 (W5 gate, measured): role_policy tightened to authored_addressed —
83
83
  with ambient/observed allowed, OTHER PEOPLE'S messages became owner place-ties
84
- ("I am once again at Radio East" from a friend -> owner workplace_location;
85
- a friend's NJ parking find -> owner tie to New Jersey). 4/5 sampled accepts
84
+ ("I am once again at the Harbor Cafe" from a friend -> owner workplace_location;
85
+ a friend's parking find -> owner tie to that city). 4/5 sampled accepts
86
86
  were junk, dominated by this leak. Location-bearing ambient signals return
87
87
  via the no-LLM synthesizer lane (timestamps/geo), never via LLM reading of
88
88
  others' words.
@@ -117,12 +117,12 @@ eval:
117
117
  expect: [{predicate: work.project, value: {status: paused}}]}
118
118
  negative_controls:
119
119
  - {text: "Sounds like Dana's team is hiring three more", role: authored, expect: [], note: "other team's news"}
120
- - {text: "I applied to Tavus' job application today", role: authored, expect: [], note: "v0.2.2 measured junk: applied is NOT hired"}
121
- - {text: "I applied to the Google Startup Fund", role: authored, expect: [], note: "v0.2.2 measured junk: applying for funding is NOT started_venture"}
120
+ - {text: "I applied to Meridian's open role today", role: authored, expect: [], note: "v0.2.2 measured junk: applied is NOT hired"}
121
+ - {text: "I applied to the Horizon Startup Fund", role: authored, expect: [], note: "v0.2.2 measured junk: applying for funding is NOT started_venture"}
122
122
  - {text: "I filed for unemployment.", role: authored, expect: [{predicate: work.employment_shape, value: between_roles}],
123
123
  expect_not: [{predicate: work.career_event}], note: "v0.2.2: shape yes, event no"}
124
- - {text: "I took the ccat again. I got a 32.", role: authored, expect: [], note: "v0.2.2 measured junk: a test score is not an award"}
125
- - {text: "All day with Texas Ventures.", role: authored, expect_not: [{predicate: work.employer}], note: "v0.2.2 measured junk: co-presence is not employment"}
124
+ - {text: "I took the practice aptitude test again. Scored a 32.", role: authored, expect: [], note: "v0.2.2 measured junk: a test score is not an award"}
125
+ - {text: "All day with Harbor Ventures.", role: authored, expect_not: [{predicate: work.employer}], note: "v0.2.2 measured junk: co-presence is not employment"}
126
126
  - {text: "(newsletter: 'The 2026 layoff wave continues')", role: ambient, expect: []}
127
127
  calibration: {min_conf_for_assert: 0.65, ece_max: 0.15}
128
128
 
@@ -70,11 +70,16 @@ def set_pack_enabled(conn: sqlite3.Connection, pack_id: str, enabled: bool) -> b
70
70
 
71
71
  def list_conflicts(conn: sqlite3.Connection, limit: int = 100) -> List[Dict[str, Any]]:
72
72
  rows: List[Dict[str, Any]] = []
73
- for cid, subj, pred, incumbent, value, conf, status, created in conn.execute(
73
+ cols = {r[1] for r in conn.execute("PRAGMA table_info(fact_conflicts)")}
74
+ has_prov = "pack_id" in cols
75
+ extra = ", pack_id, source_refs_json, quote, about_hint" if has_prov else ""
76
+ for row in conn.execute(
74
77
  "SELECT conflict_id, subject_entity_id, predicate, incumbent_object_id,"
75
- " challenger_value, challenger_confidence, status, created_at"
78
+ " challenger_value, challenger_confidence, status, created_at" + extra +
76
79
  " FROM fact_conflicts WHERE status='pending'"
77
80
  " ORDER BY created_at DESC LIMIT ?", (min(int(limit), 500),)):
81
+ cid, subj, pred, incumbent, value, conf, status, created = row[:8]
82
+ pack_id, refs_json, quote, hint = (row[8:12] if has_prov else (None, None, None, None))
78
83
  try:
79
84
  val = json.loads(value)
80
85
  except (json.JSONDecodeError, TypeError):
@@ -84,7 +89,9 @@ def list_conflicts(conn: sqlite3.Connection, limit: int = 100) -> List[Dict[str,
84
89
  "kind": "quarantine" if is_q else "conflict",
85
90
  "reason": str(incumbent)[len("quarantine:"):] if is_q else None,
86
91
  "incumbent_object_id": incumbent, "value": val,
87
- "confidence": conf, "created_at": created})
92
+ "confidence": conf, "created_at": created,
93
+ "pack_id": pack_id, "quote": quote, "about_hint": hint,
94
+ "promotable": bool(pack_id)})
88
95
  return rows
89
96
 
90
97
 
@@ -224,3 +231,182 @@ def run_pack_backfill(conn: sqlite3.Connection, pack_id: str, limit: int = 500)
224
231
  conn.commit()
225
232
  stats["quarantined"] = writer.stats.get("quarantined", 0) - stats.pop("quarantined0")
226
233
  return stats
234
+
235
+
236
+ def predicate_schemas(conn: sqlite3.Connection) -> Dict[str, Any]:
237
+ """Per-predicate field schemas for the Fact Editor (W4.6): enum options,
238
+ person-typed flags, free-text fields — straight from the bundled contracts,
239
+ so the editor can never drift from what the writer accepts."""
240
+ from .packs import load_packs
241
+ from .registry import bundled_pack_dir
242
+
243
+ out: Dict[str, Any] = {}
244
+ for pid, pack in load_packs(bundled_pack_dir()).items():
245
+ for pred in pack.predicates.values():
246
+ fields: Dict[str, Any] = {}
247
+ if pred.value_schema:
248
+ for name, spec in pred.value_schema.items():
249
+ if isinstance(spec, dict) and spec.get("enum"):
250
+ fields[name] = {"kind": "enum", "options": list(spec["enum"])}
251
+ elif isinstance(spec, list):
252
+ fields[name] = {"kind": "enum", "options": list(spec)}
253
+ elif name in ("person", "member"):
254
+ fields[name] = {"kind": "person"}
255
+ else:
256
+ fields[name] = {"kind": "text"}
257
+ elif pred.values:
258
+ fields["__value__"] = {"kind": "enum", "options": list(pred.values)}
259
+ else:
260
+ fields["__value__"] = {"kind": "text"}
261
+ out[pred.name] = {"pack": pid, "fields": fields,
262
+ "key_fields": list(pred.key_fields or []),
263
+ "temporal": pred.temporal}
264
+ return out
265
+
266
+
267
+ def promote_conflict(conn: sqlite3.Connection, conflict_id: str, *,
268
+ subject_entity_id: str = "", new_person_name: str = "",
269
+ value: Any = None, to_owner: bool = False) -> Dict[str, Any]:
270
+ """W4.6 — the review queue's 'Edit & add': the owner supplies the identity
271
+ (or corrected fields) the machine refused to guess; the fact writes through
272
+ the FULL writer path and the correction lands in the ledger as GOLD."""
273
+ import json as _json
274
+ import uuid as _uuid
275
+
276
+ from .packs import load_packs
277
+ from .registry import bundled_pack_dir
278
+ from .writer import DerivationWriter
279
+
280
+ row = conn.execute(
281
+ "SELECT subject_entity_id, predicate, challenger_value, challenger_confidence,"
282
+ " pack_id, source_refs_json, quote, about_hint, status"
283
+ " FROM fact_conflicts WHERE conflict_id=?", (conflict_id,)).fetchone()
284
+ if not row:
285
+ raise ValueError(f"unknown conflict {conflict_id}")
286
+ subj0, predicate, val_json, conf, pack_id, refs_json, quote, hint, status = row
287
+ if status != "pending":
288
+ raise ValueError(f"conflict {conflict_id} already {status}")
289
+ if not pack_id:
290
+ raise ValueError("this row predates provenance capture — dismiss and let re-extraction recreate it")
291
+ pack = load_packs(bundled_pack_dir(), only=[pack_id]).get(pack_id)
292
+ if pack is None:
293
+ raise ValueError(f"unknown pack {pack_id}")
294
+ try:
295
+ stored_value = _json.loads(val_json or "null")
296
+ except (ValueError, TypeError):
297
+ stored_value = val_json
298
+ final_value = value if value is not None else stored_value
299
+
300
+ if to_owner:
301
+ subject = conn.execute("SELECT entity_id FROM entities WHERE is_self=1").fetchone()[0]
302
+ elif subject_entity_id:
303
+ ok = conn.execute("SELECT 1 FROM entities WHERE entity_id=?", (subject_entity_id,)).fetchone()
304
+ if not ok:
305
+ raise ValueError(f"unknown entity {subject_entity_id}")
306
+ subject = subject_entity_id
307
+ elif new_person_name.strip():
308
+ subject = f"ent_{_uuid.uuid4().hex[:16]}"
309
+ n = " ".join(new_person_name.strip().split())
310
+ cols = {r[1] for r in conn.execute("PRAGMA table_info(entities)")}
311
+ base = ["entity_id", "entity_type", "canonical_name", "normalized_name", "aliases_json", "is_self"]
312
+ vals = [subject, "person", n, n.lower(), "[]", 0]
313
+ for extra in ("created_at", "updated_at"):
314
+ if extra in cols:
315
+ base.append(extra); vals.append(None) # filled by SQL below
316
+ placeholders = ", ".join(
317
+ "datetime('now')" if b in ("created_at", "updated_at") else "?" for b in base)
318
+ conn.execute(
319
+ f"INSERT INTO entities ({', '.join(base)}) VALUES ({placeholders})",
320
+ [v for b, v in zip(base, vals) if b not in ("created_at", "updated_at")])
321
+ else:
322
+ raise ValueError("supply subject_entity_id, new_person_name, or to_owner")
323
+
324
+ writer = DerivationWriter(conn, model="owner-promote")
325
+ refs = _json.loads(refs_json or "[]")
326
+ out = writer.assert_pack_fact(
327
+ pack=pack, predicate=predicate, subject_entity_id=subject,
328
+ value=final_value, actor_role="authored", source_refs=refs,
329
+ confidence=1.0, quote=quote or "", about="owner")
330
+ from ...storage.db.write_gate import commit_connection, with_db_write
331
+ with with_db_write():
332
+ conn.execute("UPDATE fact_conflicts SET status='accepted', updated_at=datetime('now')"
333
+ " WHERE conflict_id=?", (conflict_id,))
334
+ try:
335
+ conn.execute(
336
+ """INSERT INTO derivation_training_ledger
337
+ (ledger_id, stage, pack_id, pack_version, predicate, value_json,
338
+ about, quote, confidence, vstatus, written_object_id)
339
+ VALUES (?, 'owner_promote', ?, ?, ?, ?, ?, ?, 1.0, 'accepted', ?)""",
340
+ (f"dtl_{_uuid.uuid4().hex[:16]}", pack_id, pack.version, predicate,
341
+ _json.dumps(final_value, default=str), f"entity:{subject}",
342
+ quote or "", out.get("object_id")))
343
+ except sqlite3.OperationalError:
344
+ pass
345
+ commit_connection(conn)
346
+ return {"conflict_id": conflict_id, "outcome": out.get("outcome"),
347
+ "object_id": out.get("object_id"), "subject_entity_id": subject}
348
+
349
+
350
+ def revise_fact(conn: sqlite3.Connection, object_id: str, *,
351
+ value: Any = None, subject_entity_id: str = "",
352
+ evidence_date: str = "", asserted_by: str = "") -> Dict[str, Any]:
353
+ """W4.6 — owner revision of a live pack fact: closes the old row
354
+ (reason=owner_revision, belief clock inherited), re-inserts through keying
355
+ with confidence pinned 1.0. Field/date/subject edits only — a fact's KIND
356
+ never changes here (that is reject + a new fact)."""
357
+ import json as _json
358
+ import uuid as _uuid
359
+
360
+ from .packs import load_packs
361
+ from .registry import bundled_pack_dir
362
+ from .writer import DerivationWriter
363
+
364
+ row = conn.execute(
365
+ "SELECT object_key, payload_json, valid_from, ontology_id FROM signal_objects"
366
+ " WHERE object_id=? AND object_type='fact' AND valid_to IS NULL", (object_id,)).fetchone()
367
+ if not row:
368
+ raise ValueError(f"no live fact {object_id}")
369
+ key, pj, vf, pack_id = row
370
+ if not pack_id:
371
+ raise ValueError("legacy fact — use the verdict edit action")
372
+ p = _json.loads(pj or "{}")
373
+ predicate = str(p.get("predicate") or "")
374
+ pack = load_packs(bundled_pack_dir(), only=[pack_id]).get(pack_id)
375
+ if pack is None:
376
+ raise ValueError(f"unknown pack {pack_id}")
377
+ old_value = p.get("value_struct") if p.get("value_struct") is not None else p.get("object_value")
378
+ final_value = value if value is not None else old_value
379
+ subject = subject_entity_id or str(p.get("subject_entity_id") or "")
380
+ if subject_entity_id:
381
+ ok = conn.execute("SELECT 1 FROM entities WHERE entity_id=?", (subject_entity_id,)).fetchone()
382
+ if not ok:
383
+ raise ValueError(f"unknown entity {subject_entity_id}")
384
+
385
+ from ...storage.db.write_gate import commit_connection, with_db_write
386
+ with with_db_write():
387
+ conn.execute("UPDATE signal_objects SET valid_to=?, updated_at=datetime('now'),"
388
+ " updated_by='owner_revision' WHERE object_id=?",
389
+ ((evidence_date or str(vf)), object_id))
390
+ commit_connection(conn)
391
+ writer = DerivationWriter(conn, model="owner-revise")
392
+ out = writer.assert_pack_fact(
393
+ pack=pack, predicate=predicate, subject_entity_id=subject,
394
+ value=final_value, actor_role="authored",
395
+ source_refs=p.get("source_refs") or [], confidence=1.0,
396
+ quote=str(p.get("quote") or ""), about="owner",
397
+ event_date=(evidence_date or str(vf)[:10]) or None)
398
+ with with_db_write():
399
+ try:
400
+ conn.execute(
401
+ """INSERT INTO derivation_training_ledger
402
+ (ledger_id, stage, pack_id, predicate, value_json, about, confidence,
403
+ vstatus, vreason, written_object_id)
404
+ VALUES (?, 'owner_edit', ?, ?, ?, ?, 1.0, 'accepted', ?, ?)""",
405
+ (f"dtl_{_uuid.uuid4().hex[:16]}", pack_id, predicate,
406
+ _json.dumps(final_value, default=str), f"entity:{subject}",
407
+ f"revised_from:{object_id}", out.get("object_id")))
408
+ except sqlite3.OperationalError:
409
+ pass
410
+ commit_connection(conn)
411
+ return {"revised_from": object_id, "outcome": out.get("outcome"),
412
+ "object_id": out.get("object_id")}
@@ -100,7 +100,7 @@ LOSS_EVIDENCE = ("died", "passed", "passing", "funeral", "loss of", "death", "re
100
100
 
101
101
  def relationship_role_check(role: str, person: str, record_text: str):
102
102
  """A1 role-evidence guard (measured 2026-08-26 full-run): the 27B verifier
103
- CONSISTENTLY accepts possessive misattribution ("Wiki and her boyfriend Luc"
103
+ CONSISTENTLY accepts possessive misattribution ("Nora and her boyfriend Theo"
104
104
  -> owner's partner) — textual support without subject discipline. Rules,
105
105
  all deterministic:
106
106
  1. A kin-term PERSON ("Mom", "brother") is self-evidencing -> owner.
@@ -239,7 +239,7 @@ Hard rules:
239
239
  - Extract only what this record actually states about the OWNER. No guesses, no world knowledge.
240
240
  - Every assertion MUST carry "about": "owner" if the fact is about the record's author-owner,
241
241
  "other:<name>" if the record states it about someone else (their appointment, their partner,
242
- their loss — e.g. "Wiki and her boyfriend Luc" -> about: "other:Wiki"), or "unclear" if you
242
+ their loss — e.g. "Nora and her boyfriend Theo" -> about: "other:Nora"), or "unclear" if you
243
243
  cannot tell. Facts about others are NOT discarded — they are routed to that person's dossier —
244
244
  so NEVER launder a third party's fact into "owner" to save it.
245
245
  The about field does NOT make extraction stricter: extract exactly what you would have
@@ -154,18 +154,33 @@ class DerivationWriter:
154
154
  ).fetchone()
155
155
  return row[0] if row else None
156
156
 
157
- def _quarantine(self, subject_entity_id: str, predicate: str, value, confidence: float, reason: str):
157
+ def _quarantine(self, subject_entity_id: str, predicate: str, value, confidence: float,
158
+ reason: str, *, pack=None, source_refs=None, quote: str = "", about: str = ""):
158
159
  """A3 quarantine: nothing is silently lost — unroutable assertions land in
159
- fact_conflicts (the W4.2 review queue) with a sentinel incumbent id."""
160
+ fact_conflicts (the review queue) WITH their provenance (migration 68), so
161
+ the owner can promote them into facts without minting evidence-less rows."""
160
162
  import uuid as _uuid
161
- self.conn.execute(
162
- """INSERT INTO fact_conflicts (conflict_id, subject_entity_id, predicate,
163
- incumbent_object_id, challenger_value, challenger_confidence)
164
- VALUES (?, ?, ?, ?, ?, ?)""",
165
- (f"cfl_{_uuid.uuid4().hex[:12]}", subject_entity_id, predicate,
166
- f"quarantine:{reason}", json.dumps(value, ensure_ascii=False, default=str)[:500],
167
- float(confidence)),
168
- )
163
+ hint = about[6:] if isinstance(about, str) and about.startswith("other:") else ""
164
+ try:
165
+ self.conn.execute(
166
+ """INSERT INTO fact_conflicts (conflict_id, subject_entity_id, predicate,
167
+ incumbent_object_id, challenger_value, challenger_confidence,
168
+ pack_id, source_refs_json, quote, about_hint)
169
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
170
+ (f"cfl_{_uuid.uuid4().hex[:12]}", subject_entity_id, predicate,
171
+ f"quarantine:{reason}", json.dumps(value, ensure_ascii=False, default=str)[:500],
172
+ float(confidence), getattr(pack, "pack", None),
173
+ json.dumps(source_refs or [], default=str)[:800], (quote or "")[:200], hint),
174
+ )
175
+ except Exception: # noqa: BLE001 — pre-migration-68 schema
176
+ self.conn.execute(
177
+ """INSERT INTO fact_conflicts (conflict_id, subject_entity_id, predicate,
178
+ incumbent_object_id, challenger_value, challenger_confidence)
179
+ VALUES (?, ?, ?, ?, ?, ?)""",
180
+ (f"cfl_{_uuid.uuid4().hex[:12]}", subject_entity_id, predicate,
181
+ f"quarantine:{reason}", json.dumps(value, ensure_ascii=False, default=str)[:500],
182
+ float(confidence)),
183
+ )
169
184
  self.stats["quarantined"] = self.stats.get("quarantined", 0) + 1
170
185
 
171
186
  def assert_pack_fact(
@@ -200,11 +215,13 @@ class DerivationWriter:
200
215
  self.stats["routed_dossier"] = self.stats.get("routed_dossier", 0) + 1
201
216
  else:
202
217
  self._quarantine(subject_entity_id, predicate, value, confidence,
203
- reason=f"dossier_unresolved:{about[6:][:40]}")
218
+ reason=f"dossier_unresolved:{about[6:][:40]}",
219
+ pack=pack, source_refs=source_refs, quote=quote, about=about)
204
220
  return {"outcome": "quarantined", "reason": "about=other unresolvable"}
205
221
  else: # unclear — two passes could not agree on a subject
206
222
  self._quarantine(subject_entity_id, predicate, value, confidence,
207
- reason="about_unclear")
223
+ reason="about_unclear",
224
+ pack=pack, source_refs=source_refs, quote=quote, about=about)
208
225
  return {"outcome": "quarantined", "reason": "about unclear"}
209
226
  synth_preds = {q for e in pack.synthesis for q in (e.get("predicate") if isinstance(e.get("predicate"), list) else [e.get("predicate")])}
210
227
  if actor_role == "synthesis":
@@ -228,7 +245,8 @@ class DerivationWriter:
228
245
  if pred.name == "asp.milestone" and isinstance(value, dict):
229
246
  if not self._milestone_attaches(subject_entity_id, str(value.get("goal_ref") or "")):
230
247
  self._quarantine(subject_entity_id, predicate, value, confidence,
231
- reason="milestone_without_goal")
248
+ reason="milestone_without_goal",
249
+ pack=pack, source_refs=source_refs, quote=quote, about=about)
232
250
  return {"outcome": "quarantined", "reason": "milestone attaches to no stored goal"}
233
251
  # F1.6 guard — every leaf of the value
234
252
  for leaf in _value_leaves(value):
@@ -794,7 +794,7 @@ def compute_communities(conn: sqlite3.Connection) -> Dict[str, int]:
794
794
  # A community label is a NAME: name-length, from a name-natured type.
795
795
  def _labelable(eid: str) -> bool:
796
796
  nm = names.get(eid, "").strip()
797
- if not nm or len(nm) > 40 or len(nm.split()) > 4:
797
+ if not nm or len(nm) > 40 or len(nm.split()) > 4 or "\n" in nm:
798
798
  return False
799
799
  if types.get(eid, "") in ("goal", "conversation"):
800
800
  return False
@@ -820,7 +820,12 @@ def compute_communities(conn: sqlite3.Connection) -> Dict[str, int]:
820
820
  # FALLBACK; identity-matched historical names win, and genuinely
821
821
  # new cores get one LLM-derived name (validated, else fallback).
822
822
  community_cores[rank[comm]] = [str(m) for m in ranked]
823
- _apply_stable_names(conn, community_cores, labels_by_rank, names, eigen)
823
+ try:
824
+ _apply_stable_names(conn, community_cores, labels_by_rank, names, eigen)
825
+ except Exception: # noqa: BLE001 — naming is an ENHANCEMENT; a lock or
826
+ # model failure mid-pass must never cost the deterministic labels
827
+ # (first live run: a transient 'database is locked' wiped them)
828
+ logger.exception("stable naming pass failed; deterministic labels stand")
824
829
  logger.info(
825
830
  "graph structural analytics: %d nodes / %d edges, betweenness k=%s, %.2fs",
826
831
  n,
@@ -130,6 +130,9 @@ def list_facts(
130
130
  "subject_name": subject_name,
131
131
  "predicate": payload.get("predicate"),
132
132
  "object_value": payload.get("object_value"),
133
+ # the FULL structured value — object_value is a 160-char display
134
+ # string and renders as cut JSON when a report runs long (W4.6)
135
+ "value_struct": payload.get("value_struct"),
133
136
  "period_start": payload.get("period_start"),
134
137
  "period_end": payload.get("period_end"),
135
138
  "confidence": payload.get("confidence", fact["confidence"]),
@@ -43,6 +43,7 @@
43
43
  "get_data_explorer_table_prefs",
44
44
  "get_database_explorer_summary",
45
45
  "get_derivation_packs",
46
+ "get_derivation_schema",
46
47
  "get_device_info",
47
48
  "get_enrichment_lab_bundle_detail",
48
49
  "get_enrichment_lab_bundles",
@@ -133,6 +134,7 @@
133
134
  "post_source_test_enrichment",
134
135
  "post_source_test_enrichment_trigger",
135
136
  "post_source_test_ingestion",
137
+ "promote_fact_conflict",
136
138
  "put_community_name",
137
139
  "put_conversation_context",
138
140
  "put_conversation_context_llm_config",
@@ -156,6 +158,7 @@
156
158
  "read_jsonl_file",
157
159
  "replay_projection",
158
160
  "replay_projection_preview",
161
+ "revise_pack_fact",
159
162
  "routine_has_active_run",
160
163
  "run_pack_backfill",
161
164
  "set_device_name",
@@ -122,6 +122,7 @@
122
122
  "resolved_self",
123
123
  "retrieval_parts",
124
124
  "retrieval_text",
125
+ "row_cap_reached",
125
126
  "scope_denied",
126
127
  "scope_id_invalid",
127
128
  "scope_mismatch",
@@ -93,9 +93,27 @@ def fetch_direct_facts(
93
93
  "altitude": altitude or "stated", "pack": pack,
94
94
  "evidence_count": len(refs) if isinstance(refs, list) else 0,
95
95
  })
96
+ # Durable facts (a standing role/status: "mom, parent, active") outrank event
97
+ # facts ("met X at the saloon") in a known-item answer. Recency-only ordering
98
+ # let a month of introductions push the owner's parents past the compose cap:
99
+ # live 2026-08-26, "Who's in my family?" listed 16 met-events and cut
100
+ # mom/brother while keeping them in store. Stable sort keeps recency DESC
101
+ # within each band, so event feeds ("what happened with X?") are unaffected
102
+ # below the durable block.
103
+ out.sort(key=lambda f: 0 if _is_durable(f.get("value")) else 1)
96
104
  return out or None
97
105
 
98
106
 
107
+ def _is_durable(value: Any) -> bool:
108
+ """A fact whose value carries a standing role/status rather than an event."""
109
+ if isinstance(value, str):
110
+ try:
111
+ value = json.loads(value)
112
+ except (json.JSONDecodeError, TypeError):
113
+ return False
114
+ return isinstance(value, dict) and bool(value.get("role") or value.get("status"))
115
+
116
+
99
117
  def _fmt_value(v: Any) -> str:
100
118
  if isinstance(v, str):
101
119
  try: