topos-node 1.5.3__tar.gz → 1.5.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {topos_node-1.5.3/topos_node.egg-info → topos_node-1.5.4}/PKG-INFO +1 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/pyproject.toml +1 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/__version__.py +2 -2
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/app.py +21 -7
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/commands.py +4 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/tray.py +10 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/control_plane_client.py +31 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/registration.py +8 -2
- topos_node-1.5.4/topos/node_stop.py +272 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_generation.py +1 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_protocol.py +103 -5
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_release.py +27 -7
- topos_node-1.5.4/topos/permissions_v2/common_given_names.py +105 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/entity_boundary.py +386 -13
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/knowledge_contract.py +14 -4
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/runtime.py +21 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_index.py +106 -8
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_release.py +12 -5
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/job_runner.py +58 -5
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/runtime_shutdown.py +9 -4
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/upgrades/manifests.json +11 -0
- {topos_node-1.5.3 → topos_node-1.5.4/topos_node.egg-info}/PKG-INFO +1 -1
- {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/SOURCES.txt +2 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/LICENSE +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/MANIFEST.in +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/README.md +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/setup.cfg +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/shared/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/shared/filtering.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/shared/schema_registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_active_database_binding.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_active_ingestion_binding.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_app_relay_wiring.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_extensions.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_gate_leg_hermeticity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_hub_pipeline_offline_first.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_lane_shards.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_llm_integrations_storage.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_local_gate_composition.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_owner_database_hermeticity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_prewarm_first_run.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_profile_hygiene.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_profiles.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_protocol_handled_types.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_query_field_contract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_sync_dep_pins.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_system_computer_name.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/tests/test_topos_home_hermeticity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/dataset_resolution.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/duckdb_adapter.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/luck_surface.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_communities.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_directed.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_graph.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/messenger_labels.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/person_graph.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/person_overlay.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/profiles.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/query_engine.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/raw_queries.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/analytics/relationship_reads.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/analytics.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/app_registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/backup.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/community_naming_config.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/compute_remote.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/connected_apps.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/conversation_context.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/data_commit.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/data_explorer_table_prefs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/database_explorer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/db.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/device.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/disk_space_config.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/engine_run.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/enrichment.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/enrichment_lab.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/facts_llm_config.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/filter_lab.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/health.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/home_chat.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ingestion_api.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ingestion_compat.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ingestion_sources.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/intelligence_lifecycle.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/llm.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/local_mcp.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/messenger_analytics.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/nsfw_maintenance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_ai_chat_capture.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_capture_receipts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_ingestion.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_native_probe.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_search_maintenance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/permissions_source_installs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/privacy_disclose.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/query_api.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/runtime_bootstrap.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sanitization_ollama_config.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/shell.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/signal.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/signal_extraction_config.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/source_install.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/source_retention.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/source_scrub.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sources.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sources_overview.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/sync.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/tool_index.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/ui_config.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/upgrades.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/usage.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/api/user_identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/auth.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/declared_field_map.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/demo_mappers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/documents_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/grok_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/mappers/transcript_mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/models.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/canonicalization/resolver.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/__main__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/assets/topos_black.png +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/assets/topos_blk_rounded.png +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/assets/topos_white.png +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/profile_cmd.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/reprocess_cmd.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/cli/setup_models_cmd.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/conversation_context_llm.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/facts_llm.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/local_model_builds.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/model_packs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/node_function_providers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/sanitization_ollama.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/settings.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/signal_extraction.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/config/uvicorn_logging.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/contacts/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/contacts/identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/api_models.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/connection_resilience.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/db_health.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/device_helpers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/errors.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/events.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/aggregate.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/common.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/complexity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/config.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/contacts_import.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/database_explorer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/derivation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/device.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/enrichment.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/enrichment_lab.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/filter_lab.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/graph_query.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/graph_summary.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/home_chat.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/ingest.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/mcp_client_elevations.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/mcp_clients.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/messages.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/messenger_analytics.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_bind.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_ingestion.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_owner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/permissions_v2_release.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/query.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/routines.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/signal_features.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/sources.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/timeline_daily.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/handlers/tool_index.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/logging.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/metrics.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/routine_access.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/startup_banner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/state.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/table_layers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/core/types.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/data_explorer_row_delete.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/data_explorer_table_prefs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/data_explorer_tables.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/defaults.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/canonical_writer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/content_policy.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/disclosure_sweep.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/field_registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/nsfw_tags.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/privacy_layer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/disclosure/tier.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/generative_prompts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/generative_response.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/huggingface.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/ollama.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/openai.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/openai_compatible.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/redpill.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/backends/stub.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/client.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/disk_space.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/engine.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/hosted_llm_wallet.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/intake.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/memory_utils.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/model_cache.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/model_manager.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_install.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_pull.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_runtime.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/ollama_setup_guidance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/pipeline_memory.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/queue_manager.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/result_formatter.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/router.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/scoped_token.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/tasks.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/torch_runtime.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/transport.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/usage_guard.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/usage_observation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/engine/validator.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/catalog.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/derivation_recovery.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/derived_tables.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/job_readiness.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/job_writer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/derived_object_embeddings_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/language_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/model_overrides.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/manager.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/mvp_defaults.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/models/versioning.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/orchestrator.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/pipeline_activity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/processor.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/progress_bar.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/record_progress.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/registry_contract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/signal_derivation_config.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment/source_overrides.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/bundles.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/model_resolve.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/schema.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/service.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/enrichment_lab/worker.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/evals/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/evals/enrichment_eval.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/extensions.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/canonical.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/engine.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/entropy.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/focus.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/graph_metrics.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/influence.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/projection.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/snapshots.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/topic_merge.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/topics.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/topics_daily.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/complexity/volatility.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/health.mental.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/net.capability.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/net.character.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/obligations.commitments.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/places.mobility.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/bundled_packs/work.career.yaml +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/candidates.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/commitments.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/guard.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/kernels.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/net_subject_policy.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/packs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/person_bridge.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/person_reading.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/prefilter.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/report_card.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/router.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/social_bench.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/social_kernels.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/surfaces.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/synthesize.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/template.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/verify.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/derivation/writer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/affinity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/affinity_owner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/affinity_quality.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/chatgpt_declared.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/community_names.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/community_naming.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/consolidation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/context_vectors.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/cypher.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/declared_mappings.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/discourse_graph.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/dossier.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/edges.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/fact_materializer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_enrichers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_inputs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_refresh.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/graph_search.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/linking.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/maintenance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/mention_lineage.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/mention_lineage_lane.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/owner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/reads.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/rebuild_subprocess.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/resolver.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/entities/structured_fields.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/evidence_time.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/extract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/llm_extract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/reactions.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/reads.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/facts/verdicts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/fit/evaluator.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/fit/opportunity_types.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole_guard.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole_llm.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/carry_diagnosis.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/contact_excludes.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/derived_scrub.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/exclusions.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/gc.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/off_limits_list.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/off_limits_view.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/lifecycle/record_protection.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/posture.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/roles.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/provenance/writer_class.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_canonical_loader.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_ontology.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_renderer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/brief_schemas.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/chunking.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/cluster_labels.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/conversation_context.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/conversation_windows.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/data_health.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/brief_ontologies.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/intentions.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/interests.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/memory.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/places.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/profile.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/relationships.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/resources.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/time.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/wellbeing.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/definitions/work.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/derived_index.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/derived_spec.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_briefs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_definition_loader.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_profiles.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/dimension_registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/embed_context.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/extraction/artifact_router.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/extraction/artifact_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/extraction/rule_extractors.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/graph_sanitize.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/hybrid_search.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/incremental_clustering.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/model_recommendations.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/query_embed_cache.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/schemas.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/service.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/signal_object_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/source_hydration.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/structured_signal.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/tool_index.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/topic_clustering.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/aggregates.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/commitments.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/rhythm.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/vector_codec.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/vector_math.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/signal/vector_settings.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/definitions.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/engine.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/fold.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/stats/insights.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/temporal/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/temporal/points.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/temporal/records.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/timeline_projection.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/timeline_rollup.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/badges.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/daily.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/dashboard.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/instruments.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/intents.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/features/triage/readiness.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/bundles.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/schema.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/service.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/filter_lab/worker.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/home_chat/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/home_chat/schema.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/home_chat/store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/hosted_pool_lease.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/canonical_pipeline.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/chatgpt_owner_snapshot.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/checkpoints/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/imessage_attributed_text.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/inbox_crypto.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/inbox_drain.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/ingest_helpers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/jobs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/journal_location_fanout.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/journal_time_log_normalize.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_exports.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_sync.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_sync_jobs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/local_sync_schedule.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/log_preview.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/manager.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/owner_snapshot.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/browser_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/calendar_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/chatgpt_export.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/documents_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/github_activity_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/grok_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/messenger_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/transcript_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/parsers/voxterm_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/progress.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/reprocess.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/calendar.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/chatgpt.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/contact_importers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/grok.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/imessage_reader.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/signal_export_parser.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/sources/signal_reader.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/state_machine.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/triggers/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/triggers/file_trigger.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/usage_inbox_dedupe.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/schema_registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/ingestion/validation/schema_validator.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/lineage/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/lineage/provenance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/lineage/tracker.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/llm_integrations_storage.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/mcp_clients.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/mcp_stdio_proxy.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/alerts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/metrics.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/observability/tracing.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/openai_client.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/owner_key.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ai_chat_capture.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_checks.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_gate.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/answer_transport.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/automatic_message_review.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/automatic_review_worker.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/bind_protocol.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/canonical.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/canonical_floor.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/capture_receipts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/chatgpt_coverage.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/checking_model.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/contract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/english_short_words.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/entailment_grounding.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_families.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_review_runtime.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_reviews.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/evidence_time.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/exclusion_floor.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_contract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_eligibility.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_policy.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/fact_projection.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/forwarding.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity_attestation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity_dispatch.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/identity_protocol.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/imessage_reconciliation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/imessage_standing.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/index_rebuilds.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/index_review_guard.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/inferred_facts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_dispatch.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_protocol.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_provenance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ingest_snapshot_facts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_family.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_index.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_relabel.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/interest_review.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/journal_goal_field.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/knowledge_projections.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ledger.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ledger_retention.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/message_evidence.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/message_review_contract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/native_claim_grounding.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/native_imessage_probe.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/node_protocol.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/opaque_ids.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/ownership.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/permitted_derivation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/predicate_classes.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/projection_review_runtime.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/projection_reviews.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/protection_clock.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/protection_doorbell.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/protocol.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/reconciliation_facts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/reconciliation_provenance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/refresh_loop.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/release.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_contract.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_lanes.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_timing.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/search_transport.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/self_bind.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/shadow_labeler_local.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/shadow_rubric.pinned.md +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_catalog.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_counts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_kinds.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/share_week.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/signing.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/snapshot_message_facts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/permissions_v2/switches.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/audit.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/envelope.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/job_secrets.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/job_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/stages.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/pipeline/stub_enqueue.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/principal.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/profiles.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/builders.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/projections/vector_index/health_checks.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/handled_message_types.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/narrowing_vocabulary.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/query_field_contract.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/protocol/retrieval_text_contract.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/aggregate.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/audit.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/closeness.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/collaborators.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/ddr.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/disclosure.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/entity_window.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/exclusion.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/facts_direct.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/fingerprint.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/game_layer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/graph_lane.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/inference.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/intent.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/journal_event_lane.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/manifest.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/manifest_validation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/narrowing.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/overheard.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/packet_resolution.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/pipeline.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/planner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/retrieval.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/runtime.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_arbiter.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_classifier.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_head.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_registry.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_registry_loader.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/scope_shadow.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/session.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/session_utils.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/source_generation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/truth_door.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/truth_facts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/truth_prompts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/turn_classifier.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/types.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/verify.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/query/verify_modes.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/rate_limit.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/relay_stamp.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/routines/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/routines/schema.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/routines/store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/runtime_housekeeping.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/runtime_update.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/explicit_wording.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/hub_pipeline.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/nsfw_classifier.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/ollama_transforms.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/prewarm.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sanitization/privacy_filter.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/container.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/local.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/embeddings/remote.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/interfaces.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/llm/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/llm/base.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/llm/openai.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/local.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/services/postgres.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/bundled_canonical_triples.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/canonical_signal_defaults.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/declared_field_map_spec.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/definitions.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/install_authority.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/install_maintenance.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/install_service.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/retention.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/runtime_install.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/scrub_attribution.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sources/scrub_service.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/startup_banner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/factory.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/fakes.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/postgres/stores.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/protocols.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/sqlite/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/sqlite/stores.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/adapters/sqlite/vector_search.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/activity_tables.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/mapper.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/model.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/ai_chat/tables.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/canonical_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/conversations_tables.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/journal_repair.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/mapping_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/canonical/postgres.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/client.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/connection_tuning.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/activity_writer_columns_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/actor_role_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/backup.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/backup_custody.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/community_names_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/complexity_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/conflict_provenance_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/derived_row_identity_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/documents_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/episodes_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/fact_dimension_by_entity_type_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/mention_table_stamp_backfill_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/net_subject_policy_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/off_limits_carried_waiting_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/owner_only_records_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/permissions_fact_lineage_keys_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/permissions_message_context_indexes_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/permissions_read_path_indexes_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/registry.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/registry_checksums.json +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/remediation_person_model.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/scope_source_generation.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_objects.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/temporal_fields_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/transcripts_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/paths.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/postgres.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/schema.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/schema_probe.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/storage_breakdown.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/db/write_gate.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/derived_row_identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/enrichment/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/normalized/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/normalized/normalized_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/decision.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/oplog_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/oplog/postgres.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/person/identity_resolver.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/projections/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/projections/index_ops_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/projections/vector_index_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/browser_flat_tables.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/file_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/raw_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/raw_tables_manager.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/raw/sqlite_raw_store.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/security/encryption.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/signal_identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/source_settings.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/storage/user_identity.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sync/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sync/client.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/sync_handlers.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/testing/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/testing/lifespan.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/uds.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/uma_contact_enrichment.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/uma_filters.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/upgrades/__init__.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/upgrades/runner.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/utils/base_object.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos/websocket_client.py +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/dependency_links.txt +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/entry_points.txt +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/requires.txt +0 -0
- {topos_node-1.5.3 → topos_node-1.5.4}/topos_node.egg-info/top_level.txt +0 -0
|
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
|
|
|
9
9
|
|
|
10
10
|
[project]
|
|
11
11
|
name = "topos-node"
|
|
12
|
-
version = "1.5.
|
|
12
|
+
version = "1.5.4"
|
|
13
13
|
description = "Topos personal AI engine (FastAPI): local data, sync, control plane WebSocket client"
|
|
14
14
|
readme = "README.md"
|
|
15
15
|
license = "Apache-2.0"
|
|
@@ -287,6 +287,13 @@ async def startup_event() -> None:
|
|
|
287
287
|
|
|
288
288
|
allow_rebuild_children()
|
|
289
289
|
add_shutdown_listener(signal_rebuild_children)
|
|
290
|
+
# BL-168: the stop's own steps (control-plane client first, the ingestion queue parked, the permissions
|
|
291
|
+
# runtime's background work stopped) start at the signal, not when uvicorn's drain reaches shutdown_event.
|
|
292
|
+
from . import node_stop
|
|
293
|
+
|
|
294
|
+
node_stop.bind_loop(asyncio.get_running_loop())
|
|
295
|
+
node_stop.set_background_reaper(_reap_background_tasks)
|
|
296
|
+
add_shutdown_listener(node_stop.begin_stop)
|
|
290
297
|
# This process holds the database, so its backups are the ones the model
|
|
291
298
|
# manager may spend before it evicts a model. The disk floor never resolves
|
|
292
299
|
# that directory for itself — on a split node it runs beside the models, on
|
|
@@ -706,11 +713,19 @@ async def startup_event() -> None:
|
|
|
706
713
|
|
|
707
714
|
@app.on_event("shutdown")
|
|
708
715
|
async def shutdown_event() -> None:
|
|
716
|
+
from . import node_stop
|
|
709
717
|
from .pipeline.job_runner import stop_pipeline_worker
|
|
710
|
-
from .runtime_shutdown import end_runtime
|
|
718
|
+
from .runtime_shutdown import current_generation, end_runtime
|
|
711
719
|
|
|
712
720
|
# Wake cooperative workers (fact_llm / Ollama threads) before awaiting
|
|
713
721
|
# network teardown so Ctrl+C does not wait out a full enrichment batch.
|
|
722
|
+
run = current_generation()
|
|
723
|
+
run.request_stop("app_shutdown")
|
|
724
|
+
# BL-168: the control-plane client closes first, then the ingestion queue
|
|
725
|
+
# is parked (the held job requeued) and the permissions runtime's background
|
|
726
|
+
# work stopped. The same task when a signal or the tray already began it.
|
|
727
|
+
# Before end_runtime, so the queue is parked under THIS run's generation.
|
|
728
|
+
await node_stop.stop_now(run)
|
|
714
729
|
# end_runtime retires THIS run's generation — its workers stop for good —
|
|
715
730
|
# and installs a fresh one, so anything that runs later in this process
|
|
716
731
|
# (another app run, a CLI command, the next test) does not inherit a
|
|
@@ -723,10 +738,10 @@ async def shutdown_event() -> None:
|
|
|
723
738
|
# Reaped before the network teardown below, because these are the writers.
|
|
724
739
|
if state.upgrade_runner_stop is not None:
|
|
725
740
|
state.upgrade_runner_stop.set()
|
|
726
|
-
#
|
|
727
|
-
#
|
|
728
|
-
#
|
|
729
|
-
|
|
741
|
+
# Rebuild children were stopped first inside stop_now (after the control-
|
|
742
|
+
# plane client), because it unblocks the rest: a background task awaiting a
|
|
743
|
+
# rebuild through asyncio.to_thread is stuck until the child dies, however
|
|
744
|
+
# it is cancelled.
|
|
730
745
|
await _reap_background_tasks()
|
|
731
746
|
await stop_pipeline_worker()
|
|
732
747
|
await _reap_upgrade_runner()
|
|
@@ -738,8 +753,7 @@ async def shutdown_event() -> None:
|
|
|
738
753
|
except asyncio.CancelledError:
|
|
739
754
|
pass
|
|
740
755
|
state.engine_presence_task = None
|
|
741
|
-
|
|
742
|
-
await state.control_plane_client.stop()
|
|
756
|
+
# The control-plane client was stopped first, by node_stop.stop_now above.
|
|
743
757
|
# The first-pin thread waits between tries; tell it the app is gone (never blocks).
|
|
744
758
|
from .relay_stamp import stop_first_pin
|
|
745
759
|
|
|
@@ -419,7 +419,10 @@ def main(
|
|
|
419
419
|
log_path=get_log_file_path(),
|
|
420
420
|
)
|
|
421
421
|
else:
|
|
422
|
-
|
|
422
|
+
from topos import node_stop
|
|
423
|
+
|
|
424
|
+
node_stop.enable_exit_deadline()
|
|
425
|
+
uvicorn.run(app, host=host, port=port, log_config=get_uvicorn_log_config(), **node_stop.uvicorn_options())
|
|
423
426
|
|
|
424
427
|
|
|
425
428
|
from topos.cli.reprocess_cmd import reprocess_command # noqa: E402
|
|
@@ -823,8 +823,11 @@ def serve_with_tray(
|
|
|
823
823
|
"""
|
|
824
824
|
import uvicorn
|
|
825
825
|
|
|
826
|
-
|
|
826
|
+
from topos import node_stop
|
|
827
|
+
|
|
828
|
+
config = uvicorn.Config(app, host=host, port=port, log_config=log_config, **node_stop.uvicorn_options())
|
|
827
829
|
server = uvicorn.Server(config)
|
|
830
|
+
node_stop.enable_exit_deadline()
|
|
828
831
|
|
|
829
832
|
def stop_server() -> None:
|
|
830
833
|
# Every tray exit comes through here (Quit, Select Topos, Ctrl+C). None
|
|
@@ -838,6 +841,12 @@ def serve_with_tray(
|
|
|
838
841
|
signal_rebuild_children()
|
|
839
842
|
except Exception as exc: # noqa: BLE001 — never let this cost the exit itself
|
|
840
843
|
print(f"Could not stop graph rebuild children ({exc}); quitting anyway.")
|
|
844
|
+
try:
|
|
845
|
+
# BL-168: the control-plane client, the ingestion queue and the
|
|
846
|
+
# permissions runtime's background work stop now, not after the drain.
|
|
847
|
+
node_stop.begin_stop("tray_quit")
|
|
848
|
+
except Exception as exc: # noqa: BLE001
|
|
849
|
+
print(f"Could not begin the node's stop ({exc}); quitting anyway.")
|
|
841
850
|
finally:
|
|
842
851
|
server.should_exit = True
|
|
843
852
|
|
|
@@ -46,6 +46,11 @@ logger = logging.getLogger("topos.control_plane_client")
|
|
|
46
46
|
#: reconnects itself rather than being evicted.
|
|
47
47
|
PING_INTERVAL_SECONDS = 30.0
|
|
48
48
|
PING_TIMEOUT_SECONDS = 90.0
|
|
49
|
+
#: R-N154 M2: at a stop, how long the asks already being handled get to send their replies before the socket closes.
|
|
50
|
+
#: Inside node_stop's 12 s bound for the client's whole stop.
|
|
51
|
+
INBOUND_DRAIN_SECONDS = 5.0
|
|
52
|
+
#: What an ask that arrives while the node is stopping is answered with, at once.
|
|
53
|
+
STOPPING_ERROR = "Engine is stopping. Retry shortly."
|
|
49
54
|
|
|
50
55
|
_FAST_INBOUND_MESSAGE_TYPES = frozenset(
|
|
51
56
|
{
|
|
@@ -145,6 +150,9 @@ class ControlPlaneClient:
|
|
|
145
150
|
self._inbound_semaphore = asyncio.Semaphore(self._inbound_concurrency_limit)
|
|
146
151
|
self._inbound_tasks: set[asyncio.Task] = set()
|
|
147
152
|
self._inbound_lock = asyncio.Lock()
|
|
153
|
+
# R-N154 M2: set at the start of a stop; new asks are refused while the ones in hand finish.
|
|
154
|
+
self._draining = False
|
|
155
|
+
self._inbound_drain_seconds = INBOUND_DRAIN_SECONDS
|
|
148
156
|
|
|
149
157
|
self._presence_outbox_size = max(1, int(settings.control_plane_presence_outbox_size))
|
|
150
158
|
self._presence_outbox: deque[dict[str, Any]] = deque(maxlen=self._presence_outbox_size)
|
|
@@ -188,6 +196,7 @@ class ControlPlaneClient:
|
|
|
188
196
|
if self._task and not self._task.done():
|
|
189
197
|
return
|
|
190
198
|
self._stop_requested = False
|
|
199
|
+
self._draining = False
|
|
191
200
|
try:
|
|
192
201
|
# Engine handlers run here — the loop the app lives on.
|
|
193
202
|
self._handler_loop = asyncio.get_running_loop()
|
|
@@ -277,6 +286,8 @@ class ControlPlaneClient:
|
|
|
277
286
|
await asyncio.to_thread(self._thread.join, 10.0)
|
|
278
287
|
self._thread = None
|
|
279
288
|
else:
|
|
289
|
+
self._draining = True
|
|
290
|
+
await self._drain_inbound_tasks(self._inbound_drain_seconds)
|
|
280
291
|
self._stop.set()
|
|
281
292
|
if self._ws:
|
|
282
293
|
try:
|
|
@@ -302,7 +313,14 @@ class ControlPlaneClient:
|
|
|
302
313
|
self._set_state("idle")
|
|
303
314
|
|
|
304
315
|
async def _shutdown_on_client_loop(self) -> None:
|
|
305
|
-
"""Runs on the client thread's loop; unblocks _run so the thread exits.
|
|
316
|
+
"""Runs on the client thread's loop; unblocks _run so the thread exits.
|
|
317
|
+
|
|
318
|
+
Two phases (R-N154 M2). First the asks already being handled get up to ``_inbound_drain_seconds`` to send
|
|
319
|
+
their replies while every new ask is refused at once with ``STOPPING_ERROR``: a search past its checkpoint
|
|
320
|
+
has written its receipt and spent its share's allowance, and an admitted answer has its id, so closing under
|
|
321
|
+
them lost the reply the node had already paid for. Then the socket closes and what is left is cancelled."""
|
|
322
|
+
self._draining = True
|
|
323
|
+
await self._drain_inbound_tasks(self._inbound_drain_seconds)
|
|
306
324
|
self._stop.set()
|
|
307
325
|
if self._ws:
|
|
308
326
|
try:
|
|
@@ -311,6 +329,12 @@ class ControlPlaneClient:
|
|
|
311
329
|
pass
|
|
312
330
|
await self._cancel_inbound_tasks()
|
|
313
331
|
|
|
332
|
+
async def _drain_inbound_tasks(self, timeout_s: float) -> None:
|
|
333
|
+
async with self._inbound_lock:
|
|
334
|
+
pending = [task for task in self._inbound_tasks if not task.done()]
|
|
335
|
+
if pending and timeout_s > 0:
|
|
336
|
+
await asyncio.wait(pending, timeout=timeout_s)
|
|
337
|
+
|
|
314
338
|
async def _cancel_inbound_tasks(self) -> None:
|
|
315
339
|
async with self._inbound_lock:
|
|
316
340
|
pending = list(self._inbound_tasks)
|
|
@@ -420,6 +444,12 @@ class ControlPlaneClient:
|
|
|
420
444
|
|
|
421
445
|
async def _schedule_inbound_message(self, ws, data: Dict[str, Any]) -> None:
|
|
422
446
|
msg_type = str(data.get("type") or "")
|
|
447
|
+
if self._draining and msg_type not in _FAST_INBOUND_MESSAGE_TYPES and msg_type != "ping":
|
|
448
|
+
# R-N154 M2: the node is stopping. Refuse at once, so the asker hears now rather than at a timeout.
|
|
449
|
+
request_id = data.get("id")
|
|
450
|
+
if request_id:
|
|
451
|
+
await self._send_ws_json(ws, {"id": request_id, "status": "error", "error": STOPPING_ERROR})
|
|
452
|
+
return
|
|
423
453
|
if msg_type in _FAST_INBOUND_MESSAGE_TYPES:
|
|
424
454
|
task = asyncio.create_task(self._handle_message(ws, data))
|
|
425
455
|
self._inbound_tasks.add(task)
|
|
@@ -70,11 +70,17 @@ def _search_batch_version() -> int:
|
|
|
70
70
|
return 0
|
|
71
71
|
|
|
72
72
|
|
|
73
|
+
# The answer protocol this node serves, 0 when answers are off: 1 wrote answers (1.5.0); 2 also carries the writer
|
|
74
|
+
# a policy's `writer_disclosure` releases (A2A-4 amendment 9). The control plane offers the sharer that choice only
|
|
75
|
+
# to a node advertising 2, because an older node refuses a policy naming the field.
|
|
76
|
+
ANSWER_VERSION = 2
|
|
77
|
+
|
|
78
|
+
|
|
73
79
|
def _answer_version() -> int:
|
|
74
80
|
try:
|
|
75
81
|
from ..permissions_v2 import switches
|
|
76
|
-
return
|
|
77
|
-
|
|
82
|
+
return ANSWER_VERSION if (switches.is_bound() and switches.on(switches.MESSAGE_SEARCH)
|
|
83
|
+
and switches.on(switches.ANSWERS)) else 0
|
|
78
84
|
except Exception:
|
|
79
85
|
return 0
|
|
80
86
|
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""What a stop does the moment it is asked for (BL-168).
|
|
2
|
+
|
|
3
|
+
A node told to stop used to do almost nothing until uvicorn reached the app's
|
|
4
|
+
lifespan shutdown, and uvicorn reaches it only after every in-flight request
|
|
5
|
+
has finished: with no ``timeout_graceful_shutdown`` that wait has no bound. On
|
|
6
|
+
10 Oct 2026 (1.5.3) the port closed at the SIGTERM, then the node ran on for 14
|
|
7
|
+
minutes: its pipeline worker kept running the job it held, nothing stopped the
|
|
8
|
+
permissions runtime's background threads (the catch-up assessment pass, the
|
|
9
|
+
share refresh loop, the index rebuild queue), and the control-plane client,
|
|
10
|
+
which ``shutdown_event`` stops last of all, stayed connected and kept taking
|
|
11
|
+
relayed asks it could no longer answer ("Dropping inbound request due to
|
|
12
|
+
saturation", ~150). It exited when that work happened to end.
|
|
13
|
+
|
|
14
|
+
Now a stop has three parts:
|
|
15
|
+
|
|
16
|
+
1. **At the signal** (``begin_stop``, a ``runtime_shutdown`` listener; the
|
|
17
|
+
tray's Quit calls it too). It only schedules work and starts a timer, as a
|
|
18
|
+
signal handler must. On the app loop, in this order (``stop_now``):
|
|
19
|
+
close the control-plane client, so the control plane stops relaying asks
|
|
20
|
+
to a node that is going away and answers the asker at once; stop any graph
|
|
21
|
+
rebuild child (what a held job may be waiting on); park the
|
|
22
|
+
ingestion queue (``job_runner.park_pipeline_worker``: the job a worker
|
|
23
|
+
holds goes back to the queue, and no worker claims or starts again in
|
|
24
|
+
this run); stop the permissions runtime's background work
|
|
25
|
+
(``runtime.stop_background_work``: catch-up passes, refresh loop, rebuild
|
|
26
|
+
queue, answer jobs; assessments are durable checkpoints and a pass a stop
|
|
27
|
+
cuts short is planned again at the next start). Then the app's own
|
|
28
|
+
background tasks.
|
|
29
|
+
2. **The drain is bounded.** uvicorn waits ``drain_seconds()`` for in-flight
|
|
30
|
+
requests and then cancels them (``uvicorn_options``), so lifespan shutdown
|
|
31
|
+
always runs; ``shutdown_event`` runs ``stop_now`` again first (it is the
|
|
32
|
+
same task when the signal already started it).
|
|
33
|
+
3. **The process is bounded.** Cancelling a coroutine never stops the thread it
|
|
34
|
+
awaits, and on Python 3.10 ``asyncio.run`` and the interpreter join every
|
|
35
|
+
executor thread with no timeout. ``exit_deadline_seconds()`` after the stop
|
|
36
|
+
began, a process still alive logs the threads it was waiting on (names only)
|
|
37
|
+
and exits. SQLite rolls an interrupted transaction back at the next open; a
|
|
38
|
+
claimed job whose requeue never landed is recovered at the next start
|
|
39
|
+
(``recover_pipeline_jobs``).
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
from __future__ import annotations
|
|
43
|
+
|
|
44
|
+
import asyncio
|
|
45
|
+
import logging
|
|
46
|
+
import os
|
|
47
|
+
import threading
|
|
48
|
+
import time
|
|
49
|
+
from typing import Any, Callable, Optional
|
|
50
|
+
|
|
51
|
+
logger = logging.getLogger("topos.node_stop")
|
|
52
|
+
|
|
53
|
+
#: How long uvicorn lets in-flight requests finish before it cancels them.
|
|
54
|
+
DEFAULT_DRAIN_SECONDS = 10.0
|
|
55
|
+
#: From the stop request to a forced exit, if the process is still alive then.
|
|
56
|
+
DEFAULT_EXIT_DEADLINE_SECONDS = 60.0
|
|
57
|
+
#: The control-plane client's own stop waits up to 10 s for its close handshake
|
|
58
|
+
#: and 10 s for its thread; one bound over both.
|
|
59
|
+
CONTROL_PLANE_STOP_SECONDS = 12.0
|
|
60
|
+
#: Parking hands the held job back under the write gate (bounded to 2 s inside).
|
|
61
|
+
PARK_SECONDS = 5.0
|
|
62
|
+
#: The permissions runtime's stops only set events; the bound is for the gate.
|
|
63
|
+
PERMISSIONS_STOP_SECONDS = 5.0
|
|
64
|
+
BACKGROUND_REAP_SECONDS = 5.0
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _env_seconds(name: str, default: float) -> float:
|
|
68
|
+
raw = os.environ.get(name, "").strip()
|
|
69
|
+
if not raw:
|
|
70
|
+
return default
|
|
71
|
+
try:
|
|
72
|
+
value = float(raw)
|
|
73
|
+
except ValueError:
|
|
74
|
+
return default
|
|
75
|
+
return max(0.0, value)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def drain_seconds() -> float:
|
|
79
|
+
"""uvicorn's ``timeout_graceful_shutdown``: ``TOPOS_SHUTDOWN_DRAIN_SECONDS``, default 10."""
|
|
80
|
+
return _env_seconds("TOPOS_SHUTDOWN_DRAIN_SECONDS", DEFAULT_DRAIN_SECONDS)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def exit_deadline_seconds() -> float:
|
|
84
|
+
"""``TOPOS_SHUTDOWN_EXIT_DEADLINE_SECONDS``, default 60; 0 turns the forced exit off."""
|
|
85
|
+
return _env_seconds("TOPOS_SHUTDOWN_EXIT_DEADLINE_SECONDS", DEFAULT_EXIT_DEADLINE_SECONDS)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def uvicorn_options() -> dict:
|
|
89
|
+
"""Keyword arguments every node uvicorn server is built with (CLI and tray)."""
|
|
90
|
+
return {"timeout_graceful_shutdown": max(1, int(round(drain_seconds())))}
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
_lock = threading.Lock()
|
|
94
|
+
_loop: Optional[asyncio.AbstractEventLoop] = None
|
|
95
|
+
_task: Optional[asyncio.Task] = None
|
|
96
|
+
_begun = False
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def bind_loop(loop: asyncio.AbstractEventLoop) -> None:
|
|
100
|
+
"""App startup: the loop ``begin_stop`` schedules on. A new run starts with no stop begun."""
|
|
101
|
+
global _loop, _task, _begun
|
|
102
|
+
with _lock:
|
|
103
|
+
_loop = loop
|
|
104
|
+
_task = None
|
|
105
|
+
_begun = False
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def begin_stop(reason: str = "signal") -> bool:
|
|
109
|
+
"""Start the stop now. Safe inside a signal handler and from any thread.
|
|
110
|
+
|
|
111
|
+
Blocks on no lock the interrupted main thread could be holding: this
|
|
112
|
+
module's ``_lock`` is only tried (a busy lock means a stop is being begun or
|
|
113
|
+
joined already); ``current_generation`` reads without a lock; the
|
|
114
|
+
generation's own lock is reentrant; ``Event.set`` and
|
|
115
|
+
``call_soon_threadsafe`` take only locks no main-thread code here holds
|
|
116
|
+
across a call out. Idempotent per run. Returns True when this call began it."""
|
|
117
|
+
global _begun
|
|
118
|
+
from .runtime_shutdown import current_generation
|
|
119
|
+
|
|
120
|
+
if not _lock.acquire(blocking=False):
|
|
121
|
+
return False
|
|
122
|
+
try:
|
|
123
|
+
if _begun:
|
|
124
|
+
return False
|
|
125
|
+
_begun = True
|
|
126
|
+
loop = _loop
|
|
127
|
+
finally:
|
|
128
|
+
_lock.release()
|
|
129
|
+
generation = current_generation()
|
|
130
|
+
if not generation.is_stop_requested():
|
|
131
|
+
# The tray's Quit is no signal; the run is stopping all the same.
|
|
132
|
+
generation.request_stop(reason)
|
|
133
|
+
_arm_exit_deadline()
|
|
134
|
+
if loop is not None and not loop.is_closed():
|
|
135
|
+
try:
|
|
136
|
+
loop.call_soon_threadsafe(_spawn_on_loop, generation)
|
|
137
|
+
except RuntimeError: # the loop closed between the check and the call
|
|
138
|
+
pass
|
|
139
|
+
return True
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def _spawn_on_loop(generation: Any) -> None:
|
|
143
|
+
global _task
|
|
144
|
+
with _lock:
|
|
145
|
+
if _task is None:
|
|
146
|
+
_task = asyncio.get_running_loop().create_task(_stop_steps(generation), name="node-stop")
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
async def stop_now(generation: Any = None) -> None:
|
|
150
|
+
"""Run the stop's steps once per run (``shutdown_event``; the signal's task when it already began)."""
|
|
151
|
+
global _task, _begun
|
|
152
|
+
from .runtime_shutdown import current_generation
|
|
153
|
+
|
|
154
|
+
with _lock:
|
|
155
|
+
_begun = True
|
|
156
|
+
task = _task
|
|
157
|
+
if task is None or task.get_loop() is not asyncio.get_running_loop():
|
|
158
|
+
task = asyncio.get_running_loop().create_task(
|
|
159
|
+
_stop_steps(generation if generation is not None else current_generation()), name="node-stop"
|
|
160
|
+
)
|
|
161
|
+
_task = task
|
|
162
|
+
await asyncio.shield(task)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
async def _bounded(name: str, step: Callable[[], Any], seconds: float) -> None:
|
|
166
|
+
started = time.monotonic()
|
|
167
|
+
try:
|
|
168
|
+
await asyncio.wait_for(step(), timeout=seconds)
|
|
169
|
+
except asyncio.TimeoutError:
|
|
170
|
+
logger.warning("node stop: %s did not finish within %.0fs; going on", name, seconds)
|
|
171
|
+
except Exception as exc: # noqa: BLE001 — a stop step never stops the stop
|
|
172
|
+
logger.warning("node stop: %s failed (%s)", name, type(exc).__name__)
|
|
173
|
+
else:
|
|
174
|
+
logger.info("node stop: %s done in %.1fs", name, time.monotonic() - started)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
async def _stop_steps(generation: Any) -> None:
|
|
178
|
+
from .core import state
|
|
179
|
+
from .pipeline.job_runner import park_pipeline_worker
|
|
180
|
+
|
|
181
|
+
client = getattr(state, "control_plane_client", None)
|
|
182
|
+
if client is not None:
|
|
183
|
+
await _bounded("control-plane client", client.stop, CONTROL_PLANE_STOP_SECONDS)
|
|
184
|
+
# Before the tasks and workers it unblocks: cancelling a task never stops the thread it awaits, and a job
|
|
185
|
+
# waiting on a rebuild child waits until the child dies (the signal listener has usually stopped it already).
|
|
186
|
+
await _bounded("graph rebuild children", _stop_rebuild_children, REBUILD_STOP_SECONDS)
|
|
187
|
+
await _bounded("ingestion queue", lambda: park_pipeline_worker(generation), PARK_SECONDS)
|
|
188
|
+
|
|
189
|
+
def _permissions() -> Any:
|
|
190
|
+
from .permissions_v2.runtime import stop_background_work
|
|
191
|
+
|
|
192
|
+
return asyncio.to_thread(stop_background_work)
|
|
193
|
+
|
|
194
|
+
await _bounded("permissions background work", _permissions, PERMISSIONS_STOP_SECONDS)
|
|
195
|
+
reap = _background_reaper
|
|
196
|
+
if reap is not None:
|
|
197
|
+
await _bounded("background tasks", reap, BACKGROUND_REAP_SECONDS)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
REBUILD_STOP_SECONDS = 5.0
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def _stop_rebuild_children() -> Any:
|
|
204
|
+
from .features.entities import rebuild_subprocess
|
|
205
|
+
|
|
206
|
+
return asyncio.to_thread(rebuild_subprocess.stop_rebuild_children, 2.0)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
#: ``app._reap_background_tasks``, set at startup (this module never imports the app).
|
|
210
|
+
_background_reaper: Optional[Callable[[], Any]] = None
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def set_background_reaper(reap: Optional[Callable[[], Any]]) -> None:
|
|
214
|
+
global _background_reaper
|
|
215
|
+
_background_reaper = reap
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
_stop_begun = threading.Event()
|
|
219
|
+
_deadline_thread: Optional[threading.Thread] = None
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def enable_exit_deadline() -> bool:
|
|
223
|
+
"""Serving entry points only (``topos-node`` and its tray), before uvicorn starts: arm the forced exit.
|
|
224
|
+
|
|
225
|
+
The timer thread starts here, not at the stop: starting a thread inside a signal handler can deadlock on
|
|
226
|
+
``threading``'s own lock when the signal lands while the main thread is starting one (asyncio's executor
|
|
227
|
+
does, on the loop thread). A process that never calls this (tests, CLI commands) never force-exits."""
|
|
228
|
+
global _deadline_thread
|
|
229
|
+
seconds = exit_deadline_seconds()
|
|
230
|
+
if seconds <= 0:
|
|
231
|
+
return False
|
|
232
|
+
with _lock:
|
|
233
|
+
if _deadline_thread is not None and _deadline_thread.is_alive():
|
|
234
|
+
return True
|
|
235
|
+
_deadline_thread = threading.Thread(
|
|
236
|
+
target=_exit_after_stop, args=(seconds,), name="topos-exit-deadline", daemon=True
|
|
237
|
+
)
|
|
238
|
+
_deadline_thread.start()
|
|
239
|
+
return True
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _arm_exit_deadline() -> None:
|
|
243
|
+
_stop_begun.set()
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
def _exit_after_stop(seconds: float) -> None:
|
|
247
|
+
_stop_begun.wait()
|
|
248
|
+
_exit_after(seconds)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def _still_running() -> list[str]:
|
|
252
|
+
me = threading.current_thread()
|
|
253
|
+
return sorted(
|
|
254
|
+
t.name for t in threading.enumerate() if t is not me and t.is_alive() and t is not threading.main_thread()
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def _exit_after(seconds: float, *, exit: Callable[[int], Any] = os._exit, sleep: Callable[[float], Any] = time.sleep) -> None:
|
|
259
|
+
sleep(seconds)
|
|
260
|
+
names = _still_running()
|
|
261
|
+
logger.warning(
|
|
262
|
+
"node stop: still running %.0fs after the stop was asked for; exiting now (%d thread(s): %s)",
|
|
263
|
+
seconds,
|
|
264
|
+
len(names),
|
|
265
|
+
", ".join(names[:16]) or "-",
|
|
266
|
+
)
|
|
267
|
+
for handler in logging.getLogger().handlers + logger.handlers:
|
|
268
|
+
try:
|
|
269
|
+
handler.flush()
|
|
270
|
+
except Exception: # noqa: BLE001
|
|
271
|
+
pass
|
|
272
|
+
exit(0)
|
|
@@ -325,7 +325,7 @@ DOMAIN_FOLDS = frozenset(_stem(word) for domain, words in CATEGORY_TOPICS.items(
|
|
|
325
325
|
# the walk are unchanged. A family word in a question is a label of the share, never a person's name (`_name_terms`).
|
|
326
326
|
SOURCE_FAMILIES = ("imessage", "chatgpt", "journal", "whatsapp", "signal", "telegram", "gmail", "slack", "discord")
|
|
327
327
|
# AR152 class Q, per-item carriage: on when shipped; a pinned constant so a measurement may run both ways.
|
|
328
|
-
PER_ITEM_CARRIAGE =
|
|
328
|
+
PER_ITEM_CARRIAGE = False # off from 1.5.4 (owner, 11 Oct, BL-163): on the rig it cost 6 of 84 answerable questions with must-abstain 0/60 either way; R-RULES F2's steer fix makes off a precision cost only
|
|
329
329
|
_COORDINATORS = frozenset({"and", "or"})
|
|
330
330
|
_SUBJECT_TOKEN = re.compile(r"[^\W_]+|[,&/]", re.UNICODE)
|
|
331
331
|
|