topos-node 1.4.0__tar.gz → 1.4.1__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.4.0/topos_node.egg-info → topos_node-1.4.1}/PKG-INFO +1 -1
- {topos_node-1.4.0 → topos_node-1.4.1}/pyproject.toml +1 -1
- topos_node-1.4.1/tests/test_hub_pipeline_offline_first.py +210 -0
- topos_node-1.4.1/tests/test_lane_shards.py +219 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_topos_home_hermeticity.py +119 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/__version__.py +2 -2
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/settings.py +6 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/release.py +16 -9
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/search_transport.py +15 -5
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/shadow_index.py +39 -16
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/shadow_labeler_local.py +174 -44
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/shadow_labelers.py +3 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/shadow_rescore.py +126 -31
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/disclosure.py +21 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/inference.py +12 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/retrieval.py +9 -4
- topos_node-1.4.1/topos/sanitization/hub_pipeline.py +73 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sanitization/nsfw_classifier.py +8 -2
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sanitization/privacy_filter.py +5 -3
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/__init__.py +70 -14
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/upgrades/manifests.json +6 -0
- {topos_node-1.4.0 → topos_node-1.4.1/topos_node.egg-info}/PKG-INFO +1 -1
- {topos_node-1.4.0 → topos_node-1.4.1}/topos_node.egg-info/SOURCES.txt +3 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/LICENSE +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/MANIFEST.in +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/README.md +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/setup.cfg +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/shared/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/shared/filtering.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/shared/schema_registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_active_database_binding.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_active_ingestion_binding.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_extensions.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_gate_leg_hermeticity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_llm_integrations_storage.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_local_gate_composition.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_owner_database_hermeticity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_prewarm_first_run.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_profile_hygiene.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_profiles.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_protocol_handled_types.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_query_field_contract.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_sync_dep_pins.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/tests/test_system_computer_name.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/dataset_resolution.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/duckdb_adapter.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/luck_surface.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/messenger_communities.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/messenger_directed.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/messenger_graph.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/messenger_labels.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/person_graph.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/person_overlay.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/profiles.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/query_engine.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/raw_queries.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/analytics/relationship_reads.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/analytics.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/app_registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/backup.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/community_naming_config.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/compute_remote.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/connected_apps.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/conversation_context.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/data_commit.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/data_explorer_table_prefs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/database_explorer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/db.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/device.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/disk_space_config.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/engine_run.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/enrichment.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/enrichment_lab.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/facts_llm_config.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/filter_lab.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/health.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/home_chat.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/ingestion_api.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/ingestion_compat.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/ingestion_sources.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/intelligence_lifecycle.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/llm.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/local_mcp.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/messenger_analytics.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/permissions_identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/permissions_ingestion.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/privacy_disclose.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/query_api.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/runtime_bootstrap.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/sanitization_ollama_config.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/shell.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/signal.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/signal_extraction_config.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/source_install.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/source_scrub.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/sources.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/sources_overview.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/sync.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/tool_index.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/ui_config.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/uma_data.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/upgrades.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/usage.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/api/user_identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/app.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/auth.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/declared_field_map.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/browser_activity_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/chatgpt_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/demo_mappers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/documents_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/github_activity_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/google_calendar_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/grok_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/messenger_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/mappers/transcript_mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/models.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/canonicalization/resolver.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/__main__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/assets/topos_black.png +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/assets/topos_blk_rounded.png +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/assets/topos_white.png +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/commands.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/profile_cmd.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/reprocess_cmd.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/setup_models_cmd.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/cli/tray.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/conversation_context_llm.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/facts_llm.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/local_model_builds.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/model_packs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/node_function_providers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/sanitization_ollama.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/signal_extraction.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/config/uvicorn_logging.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/contacts/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/contacts/identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/control_plane_client.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/api_models.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/connection_resilience.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/db_health.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/device_helpers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/errors.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/events.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/aggregate.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/common.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/complexity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/config.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/contacts_import.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/database_explorer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/derivation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/device.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/enrichment.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/enrichment_lab.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/filter_lab.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/graph_query.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/graph_summary.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/home_chat.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/ingest.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/mcp_client_elevations.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/mcp_clients.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/messages.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/messenger_analytics.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/permissions_v2.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/permissions_v2_identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/permissions_v2_ingestion.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/permissions_v2_release.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/query.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/routines.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/shadow_rescore.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/signal_features.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/sources.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/timeline_daily.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/tool_index.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/handlers/uma.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/logging.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/metrics.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/routine_access.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/startup_banner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/state.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/table_layers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/core/types.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/data_explorer_row_delete.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/data_explorer_table_prefs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/data_explorer_tables.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/defaults.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/disclosure/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/disclosure/canonical_writer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/disclosure/content_policy.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/disclosure/field_registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/disclosure/privacy_layer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/disclosure/tier.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/generative_prompts.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/generative_response.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/huggingface.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/ollama.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/openai.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/openai_compatible.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/redpill.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/backends/stub.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/client.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/disk_space.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/engine.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/hosted_llm_wallet.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/intake.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/memory_utils.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/model_cache.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/model_manager.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/ollama_install.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/ollama_pull.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/ollama_runtime.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/ollama_setup_guidance.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/pipeline_memory.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/queue_manager.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/registration.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/result_formatter.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/router.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/scoped_token.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/tasks.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/torch_runtime.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/transport.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/usage_guard.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/usage_observation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/engine/validator.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/catalog.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/derivation_recovery.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/derived_tables.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/job_readiness.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/job_writer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/_batch_limits.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/_engine_runner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/attention_triage_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/availability_scores_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/brief_fallback.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/complexity_snapshot_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/derivation_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/derived_object_embeddings_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/dimension_summary_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/embeddings_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/emo_27_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/entities_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/fact_extraction_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/goal_extraction_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/pii_redaction_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/relationship_edges_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/sentiment_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/statistics_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/timeline_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/topic_clusters_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/canonical/topics_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/raw/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/raw/attachments_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/raw/language_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/raw/time_normalization_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/jobs/raw/tool_calls_job.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/model_overrides.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/models/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/models/manager.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/models/mvp_defaults.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/models/registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/models/versioning.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/orchestrator.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/pipeline_activity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/processor.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/progress_bar.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/record_progress.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/registry_contract.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/signal_derivation_config.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment/source_overrides.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment_lab/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment_lab/bundles.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment_lab/model_resolve.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment_lab/schema.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment_lab/service.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment_lab/store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/enrichment_lab/worker.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/evals/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/evals/enrichment_eval.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/extensions.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/canonical.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/engine.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/entropy.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/focus.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/graph_metrics.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/influence.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/projection.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/snapshots.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/topic_merge.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/topics.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/topics_daily.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/complexity/volatility.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/_scales.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/admin.legal.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/aspirations.goals.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/behavior.habits.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/behavior.preferences.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/beliefs.civic.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/beliefs.spiritual.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/communication.style.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/community.membership.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/craft.tooling.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/expertise.knowledge.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/finances.economics.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/health.lifestyle.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/health.mental.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/health.physical.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/household.pets.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/identity.core.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/interests.taste.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/life.events.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/narrative.self.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/net.capability.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/net.character.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/obligations.commitments.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/personality.traits.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/places.mobility.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/possessions.assets.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/relationships.social.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/values.motivation.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/dispositions.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/expertise.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/habits.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/interests.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/preferences.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/stances.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/tools.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/vocab/values.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/bundled_packs/work.career.yaml +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/candidates.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/commitments.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/guard.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/kernels.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/net_subject_policy.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/packs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/person_bridge.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/person_reading.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/prefilter.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/report_card.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/router.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/social_bench.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/social_kernels.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/surfaces.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/synthesize.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/template.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/verify.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/derivation/writer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/affinity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/affinity_owner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/affinity_quality.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/chatgpt_declared.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/community_names.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/community_naming.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/consolidation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/context_vectors.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/cypher.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/declared_mappings.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/discourse_graph.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/dossier.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/edges.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/fact_materializer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/graph_enrichers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/graph_refresh.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/graph_search.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/linking.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/maintenance.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/mention_lineage.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/mention_lineage_lane.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/owner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/reads.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/rebuild_subprocess.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/resolver.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/entities/structured_fields.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/evidence_time.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/extract.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/llm_extract.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/reactions.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/reads.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/facts/verdicts.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/fit/evaluator.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/fit/opportunity_types.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/blackhole.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/blackhole_guard.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/blackhole_llm.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/blackhole_rebuild.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/derived_scrub.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/exclusions.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/gc.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/lifecycle/record_protection.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/provenance/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/provenance/posture.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/provenance/roles.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/brief_canonical_loader.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/brief_ontology.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/brief_renderer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/brief_schemas.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/chunking.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/cluster_labels.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/conversation_context.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/conversation_windows.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/data_health.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/brief_ontologies.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/intentions.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/interests.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/memory.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/places.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/profile.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/relationships.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/resources.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/schema/dimension_definition.schema.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/time.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/wellbeing.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/definitions/work.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/derived_index.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/derived_spec.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/dimension_briefs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/dimension_definition_loader.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/dimension_profiles.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/dimension_registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/embed_context.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/extraction/artifact_router.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/extraction/artifact_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/extraction/rule_extractors.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/graph_sanitize.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/hybrid_search.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/incremental_clustering.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/model_recommendations.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/query_embed_cache.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/schemas.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/service.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/signal_object_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/source_hydration.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/structured_signal.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/tool_index.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/topic_clustering.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/typed_stores/aggregates.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/typed_stores/commitments.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/typed_stores/rhythm.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/typed_stores/scope_materializer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/vector_codec.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/vector_math.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/signal/vector_settings.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/stats/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/stats/definitions.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/stats/engine.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/stats/fold.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/stats/insights.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/temporal/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/temporal/points.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/temporal/records.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/timeline_projection.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/timeline_rollup.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/triage/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/triage/badges.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/triage/daily.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/triage/dashboard.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/triage/instruments.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/triage/intents.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/features/triage/readiness.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/filter_lab/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/filter_lab/bundles.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/filter_lab/schema.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/filter_lab/service.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/filter_lab/store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/filter_lab/worker.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/home_chat/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/home_chat/schema.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/home_chat/store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/hosted_pool_lease.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/canonical_pipeline.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/chatgpt_owner_snapshot.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/checkpoints/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/checkpoints/checkpoint_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/checkpoints/sqlite_checkpoint_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/inbox_crypto.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/inbox_drain.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/ingest_helpers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/jobs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/journal_location_fanout.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/journal_time_log_normalize.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/local_exports.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/local_sync.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/local_sync_jobs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/log_preview.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/manager.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/owner_snapshot.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/browser_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/calendar_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/chatgpt_conversation_flattener.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/chatgpt_export.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/chatgpt_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/demo_file_parsers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/documents_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/github_activity_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/google_calendar_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/grok_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/messenger_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/transcript_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/parsers/voxterm_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/progress.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/reprocess.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/calendar.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/chatgpt.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/contact_importers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/grok.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/imessage_reader.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/signal_export_parser.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/sources/signal_reader.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/state_machine.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/triggers/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/triggers/file_trigger.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/triggers/sqlite_trigger.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/usage_inbox_dedupe.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/validation/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/validation/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/validation/schema_registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/ingestion/validation/schema_validator.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/lineage/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/lineage/provenance.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/lineage/tracker.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/llm_integrations_storage.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/mcp_clients.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/mcp_stdio_proxy.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/observability/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/observability/alerts.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/observability/metrics.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/observability/tracing.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/openai_client.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/owner_key.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/canonical.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/canonical_floor.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/contract.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/evidence.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/evidence_review_runtime.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/evidence_reviews.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/exclusion_floor.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/__main__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/evaluators.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/fact_bridge.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/harness.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/models.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/retention.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/scoring.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/source_bridge.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/experiments/synthetic.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/fact_contract.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/fact_eligibility.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/fact_policy.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/fact_projection.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/fact_release.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/fact_release_transport.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/forwarding.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/identity_attestation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/identity_dispatch.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/identity_protocol.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/ingest_dispatch.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/ingest_protocol.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/ingest_provenance.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/ingest_snapshot_facts.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/ledger.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/ledger_retention.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/node_protocol.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/opaque_ids.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/projection_review_runtime.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/projection_reviews.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/protection_clock.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/protocol.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/release_transport.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/runtime.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/search_contract.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/search_index.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/search_lanes.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/search_release.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/permissions_v2/signing.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/audit.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/envelope.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/job_runner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/job_secrets.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/job_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/stages.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/pipeline/stub_enqueue.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/principal.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/profiles.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/projections/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/projections/vector_index/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/projections/vector_index/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/projections/vector_index/builders.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/projections/vector_index/health_checks.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/protocol/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/protocol/handled_message_types.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/protocol/narrowing_vocabulary.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/protocol/query_field_contract.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/protocol/retrieval_text_contract.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/aggregate.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/audit.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/closeness.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/cohort_resolvers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/collaborators.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/ddr.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/entity_window.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/exclusion.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/facts_direct.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/fingerprint.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/game_layer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/grant_cache.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/graph_lane.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/intent.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/journal_event_lane.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/manifest.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/manifest_validation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/minimizer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/narrowing.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/negotiation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/overheard.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/packet_resolution.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/pipeline.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/planner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/runtime.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/scope_arbiter.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/scope_classifier.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/scope_head.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/scope_registry.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/scope_registry_loader.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/scope_shadow.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/session.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/session_utils.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/source_generation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/truth_door.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/truth_facts.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/truth_prompts.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/turn_classifier.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/types.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/verify.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/query/verify_modes.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/rate_limit.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/relay_stamp.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/routines/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/routines/schema.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/routines/store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/runtime_housekeeping.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/runtime_shutdown.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/runtime_update.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sanitization/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sanitization/ollama_transforms.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sanitization/prewarm.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/scope_resolution.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/container.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/embeddings/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/embeddings/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/embeddings/local.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/embeddings/remote.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/interfaces.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/llm/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/llm/base.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/llm/openai.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/local.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/services/postgres.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/bundled_canonical_triples.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/canonical_signal_defaults.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/declared_field_map_spec.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/definitions.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/install_service.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/runtime_install.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/scrub_attribution.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sources/scrub_service.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/startup_banner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/factory.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/fakes.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/postgres/stores.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/protocols.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/sqlite/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/sqlite/stores.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/adapters/sqlite/vector_search.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/activity_tables.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/ai_chat/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/ai_chat/canonicalizer.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/ai_chat/mapper.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/ai_chat/model.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/ai_chat/tables.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/calendar_contacts_tables.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/canonical_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/conversations_tables.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/journal_repair.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/mapping_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/canonical/postgres.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/client.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/connection_tuning.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/activity_events_content_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/actor_role_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/affinity_pair_labels_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/attention_triage_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/attention_triage_v2.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/backup.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/backup_custody.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/calendar_events_scheduling_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/canonical_address_book_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/canonical_disclosure_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/canonical_nsfw_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/community_names_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/complexity_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/conflict_provenance_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/conversation_context_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/derivation_factory_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/derivation_ledger_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/derivation_provenance_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/derived_row_identity_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/documents_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/enrichment_record_progress_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/enrichment_spec_version_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_affinity_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_blackhole_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_context_vectors_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_context_vectors_v2.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_edges_validity_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_mentions_authored_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_review_candidate_bar_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_review_dedup_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/entity_review_provenance_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/episodes_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/extraction_artifacts.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/fact_dimension_by_entity_type_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/journal_entries_duration_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/journal_entries_ends_at_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/journal_entries_people_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/journal_entries_place_name_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/journal_entries_starts_at_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/journal_origin_dimension_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/mention_table_stamp_backfill_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/message_emotions_role_backfill_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/message_emotions_role_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/net_subject_policy_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/owner_only_records_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/pack_registry_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/permissions_fact_lineage_keys_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/permissions_read_path_indexes_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/pipeline_jobs_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/query_artifacts_duration_ms_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/registry.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/registry_checksums.json +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/remediation_person_model.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/retire_url_classification_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/scope_source_generation.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/signal_dimension_backfill_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/signal_dimension_harness.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/signal_objects.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/signal_objects_period_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/signal_objects_updated_by_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/signal_summaries_drop_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/stage9_column_renames.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/temporal_fields_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/transcripts_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/vector_storage_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/vector_storage_v2.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/vector_storage_v3.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/vector_storage_v4.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_clusters_v2.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_entities_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_entity_review_v2.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_facts_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_lifecycle_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_mvp_phase0.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_mvp_phase1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_mvp_phase4_messages_cutover.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_mvp_phase5_topic_clusters.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_mvp_phase6_dimension_briefs.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_mvp_query_quality.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_mvp_topic_clusters_coordination.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_stats_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/migrations/wiki_timeline_v1.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/paths.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/postgres.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/schema.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/schema_probe.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/storage_breakdown.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/db/write_gate.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/derived_row_identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/enrichment/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/enrichment/canonical_enrichment_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/enrichment/raw_enrichment_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/normalized/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/normalized/normalized_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/oplog/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/oplog/decision.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/oplog/oplog_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/oplog/postgres.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/person/identity_resolver.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/projections/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/projections/index_ops_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/projections/vector_index_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/raw/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/raw/browser_flat_tables.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/raw/file_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/raw/raw_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/raw/raw_tables_manager.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/raw/sqlite_raw_store.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/security/encryption.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/signal_identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/source_settings.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/storage/user_identity.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sync/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sync/client.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/sync_handlers.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/testing/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/testing/lifespan.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/uds.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/uma_authority.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/uma_contact_enrichment.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/uma_filters.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/uma_resource_id.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/uma_rpt.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/upgrades/__init__.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/upgrades/runner.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/utils/base_object.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos/websocket_client.py +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos_node.egg-info/dependency_links.txt +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos_node.egg-info/entry_points.txt +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/topos_node.egg-info/requires.txt +0 -0
- {topos_node-1.4.0 → topos_node-1.4.1}/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.4.
|
|
12
|
+
version = "1.4.1"
|
|
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"
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""A cached model loads with no Hub request; only a cache miss talks to the Hub.
|
|
2
|
+
|
|
3
|
+
The boot of 2026-09-25 sat for hours in a Hub GET that carries no timeout
|
|
4
|
+
(transformers' tokenizer loader listing chat templates), with the tray on
|
|
5
|
+
"preparing models (0 of 2)" and every later caller of the privacy-filter slot
|
|
6
|
+
waiting behind it. These tests pin the shape that avoids the request entirely:
|
|
7
|
+
tokenizer and model built with `local_files_only=True` first, handed to
|
|
8
|
+
`pipeline()` as objects, and the Hub consulted only after that attempt fails
|
|
9
|
+
the way transformers fails a cache miss. They drive a fake `transformers` so no
|
|
10
|
+
weights are needed; the real loads were measured at zero requests.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import logging
|
|
16
|
+
import os
|
|
17
|
+
import sys
|
|
18
|
+
import types
|
|
19
|
+
|
|
20
|
+
import pytest
|
|
21
|
+
|
|
22
|
+
from topos.sanitization import hub_pipeline
|
|
23
|
+
|
|
24
|
+
REPO = "example/some-classifier"
|
|
25
|
+
CACHE_MISS = OSError(
|
|
26
|
+
"We couldn't connect to 'https://huggingface.co' to load the files, "
|
|
27
|
+
"and couldn't find them in the cached files."
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Calls:
|
|
32
|
+
def __init__(self) -> None:
|
|
33
|
+
self.from_pretrained: list[tuple[str, str, dict]] = []
|
|
34
|
+
self.pipeline: list[tuple[str, object, dict]] = []
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def fake_transformers(
|
|
38
|
+
calls: Calls, *, cached: bool = True, model_error: BaseException | None = None
|
|
39
|
+
):
|
|
40
|
+
"""The four names load_pipeline touches, recording every call.
|
|
41
|
+
|
|
42
|
+
`cached=False` is an empty cache: every `local_files_only` load raises the
|
|
43
|
+
OSError transformers raises for one. `model_error` is raised by the model
|
|
44
|
+
head's loader on top of that.
|
|
45
|
+
"""
|
|
46
|
+
mod = types.ModuleType("transformers")
|
|
47
|
+
|
|
48
|
+
def _auto(name: str, error: BaseException | None = None):
|
|
49
|
+
class Auto:
|
|
50
|
+
@classmethod
|
|
51
|
+
def from_pretrained(cls, model_id: str, **kwargs):
|
|
52
|
+
calls.from_pretrained.append((name, model_id, kwargs))
|
|
53
|
+
if not cached and kwargs.get("local_files_only"):
|
|
54
|
+
raise CACHE_MISS
|
|
55
|
+
if error is not None:
|
|
56
|
+
raise error
|
|
57
|
+
return (name, model_id)
|
|
58
|
+
|
|
59
|
+
Auto.__name__ = name
|
|
60
|
+
return Auto
|
|
61
|
+
|
|
62
|
+
mod.AutoTokenizer = _auto("AutoTokenizer")
|
|
63
|
+
mod.AutoModelForTokenClassification = _auto("AutoModelForTokenClassification", model_error)
|
|
64
|
+
mod.AutoModelForSequenceClassification = _auto("AutoModelForSequenceClassification", model_error)
|
|
65
|
+
|
|
66
|
+
def pipeline(task: str, model, **kwargs):
|
|
67
|
+
calls.pipeline.append((task, model, kwargs))
|
|
68
|
+
return ("pipeline", task, model, kwargs)
|
|
69
|
+
|
|
70
|
+
mod.pipeline = pipeline
|
|
71
|
+
return mod
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@pytest.fixture
|
|
75
|
+
def calls(monkeypatch):
|
|
76
|
+
calls = Calls()
|
|
77
|
+
monkeypatch.setitem(sys.modules, "transformers", fake_transformers(calls))
|
|
78
|
+
return calls
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _load(model_class: str = "AutoModelForTokenClassification", **kwargs):
|
|
82
|
+
return hub_pipeline.load_pipeline(
|
|
83
|
+
"token-classification", REPO, model_class=model_class, **kwargs
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def test_a_cached_model_loads_both_parts_offline_and_hands_pipeline_objects(calls):
|
|
88
|
+
handle = _load(device="cpu")
|
|
89
|
+
|
|
90
|
+
assert calls.from_pretrained == [
|
|
91
|
+
("AutoTokenizer", REPO, {"local_files_only": True}),
|
|
92
|
+
("AutoModelForTokenClassification", REPO, {"local_files_only": True}),
|
|
93
|
+
]
|
|
94
|
+
# pipeline() gets objects, so it has nothing left to resolve against the Hub.
|
|
95
|
+
assert calls.pipeline == [
|
|
96
|
+
(
|
|
97
|
+
"token-classification",
|
|
98
|
+
("AutoModelForTokenClassification", REPO),
|
|
99
|
+
{"tokenizer": ("AutoTokenizer", REPO), "device": "cpu"},
|
|
100
|
+
)
|
|
101
|
+
]
|
|
102
|
+
assert handle[0] == "pipeline"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def test_a_cold_cache_fails_the_offline_attempt_and_loads_through_the_hub(
|
|
106
|
+
monkeypatch, caplog
|
|
107
|
+
):
|
|
108
|
+
calls = Calls()
|
|
109
|
+
monkeypatch.setitem(sys.modules, "transformers", fake_transformers(calls, cached=False))
|
|
110
|
+
|
|
111
|
+
with caplog.at_level(logging.INFO, logger="topos.sanitization.hub_pipeline"):
|
|
112
|
+
_load(device="cpu")
|
|
113
|
+
|
|
114
|
+
# The tokenizer is the first thing asked for, and the first to refuse.
|
|
115
|
+
assert calls.from_pretrained == [("AutoTokenizer", REPO, {"local_files_only": True})]
|
|
116
|
+
assert calls.pipeline == [("token-classification", REPO, {"device": "cpu"})]
|
|
117
|
+
assert "loading from the Hub" in caplog.text
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_a_file_the_loader_wants_but_the_cache_lacks_is_a_cache_miss_too(monkeypatch):
|
|
121
|
+
"""A newer transformers may ask for a file an older download never fetched."""
|
|
122
|
+
calls = Calls()
|
|
123
|
+
monkeypatch.setitem(
|
|
124
|
+
sys.modules, "transformers", fake_transformers(calls, model_error=CACHE_MISS)
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
_load()
|
|
128
|
+
|
|
129
|
+
assert [name for name, _repo, _kw in calls.from_pretrained] == [
|
|
130
|
+
"AutoTokenizer",
|
|
131
|
+
"AutoModelForTokenClassification",
|
|
132
|
+
]
|
|
133
|
+
assert calls.pipeline == [("token-classification", REPO, {})]
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def test_a_failure_that_is_not_a_cache_miss_propagates_without_a_hub_retry(monkeypatch):
|
|
137
|
+
"""A wedged torch load is not fixed by a download; the retry would reopen the hang."""
|
|
138
|
+
calls = Calls()
|
|
139
|
+
monkeypatch.setitem(
|
|
140
|
+
sys.modules, "transformers", fake_transformers(calls, model_error=RuntimeError("mps wedged"))
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
with pytest.raises(RuntimeError, match="mps wedged"):
|
|
144
|
+
_load()
|
|
145
|
+
|
|
146
|
+
assert calls.pipeline == []
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def test_an_unknown_model_class_fails_before_anything_loads(calls):
|
|
150
|
+
with pytest.raises(AttributeError):
|
|
151
|
+
_load(model_class="AutoModelForNoSuchHead")
|
|
152
|
+
|
|
153
|
+
assert calls.from_pretrained == []
|
|
154
|
+
assert calls.pipeline == []
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class _PassThroughCache:
|
|
158
|
+
"""The slot cache without residency bookkeeping: run the loader, hand back its result."""
|
|
159
|
+
|
|
160
|
+
def acquire(self, slot, model_id, loader):
|
|
161
|
+
return loader(), False
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def test_the_privacy_filter_loads_through_the_cache_first(calls, monkeypatch):
|
|
165
|
+
from topos.engine import model_cache
|
|
166
|
+
from topos.sanitization import privacy_filter
|
|
167
|
+
|
|
168
|
+
repo = privacy_filter.PRIVACY_FILTER_MODEL_ID
|
|
169
|
+
monkeypatch.setattr(privacy_filter, "_resolve_device", lambda: "cpu")
|
|
170
|
+
monkeypatch.setattr(model_cache, "get_model_cache", lambda: _PassThroughCache())
|
|
171
|
+
|
|
172
|
+
privacy_filter._get_pipeline(repo)
|
|
173
|
+
|
|
174
|
+
assert [(name, kw) for name, _repo, kw in calls.from_pretrained] == [
|
|
175
|
+
("AutoTokenizer", {"local_files_only": True}),
|
|
176
|
+
("AutoModelForTokenClassification", {"local_files_only": True}),
|
|
177
|
+
]
|
|
178
|
+
((task, model, kwargs),) = calls.pipeline
|
|
179
|
+
assert task == "token-classification"
|
|
180
|
+
assert model == ("AutoModelForTokenClassification", repo)
|
|
181
|
+
assert kwargs == {"tokenizer": ("AutoTokenizer", repo), "device": "cpu"}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def test_the_nsfw_classifier_loads_through_the_cache_first_and_keeps_every_label(
|
|
185
|
+
calls, monkeypatch
|
|
186
|
+
):
|
|
187
|
+
from topos.engine import model_cache
|
|
188
|
+
from topos.sanitization import nsfw_classifier
|
|
189
|
+
|
|
190
|
+
repo = nsfw_classifier.DEFAULT_NSFW_CLASSIFIER_MODEL
|
|
191
|
+
monkeypatch.setattr(model_cache, "get_model_cache", lambda: _PassThroughCache())
|
|
192
|
+
|
|
193
|
+
nsfw_classifier._get_pipeline(repo)
|
|
194
|
+
|
|
195
|
+
assert [(name, kw) for name, _repo, kw in calls.from_pretrained] == [
|
|
196
|
+
("AutoTokenizer", {"local_files_only": True}),
|
|
197
|
+
("AutoModelForSequenceClassification", {"local_files_only": True}),
|
|
198
|
+
]
|
|
199
|
+
((task, model, kwargs),) = calls.pipeline
|
|
200
|
+
assert task == "text-classification"
|
|
201
|
+
assert model == ("AutoModelForSequenceClassification", repo)
|
|
202
|
+
# top_k=None is what makes the classifier return both labels, not only the top one.
|
|
203
|
+
assert kwargs == {"tokenizer": ("AutoTokenizer", repo), "top_k": None}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def test_settings_switch_off_the_safetensors_conversion_probe():
|
|
207
|
+
"""The `.bin` conversion thread is four un-timed Hub GETs `local_files_only` does not stop."""
|
|
208
|
+
import topos.config.settings # noqa: F401 (set at import, like the progress-bar default)
|
|
209
|
+
|
|
210
|
+
assert os.environ.get("DISABLE_SAFETENSORS_CONVERSION") == "1"
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"""CI runs the public lane as slices; together they must still be the whole lane.
|
|
2
|
+
|
|
3
|
+
ci.yml's job matrix runs one job per slice of tests/lane_shards.py. Ways that
|
|
4
|
+
silently stop testing something, none of which turns anything red on its own:
|
|
5
|
+
- a slice defined in the table but missing from the matrix: its tests never
|
|
6
|
+
run anywhere;
|
|
7
|
+
- a matrix `exclude:`/`include:`, a `continue-on-error`, or an `if:` on the lane
|
|
8
|
+
step: a slice is skipped, or its red is forgiven;
|
|
9
|
+
- the packaging job skipped behind a red lane: GitHub counts "skipped" as
|
|
10
|
+
passing for a required check;
|
|
11
|
+
- a prefix that no longer names a real path after a rename: its tests fall to
|
|
12
|
+
`rest`, which still runs them, but the balance the table was measured for is
|
|
13
|
+
gone and nobody is told.
|
|
14
|
+
This file fails on each. It runs in every slice (lane_shards.EVERY_SLICE), so no
|
|
15
|
+
one slice's removal takes it along. It also pins the ownership rule that makes
|
|
16
|
+
the slices a partition.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import re
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from types import SimpleNamespace
|
|
24
|
+
|
|
25
|
+
import pytest
|
|
26
|
+
|
|
27
|
+
from tests import lane_shards
|
|
28
|
+
|
|
29
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
30
|
+
CI_WORKFLOW = REPO_ROOT / ".github" / "workflows" / "ci.yml"
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _ci_text() -> str:
|
|
34
|
+
return CI_WORKFLOW.read_text(encoding="utf-8")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _ci_matrix_shards() -> list[str]:
|
|
38
|
+
"""The `shard: [...]` list in ci.yml, textually, like its sibling guard
|
|
39
|
+
tests/test_local_gate_composition.py reads the `run:` lines."""
|
|
40
|
+
found = re.findall(r"^\s*shard:\s*\[([^\]]*)\]\s*$", _ci_text(), re.MULTILINE)
|
|
41
|
+
assert len(found) == 1, f"expected one `shard: [...]` matrix in {CI_WORKFLOW}, found {found}"
|
|
42
|
+
return [name.strip() for name in found[0].split(",") if name.strip()]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_the_ci_matrix_names_every_slice_exactly_once() -> None:
|
|
46
|
+
names = _ci_matrix_shards()
|
|
47
|
+
assert sorted(names) == sorted(lane_shards.SHARDS), (
|
|
48
|
+
f"ci.yml's matrix {names} and tests/lane_shards.py's slices "
|
|
49
|
+
f"{sorted(lane_shards.SHARDS)} disagree. A slice missing from the matrix "
|
|
50
|
+
"is a slice of the lane that CI never runs."
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def test_the_ci_lane_step_runs_the_matrix_slice() -> None:
|
|
55
|
+
"""Without the flag every job would run the whole lane: nothing lost, four times the minutes."""
|
|
56
|
+
lane_lines = [
|
|
57
|
+
line for line in _ci_text().splitlines()
|
|
58
|
+
if re.match(r"^\s*run:\s*uv run pytest tests\s", line)
|
|
59
|
+
]
|
|
60
|
+
assert lane_lines, f"no `run: uv run pytest tests ...` line in {CI_WORKFLOW}"
|
|
61
|
+
assert all(f"{lane_shards.OPTION} ${{{{ matrix.shard }}}}" in line for line in lane_lines), lane_lines
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _ci_job(name: str) -> str:
|
|
65
|
+
"""One job of ci.yml, textually: from its key to the next job key."""
|
|
66
|
+
match = re.search(
|
|
67
|
+
rf"^ {re.escape(name)}:\s*\n(.*?)(?=^ [A-Za-z0-9_-]+:\s*$|\Z)",
|
|
68
|
+
_ci_text(), re.MULTILINE | re.DOTALL,
|
|
69
|
+
)
|
|
70
|
+
assert match is not None, f"no `{name}` job in {CI_WORKFLOW}"
|
|
71
|
+
return match.group(1)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _ci_step(job: str, step_name: str) -> str:
|
|
75
|
+
match = re.search(
|
|
76
|
+
rf"- name: {re.escape(step_name)}\s*\n(.*?)(?=^\s*- name:|\Z)", job, re.MULTILINE | re.DOTALL,
|
|
77
|
+
)
|
|
78
|
+
assert match is not None, f"no `{step_name}` step"
|
|
79
|
+
return match.group(1)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_nothing_in_the_lane_job_skips_a_slice_or_forgives_its_red() -> None:
|
|
83
|
+
job = _ci_job("public-lane")
|
|
84
|
+
for word in ("exclude:", "include:", "continue-on-error"):
|
|
85
|
+
assert word not in job, (
|
|
86
|
+
f"ci.yml's public-lane job now says `{word}`. That can skip a slice or turn a red "
|
|
87
|
+
"slice green while the matrix list still names it; the slices are the lane."
|
|
88
|
+
)
|
|
89
|
+
lane_step = _ci_step(job, "Run public test lane")
|
|
90
|
+
assert not re.search(r"^\s*if:", lane_step, re.MULTILINE), (
|
|
91
|
+
"the lane step has an `if:`, so some slice can skip its tests and still pass"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def test_the_package_job_goes_red_with_the_lane() -> None:
|
|
96
|
+
"""Not merely skipped: a skipped job reports as passing to a required check."""
|
|
97
|
+
job = _ci_job("test-and-package")
|
|
98
|
+
assert re.search(r"^\s*needs:\s*public-lane\s*$", job, re.MULTILINE), job
|
|
99
|
+
assert re.search(r"^ if:\s*\$\{\{\s*!cancelled\(\)\s*\}\}\s*$", job, re.MULTILINE), (
|
|
100
|
+
"test-and-package must run when a slice is red (and only skip on cancel), so that its "
|
|
101
|
+
"check goes red with the lane instead of reporting `skipped`"
|
|
102
|
+
)
|
|
103
|
+
first_step = re.search(r"^\s*steps:\s*\n\s*- name: ([^\n]+)\n(.*?)(?=^\s*- name:)", job,
|
|
104
|
+
re.MULTILINE | re.DOTALL)
|
|
105
|
+
assert first_step is not None, job
|
|
106
|
+
body = first_step.group(2)
|
|
107
|
+
assert "needs.public-lane.result != 'success'" in body and "exit 1" in body, (
|
|
108
|
+
f"the first step of test-and-package ({first_step.group(1)!r}) must fail the job when "
|
|
109
|
+
"the lane did not pass, before any gated step runs"
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_every_prefix_still_names_tests() -> None:
|
|
114
|
+
for name, prefixes in lane_shards.SHARDS.items():
|
|
115
|
+
for prefix in prefixes:
|
|
116
|
+
if prefix.endswith("/"):
|
|
117
|
+
held = list((REPO_ROOT / prefix).rglob("test_*.py"))
|
|
118
|
+
else:
|
|
119
|
+
parent = (REPO_ROOT / prefix).parent
|
|
120
|
+
held = list(parent.glob(Path(prefix).name + "*.py"))
|
|
121
|
+
assert held, (
|
|
122
|
+
f"slice {name!r} claims {prefix!r}, which holds no test files any more. "
|
|
123
|
+
"Its tests now run in `rest`; move the prefix and re-measure the balance "
|
|
124
|
+
"(tests/lane_shards.py says how)."
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def test_no_prefix_is_claimed_twice() -> None:
|
|
129
|
+
"""A tie would go to whichever slice the dict lists first, silently."""
|
|
130
|
+
claimed = [p for prefixes in lane_shards.SHARDS.values() for p in prefixes]
|
|
131
|
+
assert len(claimed) == len(set(claimed)), claimed
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@pytest.mark.parametrize(
|
|
135
|
+
("nodeid", "owner"),
|
|
136
|
+
[
|
|
137
|
+
("tests/permissions_v2/test_evidence.py::test_x", "permissions_v2"),
|
|
138
|
+
# the longer prefix wins over tests/permissions_v2/
|
|
139
|
+
("tests/permissions_v2/test_message_search_index.py::test_x", "message_search_gap"),
|
|
140
|
+
("tests/gap/p3/engine/test_x.py::TestY::test_z[a-b]", "message_search_gap"),
|
|
141
|
+
("tests/features/test_x.py::test_y", "features_topos_core"),
|
|
142
|
+
("tests/topos/test_x.py::test_y", "features_topos_core"),
|
|
143
|
+
("tests/core/test_x.py::test_y", "features_topos_core"),
|
|
144
|
+
("tests/query/test_x.py::test_y", "rest"),
|
|
145
|
+
("tests/test_profiles.py::test_x", "rest"),
|
|
146
|
+
# a directory prefix does not claim a sibling that merely shares its name
|
|
147
|
+
("tests/topos_home_pin_test.py::test_x", "rest"),
|
|
148
|
+
# added after the table was written: runs in `rest`, never dropped
|
|
149
|
+
("tests/a_directory_added_later/test_x.py::test_y", "rest"),
|
|
150
|
+
],
|
|
151
|
+
)
|
|
152
|
+
def test_the_most_specific_prefix_owns_an_item(nodeid: str, owner: str) -> None:
|
|
153
|
+
assert lane_shards.shard_of(nodeid) == owner
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class _Config:
|
|
157
|
+
def __init__(self, shard):
|
|
158
|
+
self._shard = shard
|
|
159
|
+
self.deselected: list = []
|
|
160
|
+
self.hook = SimpleNamespace(pytest_deselected=lambda items: self.deselected.extend(items))
|
|
161
|
+
|
|
162
|
+
def getoption(self, name):
|
|
163
|
+
assert name == "lane_shard"
|
|
164
|
+
return self._shard
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _items(*nodeids):
|
|
168
|
+
return [SimpleNamespace(nodeid=n) for n in nodeids]
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def test_a_slice_keeps_what_it_owns_and_deselects_the_rest() -> None:
|
|
172
|
+
items = _items(
|
|
173
|
+
"tests/permissions_v2/test_evidence.py::test_x",
|
|
174
|
+
"tests/permissions_v2/test_message_search_state.py::test_x",
|
|
175
|
+
"tests/query/test_x.py::test_y",
|
|
176
|
+
)
|
|
177
|
+
config = _Config("rest")
|
|
178
|
+
lane_shards.deselect_other_shards(config, items)
|
|
179
|
+
assert [i.nodeid for i in items] == ["tests/query/test_x.py::test_y"]
|
|
180
|
+
assert len(config.deselected) == 2
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def test_without_the_option_nothing_is_deselected() -> None:
|
|
184
|
+
items = _items("tests/permissions_v2/test_evidence.py::test_x", "tests/query/test_x.py::test_y")
|
|
185
|
+
config = _Config(None)
|
|
186
|
+
lane_shards.deselect_other_shards(config, items)
|
|
187
|
+
assert len(items) == 2 and config.deselected == []
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def test_the_slices_partition_any_set_of_items() -> None:
|
|
191
|
+
"""Every item goes to exactly one slice, so running every slice runs every item
|
|
192
|
+
once; the only exception is the guard in EVERY_SLICE, which runs in each."""
|
|
193
|
+
guard = "tests/test_lane_shards.py::test_the_ci_matrix_names_every_slice_exactly_once"
|
|
194
|
+
nodeids = [
|
|
195
|
+
"tests/permissions_v2/test_evidence.py::test_x",
|
|
196
|
+
"tests/permissions_v2/test_message_search_state.py::test_x",
|
|
197
|
+
"tests/gap/p1/engine/test_x.py::test_y",
|
|
198
|
+
"tests/features/test_x.py::test_y",
|
|
199
|
+
"tests/query/test_x.py::test_y",
|
|
200
|
+
"tests/test_profiles.py::test_x",
|
|
201
|
+
"tests/a_directory_added_later/test_x.py::test_y",
|
|
202
|
+
]
|
|
203
|
+
kept = []
|
|
204
|
+
for shard in lane_shards.SHARDS:
|
|
205
|
+
items = _items(*nodeids, guard)
|
|
206
|
+
lane_shards.deselect_other_shards(_Config(shard), items)
|
|
207
|
+
assert guard in [i.nodeid for i in items], shard
|
|
208
|
+
kept.extend(i.nodeid for i in items if i.nodeid != guard)
|
|
209
|
+
assert sorted(kept) == sorted(nodeids)
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
def test_this_guard_runs_in_every_slice() -> None:
|
|
213
|
+
"""Placed in one slice, it could not see that slice taken out of the matrix."""
|
|
214
|
+
here = f"tests/{Path(__file__).name}::test_this_guard_runs_in_every_slice"
|
|
215
|
+
assert here.startswith(lane_shards.EVERY_SLICE)
|
|
216
|
+
for shard in lane_shards.SHARDS:
|
|
217
|
+
items = _items(here)
|
|
218
|
+
lane_shards.deselect_other_shards(_Config(shard), items)
|
|
219
|
+
assert len(items) == 1, shard
|
|
@@ -163,6 +163,125 @@ def test_conftest_pins_every_topos_home_default_outside_any_home() -> None:
|
|
|
163
163
|
)
|
|
164
164
|
|
|
165
165
|
|
|
166
|
+
# -- the session defaults: what a hop that outlives its test's pin resolves --------
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def test_between_tests_the_session_defaults_hold_not_an_unset_variable(
|
|
170
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
171
|
+
) -> None:
|
|
172
|
+
"""``monkeypatch.undo()`` takes back every autouse pin at once (they share this
|
|
173
|
+
one monkeypatch), which is the state between two tests. At module event-loop
|
|
174
|
+
scope the pipeline worker's last sweep hop runs there, and it opens and
|
|
175
|
+
migrates whatever database path it finds (2026-09-24). Until then that was
|
|
176
|
+
the variable's absence.
|
|
177
|
+
"""
|
|
178
|
+
from tests import topos_home_pin
|
|
179
|
+
from topos.config.settings import settings
|
|
180
|
+
from topos.core import state
|
|
181
|
+
from topos.storage.db.paths import DATABASE_FILENAME, active_base
|
|
182
|
+
|
|
183
|
+
monkeypatch.undo()
|
|
184
|
+
session = topos_home_pin.session_values()
|
|
185
|
+
assert set(session) == set(topos_home_pin.SESSION_DEFAULT_ENV)
|
|
186
|
+
real_topos = os.path.realpath(os.path.join(live_db_watch.REAL_HOME, ".topos"))
|
|
187
|
+
for name, value in session.items():
|
|
188
|
+
assert os.environ.get(name) == value, f"{name} was left {os.environ.get(name)!r}"
|
|
189
|
+
assert not os.path.realpath(value).startswith(real_topos + os.sep), (name, value)
|
|
190
|
+
database = Path(session["TOPOS_DATABASE_PATH"])
|
|
191
|
+
assert settings.topos_database_path == str(database)
|
|
192
|
+
assert state._resolve_database_path_from_settings() == database
|
|
193
|
+
if str(database) == topos_home_pin.session_default_paths()["TOPOS_DATABASE_PATH"]:
|
|
194
|
+
# Nothing exported: the settings route and the active_base route name ONE file.
|
|
195
|
+
assert active_base() / DATABASE_FILENAME == database
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def test_per_test_pins_win_over_the_session_defaults_inside_a_test(
|
|
199
|
+
_live_db_guard_path: str, _scope_shadow_guard_dir: Path
|
|
200
|
+
) -> None:
|
|
201
|
+
"""The session defaults must never reach INTO a test: one shared database let
|
|
202
|
+
tests poison each other (see ``_live_db_guard_path``). Moving them into
|
|
203
|
+
``PINNED_ENV`` would do exactly that, because ``repin_env`` runs after
|
|
204
|
+
``_no_live_db_guard`` at setup; this is the test that fails then.
|
|
205
|
+
"""
|
|
206
|
+
from tests import topos_home_pin
|
|
207
|
+
from topos.config.settings import settings
|
|
208
|
+
from topos.core import state
|
|
209
|
+
from topos.query import scope_shadow
|
|
210
|
+
from topos.storage.db.migrations.backup import backup_dir_for
|
|
211
|
+
|
|
212
|
+
session = topos_home_pin.session_values()
|
|
213
|
+
own_db = Path(_live_db_guard_path)
|
|
214
|
+
assert os.environ["TOPOS_DATABASE_PATH"] == str(own_db) != session["TOPOS_DATABASE_PATH"]
|
|
215
|
+
assert settings.topos_database_path == str(own_db)
|
|
216
|
+
assert state._resolve_database_path_from_settings() == own_db
|
|
217
|
+
assert backup_dir_for(own_db) == own_db.parent / "backups" != Path(session["TOPOS_BACKUP_DIR"])
|
|
218
|
+
assert scope_shadow.default_log_path() == _scope_shadow_guard_dir / "scope_shadow.jsonl"
|
|
219
|
+
assert scope_shadow.default_log_path() != Path(session["TOPOS_SCOPE_SHADOW_LOG"])
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def test_an_exported_path_is_kept_unless_it_points_into_owner_data(tmp_path: Path) -> None:
|
|
223
|
+
"""``just test-owner-db-eval`` exports its snapshot and the lane's modules read
|
|
224
|
+
it at collection, so an export is kept. One into ``~/.topos`` is replaced.
|
|
225
|
+
Against a throwaway root armed as owner data, never the real one.
|
|
226
|
+
"""
|
|
227
|
+
from tests import topos_home_pin
|
|
228
|
+
|
|
229
|
+
owner = tmp_path / "pretend-home" / ".topos"
|
|
230
|
+
owner.mkdir(parents=True)
|
|
231
|
+
pinned = {
|
|
232
|
+
name: str(tmp_path / "session" / rel)
|
|
233
|
+
for name, rel in topos_home_pin.SESSION_DEFAULT_ENV.items()
|
|
234
|
+
}
|
|
235
|
+
snapshot = str(tmp_path / "topos-owner-snapshot-x.db")
|
|
236
|
+
with live_db_watch.watching_root(owner):
|
|
237
|
+
chosen, replaced = topos_home_pin._choose_session_defaults(
|
|
238
|
+
{
|
|
239
|
+
"TOPOS_DATABASE_PATH": snapshot,
|
|
240
|
+
"TOPOS_BACKUP_DIR": str(owner / "backups"),
|
|
241
|
+
"TOPOS_SCOPE_SHADOW_LOG": " ",
|
|
242
|
+
},
|
|
243
|
+
pinned,
|
|
244
|
+
)
|
|
245
|
+
into_owner, replaced_db = topos_home_pin._choose_session_defaults(
|
|
246
|
+
{"TOPOS_DATABASE_PATH": str(owner / "database.db")}, pinned
|
|
247
|
+
)
|
|
248
|
+
assert chosen == {
|
|
249
|
+
"TOPOS_DATABASE_PATH": snapshot,
|
|
250
|
+
"TOPOS_BACKUP_DIR": pinned["TOPOS_BACKUP_DIR"],
|
|
251
|
+
"TOPOS_SCOPE_SHADOW_LOG": pinned["TOPOS_SCOPE_SHADOW_LOG"],
|
|
252
|
+
}
|
|
253
|
+
assert replaced == {"TOPOS_BACKUP_DIR": str(owner / "backups")} # blank is unset
|
|
254
|
+
assert into_owner["TOPOS_DATABASE_PATH"] == pinned["TOPOS_DATABASE_PATH"]
|
|
255
|
+
assert replaced_db == {"TOPOS_DATABASE_PATH": str(owner / "database.db")}
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def test_a_session_default_changed_without_monkeypatch_is_put_back_after_teardown(
|
|
259
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
260
|
+
) -> None:
|
|
261
|
+
"""A raw change would otherwise become the NEXT test's "original": its
|
|
262
|
+
monkeypatch records the leaked value and restores it after every later test.
|
|
263
|
+
"""
|
|
264
|
+
import inspect
|
|
265
|
+
|
|
266
|
+
from tests import conftest, topos_home_pin
|
|
267
|
+
from topos.config.settings import settings
|
|
268
|
+
|
|
269
|
+
monkeypatch.undo()
|
|
270
|
+
session = topos_home_pin.session_values()
|
|
271
|
+
try:
|
|
272
|
+
os.environ.pop("TOPOS_BACKUP_DIR", None)
|
|
273
|
+
os.environ["TOPOS_SCOPE_SHADOW_LOG"] = "/elsewhere/scope_shadow.jsonl"
|
|
274
|
+
settings.topos_database_path = None
|
|
275
|
+
topos_home_pin.restore_session_defaults()
|
|
276
|
+
assert {name: os.environ.get(name) for name in session} == session
|
|
277
|
+
assert settings.topos_database_path == session["TOPOS_DATABASE_PATH"]
|
|
278
|
+
finally:
|
|
279
|
+
topos_home_pin.restore_session_defaults()
|
|
280
|
+
assert "topos_home_pin.restore_session_defaults()" in inspect.getsource(
|
|
281
|
+
conftest.pytest_runtest_logfinish
|
|
282
|
+
), "nothing calls it after teardown, so the property above is untested where it matters"
|
|
283
|
+
|
|
284
|
+
|
|
166
285
|
@pytest.mark.asyncio
|
|
167
286
|
async def test_presence_lifespan_with_a_control_plane_leaves_home_untouched(
|
|
168
287
|
scratch_home: Path, tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
@@ -12,6 +12,12 @@ from topos.config.local_model_builds import tag_for_this_machine
|
|
|
12
12
|
|
|
13
13
|
# Set before any huggingface_hub import during app/route loading.
|
|
14
14
|
os.environ.setdefault("HF_HUB_DISABLE_PROGRESS_BARS", "1")
|
|
15
|
+
# A `.bin` checkpoint makes transformers start a background thread that asks the
|
|
16
|
+
# Hub for a safetensors conversion PR: four GETs with no timeout, past every
|
|
17
|
+
# `local_files_only` guard (topos/sanitization/hub_pipeline.py has the boot that
|
|
18
|
+
# hung in a Hub call). The node never asks the Hub to convert checkpoints for it.
|
|
19
|
+
# setdefault: an operator who wants the probe exports "0".
|
|
20
|
+
os.environ.setdefault("DISABLE_SAFETENSORS_CONVERSION", "1")
|
|
15
21
|
|
|
16
22
|
|
|
17
23
|
DEFAULT_TOPOS_CONTROL_PLANE_URL = "wss://cp.logu3s.com/ws/engine"
|
|
@@ -171,12 +171,16 @@ def source_message_decision(policy: PolicyV2, evidence: QualifiedEvidence) -> De
|
|
|
171
171
|
missing_context_codes=["classification"] if verdict == "indeterminate" else [])
|
|
172
172
|
|
|
173
173
|
|
|
174
|
-
def _file_shadow_index(ledger, *, request_id, grant_id, records, record_key, now) -> None:
|
|
174
|
+
def _file_shadow_index(ledger, *, request_id, grant_id, records, identities, record_key, now) -> None:
|
|
175
175
|
"""File this release in the node's shadow index, if the node keeps one. Never raises into a release.
|
|
176
176
|
|
|
177
177
|
Placed here rather than inside `_checkpoint` because the grant's record key lives on this side: the ledger
|
|
178
178
|
has no key and must not grow one. A release whose index write fails is counted by `shadow_index.failures()`
|
|
179
|
-
and shows up later as
|
|
179
|
+
and shows up later as a `records_unavailable_*` re-score, which is the visible form of the hole.
|
|
180
|
+
|
|
181
|
+
`identities` are the released rows' canonical identities, in the records' order. They are what the sealed
|
|
182
|
+
pointer must hold: under p2a-v3 a record's own id is the opaque one, and a pointer to that could never find
|
|
183
|
+
its row again (every p2a-v3 re-score at e848f512 answered `records_unavailable`).
|
|
180
184
|
"""
|
|
181
185
|
from . import shadow_index
|
|
182
186
|
if not shadow_index.enabled():
|
|
@@ -184,7 +188,7 @@ def _file_shadow_index(ledger, *, request_id, grant_id, records, record_key, now
|
|
|
184
188
|
try:
|
|
185
189
|
with ledger._transaction() as conn:
|
|
186
190
|
shadow_index.record_release(conn, request_id=request_id, grant_id=grant_id, records=records,
|
|
187
|
-
record_key=record_key, now=now)
|
|
191
|
+
identities=identities, record_key=record_key, now=now)
|
|
188
192
|
except Exception: # noqa: BLE001 -- an unauditable read is still a correct read
|
|
189
193
|
shadow_index._count_failure()
|
|
190
194
|
|
|
@@ -262,21 +266,23 @@ class SourceMessageRelease:
|
|
|
262
266
|
now=self.clock())
|
|
263
267
|
raise PolicyError("permission_denied")
|
|
264
268
|
key = self._record_key(signed) if signed.capability_version == CAPABILITY_OPAQUE else None
|
|
265
|
-
|
|
269
|
+
released = []
|
|
266
270
|
for ref in qualified.snapshot.leaves:
|
|
267
271
|
row = rows[_key(ref.identity)]
|
|
268
272
|
identity = ref.identity
|
|
269
273
|
record_id = identity.record_id if key is None else opaque_record_id(key, grant_id=signed.grant_id,
|
|
270
274
|
table=identity.table, source_id=identity.source_id, dataset_id=identity.dataset_id,
|
|
271
275
|
record_id=identity.record_id)
|
|
272
|
-
|
|
273
|
-
|
|
276
|
+
released.append(({"record_id": record_id, "source_id": identity.source_id,
|
|
277
|
+
"canonical_table": identity.table, "content": row.get("content")}, identity))
|
|
274
278
|
if key is not None:
|
|
275
279
|
# The canonical ids are gone from the ids, but the LIST was still ordered by
|
|
276
280
|
# them (the snapshot sorts leaves by their canonical identity), which ranks
|
|
277
281
|
# the records the owner's store holds. Under an opaque view the order is the
|
|
278
|
-
# opaque one, which says nothing a recipient did not already hold.
|
|
279
|
-
|
|
282
|
+
# opaque one, which says nothing a recipient did not already hold. Each record
|
|
283
|
+
# keeps its own identity through the sort: the shadow index seals that.
|
|
284
|
+
released.sort(key=lambda pair: pair[0]["record_id"])
|
|
285
|
+
records = [record for record, _identity in released]
|
|
280
286
|
output = disclosure.parse({"family": "canonical_record", "operation": "read", "view_id": view, "records": records})
|
|
281
287
|
if not records or len(canonical_bytes(output.model_dump())) > MAX_DISCLOSURE_BYTES:
|
|
282
288
|
raise PolicyError("disclosure_budget")
|
|
@@ -292,7 +298,8 @@ class SourceMessageRelease:
|
|
|
292
298
|
# (permissions_v2/shadow_index.py). Ids and a sealed pointer, never content; off unless the node
|
|
293
299
|
# is told otherwise; and inside its own try, so a release is never a casualty of being auditable.
|
|
294
300
|
_file_shadow_index(ledger, request_id=request_id, grant_id=signed.grant_id, records=output.records,
|
|
295
|
-
record_key=key,
|
|
301
|
+
identities=[identity for _record, identity in released], record_key=key,
|
|
302
|
+
now=self.clock())
|
|
296
303
|
checked_at = self.clock()
|
|
297
304
|
verify_current_signature(signed, trusted_keys=ledger.trusted_keys, now=checked_at)
|
|
298
305
|
result = sign_node_result(ReleaseBody(version="topos-node-disclosure/v1",
|