apsimo 1.3.0__tar.gz → 1.3.2__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.
- {apsimo-1.3.0 → apsimo-1.3.2}/PKG-INFO +2 -2
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/authority.py +2 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/host.py +59 -6
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cli.py +1 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/selection.py +22 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/setup.py +2 -2
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/setup_hermes.py +41 -3
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo.egg-info/PKG-INFO +2 -2
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo.egg-info/SOURCES.txt +3 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo.egg-info/requires.txt +1 -1
- {apsimo-1.3.0 → apsimo-1.3.2}/pyproject.toml +2 -2
- apsimo-1.3.2/tests/test_enrolled_sender_turns.py +94 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_turn_outbox.py +4 -1
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_setup.py +93 -0
- apsimo-1.3.2/tests/test_recall_request_repetition.py +140 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_scoped_api_authority.py +11 -9
- apsimo-1.3.2/tests/test_scoped_contact_resolution.py +48 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_vectors.py +8 -3
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_server_integration.py +8 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/LICENSE +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/README.md +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/__main__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/agent/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/agent/client.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/agent/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/agents/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/agents/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/agents/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/agents/websocket.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/auth_telemetry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/contact_grants.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/middleware.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/commitment_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/context_gate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/executions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/followup_plans.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/governed_actions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/initiative_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/mining.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/observations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/social_state.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/task_queue.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/temporal_followups.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/transport.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/routers/transport_ingress_api.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/schemas/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/api/schemas/host.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/autonomy/cli.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/autonomy/condition_worker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/autonomy/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/autonomy/loop.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/autonomy/registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/autonomy/scheduler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/autonomy/synthesis.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/backup.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/contradictions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/decay.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/promotion.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/resolve.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/source_claims.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/source_projection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/source_time.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/beliefs/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/aggregators.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/composer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/delivery.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/engagement.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/enhancer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/scheduler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/briefings/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/block.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/cli.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/genesis.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/identity.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/keys.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/local_keys.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/manager.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/node.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/plugin_transactions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/protocol.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/state_machine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/storage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/transactions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/chain/validation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/channels/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/channels/manifest.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/channels/migrations/001_channels_schema.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/channels/phone_gateways.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/channels/presence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/channels/router.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/channels/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/charter.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/drive_governance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/evidence_pipeline.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/external_events.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/goal_spine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/introspection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/prompt.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/runtime.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/cognition/trigger.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/commitments/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/commitments/local_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/commitments/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/commitments/work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/compat.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/compression/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/connectors/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/connectors/base.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/connectors/caldav_calendar.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/connectors/fs_documents.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/connectors/imap_email.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/connectors/manager.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/connectors/webhook_pull.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/comms.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/exporters/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/exporters/vcard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/identity_links.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/importer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/importers/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/importers/batch.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/importers/macos_contacts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/migrations/001_contacts_schema.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/migrations/002_trust_scopes.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/migrations/003_open_gateway_enum.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/migrations/004_contact_provision_operations.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/migrations/005_identity_links.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/scoring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/transport_ingress.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contacts/world_bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contextgate/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contextgate/chunker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contextgate/estimate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contextgate/gate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/contextgate/retrieve.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/delivery/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/delivery/bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/delivery/channels.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/delivery/classification.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/delivery/rate_limiter.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/delivery/reachout_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directed/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directed/audit.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directed/intake.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directed/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directed/service.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directives/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directives/evidence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directives/extractor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directives/guard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directives/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directives/service.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/directives/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/doctor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/environment.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/events/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/events/broadcaster.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/events/bus.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/events/journal.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/events/stream.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/events/types.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/execution_results.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feedback/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feedback/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/cli.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/example-feed.yaml +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/hermes_cron.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/manager.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/spec.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/feeds/template.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/audit.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/communication_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/context_provenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/env_risk.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/guard_audit.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/base.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/l1_recipient.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/l2_pii.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/l3_cross_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/l4_trust_tier.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/l5_injection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/l6_review.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/l7_delay.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/layers/tom2_epistemic.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/pending_dispatch.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/pipeline.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/rejection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/response_guard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/rulesets/injection_v1.yaml +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/surface_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/gate/taint.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/genesis.json +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/decomposer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/inference.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/priority.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/queue_bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/replan.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/schema.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/goals/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/governed_actions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/harness_integration/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/harness_integration/context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/harness_integration/skills.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity/participants.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity/resolver.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/builder.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/corpus.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/runner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/briefings.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/chain.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/goals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/memory.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/neo4j_cognition.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/relationship.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/sessions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/skills.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/task_queue.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/seeders/world_model.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/self_query.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/self_reflection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/skill.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/identity_bootstrap/verifier.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/action_registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/approval_authority.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/approval_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/assignment.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/backup_evidence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/context_freshness.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/native_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/standing_approvals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/initiatives/temporal_followup.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/gap_detector.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/metalearner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/metrics_collector.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/performance_index.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/strategy_adjuster.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/cognition/types.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/anomaly_detector.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/initiative_engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/preference_learner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/research_orchestrator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/self_directed_thinker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/self_reflector.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/session_continuity.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/task_planner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/components/tool_learner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/client.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/consolidator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/distiller.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/migrations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/queries.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/recall.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/reconciler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/graph/schema.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/learning/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/learning/continuous_learner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/learning/feedback_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/mind_model/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/mind_model/graph_baseline.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/mind_model/signal_collector.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/relationships/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/relationships/profiler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/relationships/scorer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/relationships/signal_floor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/relationships/trust_tiers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/synthesis/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/synthesis/connection_discoverer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/synthesis/cross_domain_analyzer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/synthesis/insight_deliverer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/synthesis/insight_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/synthesis/insight_validator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/synthesis/novelty_scorer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/turn_middleware/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/intelligence/turn_middleware/memory_sync.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mcp/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mcp/__main__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mcp/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mcp/server.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/migrations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mining/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mining/corpus.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mining/escalations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mining/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/mining/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/models/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/models/memory.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/models/mesh.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/models/person.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/models/signal.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/observations/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/observations/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/patterns/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/patterns/extract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/patterns/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/persona/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/persona/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/persona/manifest.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/projects/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/projects/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/projects/event_outbox.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/projects/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/projects/planner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/projects/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/proposals/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/proposals/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/proposals/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/cases.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/cli.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/memory_cases.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/records.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/report.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/runner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/qualification/structured_cases.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/executor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/loop.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/native_tools/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/native_tools/calculate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/native_tools/file_ops.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/native_tools/web_search.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/reasoning/tool_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/redact/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/repos/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/repos/mirrors.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/artifact.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/gatherer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/pipeline.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/base.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/brave.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/cache.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/duckduckgo.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/orchestrator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/serpapi.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/search/tavily.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/research/synthesizer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/complexity_scorer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/endpoints.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/fallback.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/functions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/native_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/router.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/self_learning.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/router/tiers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sandbox/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sandbox/backend.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sandbox/manager.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/scope_bounds.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/backends/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/backends/base.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/backends/env.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/backends/keyring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/backends/onepassword.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/cli.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/manager.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/migration.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/secrets/types.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/seed.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/appraisals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/benchmark.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/brief.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/event_concerns.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/execution_forecasts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/expectations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/experiments.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/journal.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/judgments.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/native_outcomes.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/params.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/perspective.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/reconcile.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/reply_forecasts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/runtime_forecasts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/runtime_models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/settlement.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/situation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/supervised.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/thinker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/trust.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/self_model/workspace.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/server.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/services/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/services/agent_bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/services/initiative_executor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/services/instance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sessions/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sessions/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sessions/context_loader.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sessions/federation_session.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sessions/isolated_session.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sessions/reports.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/sessions/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/setup_local_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/setup_native_goals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/setup_native_reviews.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/base.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/budget.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executors/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executors/behavioral_correction.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executors/capability_gap.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executors/data_quality.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executors/knowledge_acquisition.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executors/operational_hygiene.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/executors/subsystem_health.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/hermes_export.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/index.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/learning/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/learning/novelty_detector.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/learning/pattern_extractor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/learning/triggers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/loader.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/migrations/002_progressive_loading.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/migrations/backfill_triggers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/packager.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/protocols.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/runtime.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/sandbox_runner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/scheduler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/schema.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/security/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/security/guards.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills/security/scanner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills_memory/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills_memory/distill.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills_memory/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills_memory/retrieve.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/skills_memory/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/surprise/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/surprise/accumulation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/surprise/scorer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/surprise/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/action_receipts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/approval_relay_canary.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/contract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/events.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/governor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/handlers/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/handlers/base.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/handlers/inference.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/handlers/monitoring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/handlers/registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/handlers/subtask_handler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/handlers/system_maintenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/mesh_integration.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/models.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/queue_manager.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/routing.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/scheduler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/schema.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/work_control.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/task_queue/worker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/telemetry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/affect.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/approvals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/arcs.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/asymmetry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/eligibility.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/engagement.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/exposure.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/extractor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/fact_adapters.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/facts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/integration.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/leveled.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/levels.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/recipient_audit.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/recipient_simulator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/source_lineage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/tom2.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/visibility.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tom/visibility_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tools/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tools/definitions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/tools/handlers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/toolsmith/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/toolsmith/authority.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/toolsmith/engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/toolsmith/integrity.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/toolsmith/miner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/toolsmith/policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/toolsmith/registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/audio.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/documents.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/executions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/hermes_history.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/hermes_kanban.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/hermes_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/idempotency.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/local_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/media.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/reported_workers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/source_annotations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/source_attribution.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/source_read.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/source_vectors.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/turns/video.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/util/autonomy_preset.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/util/instance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/util/model_output.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/util/quiet_hours.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/util/session_safety.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/util/temporal.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/backfill.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/caption.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/collections.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/embedder.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/image_preprocess.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/image_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/indexes.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/migrate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/multimodal_provider.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/multimodal_types.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/openai_provider.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/query.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/reranker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/safety_image.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/scanner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/setup.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/vector/tiers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/work_orders.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/workers/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/workers/agent_bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/workers/colony_worker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/workers/queue_worker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/workers/skills_sync.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/causal_maintenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/causal_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/causal_query.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/confidence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/constants.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/entities.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/expectation_resolvers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/base.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/conversation_extractor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/detector.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/document_extractor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/formats/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/formats/csv_fmt.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/formats/html_fmt.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/formats/json_fmt.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/formats/pdf.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/formats/text.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/llm_extractor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/extraction/pipeline.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/integrations/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/integrations/mind_model_bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/integrations/social_intel_bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/jobs/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/jobs/extraction_job.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/llm_extract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/neo4j/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/neo4j/backend.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/observations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/populator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/postgres/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/postgres/backend.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/relationships.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/resolution/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/resolution/entity_resolver.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/resolution/merge_audit.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/resolution/merge_workflow.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/source_reports.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/sqlite/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/sqlite/backend.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/sqlite/schema.sql +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo/world_model/store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo.egg-info/dependency_links.txt +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo.egg-info/entry_points.txt +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/apsimo.egg-info/top_level.txt +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/colony_sidecar/__init__.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/setup.cfg +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_accepted_local_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_adaptive_params.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_affect.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_action_routing.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_api.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_bridge.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_bridge_service.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_sdk.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_sensor_loop.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_snapshot.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_agent_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_annotated_recall_reinforcement.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_answer_source_lineage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_appraisal_incident_decisions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_approval_gate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_approval_relay_canary.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_apsimo_compat.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_apsimo_harness_guidance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_assignment_engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_audit_cleanup.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_auth_coverage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_auth_migration_readiness.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_authz_scope_api.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_autonomy_preset.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_backup.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_backup_receipt_evidence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_beliefs.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_bind_auth_guard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_boundary_fail_closed.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_bounded_approval_authority.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_briefing_aggregators.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_canonical_scoped_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_canonical_source_read.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_causal_extract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_causal_falsifiability.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_causal_maintenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_causal_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_causal_query.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_causal_query_only_guard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_chain_keys.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_channel_preferences.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_channel_registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_channel_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_evidence_pipeline.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_evidence_server_wiring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_goal_spine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_observability.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_p4_controlled_learning.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_p4_server_integration.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_p6_p7_server_wiring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_p7_drive_governance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_phase_b_runtime.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_phase_c_scheduler.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_cognition_server_wiring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_colony_memory_provider.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_commitment_resolution.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_commitment_resolution_downgrade.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_commitment_resolution_schema.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_commitment_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_commitments.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_competence_reconciliation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_compression.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_concern_resolution_receipts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_condition_producer.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_connectors.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_contact_fact_recall.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_contact_policy_projection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_contact_provisioning.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_contact_timezone.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_contacts_intro.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_contacts_persistence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_context_gate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_context_phase1.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_context_provenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_conversation_presence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_conversation_turn_concerns.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_current_work_recall_selection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_delivery_bridge_503.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_delivery_gateway_identity.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_delivery_reachout_routing.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_directed.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_directed_envelope.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_directed_reports.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_directed_trust.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_directive_sources.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_directives.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_distill.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_doctor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_document_memory_guard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_duckduckgo_provider.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_embedding_generations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_ensure_channel_id.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_env_risk.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_event_broadcasts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_event_bus_types.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_event_concerns.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_event_stream_reliability.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_execution_forecasts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_execution_input_purpose.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_execution_registry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_expectations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_expectations_v2.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_experiments.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_external_cognition_events.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_external_event_concerns.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_facts_backfill.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_feedback.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_followup_plans.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_forecast_learning.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_function_routing.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_gap_generators.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_genesis_manifest.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_global_pause.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_goal_dispatch_availability.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_goal_inference_provenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_goal_reader_imports.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_governed_actions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_governed_research_handoff.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_graduated_approvals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_grant_envelope.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_graph_reindex_metadata.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_guard_audit.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_guard_chat_mode.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_guard_derive_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_guard_enforce_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_export.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_general_governance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_history_import.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_native_tool_authority.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_plugin_contract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_plugin_event_lifecycle.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_plugin_event_replay.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_plugin_guard_shadow.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_plugin_signals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_plugin_turn_id.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_queue_stats_projection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_setup.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hermes_work_projection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_host_input_provenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_hostworker_agreement.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_identity_continuity.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_identity_corrections.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_inference_context_gate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_initiative_engine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_initiative_evidence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_initiative_executor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_initiative_feedback.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_initiative_pipeline_v016.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_initiative_retry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_initiative_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_input_source_lineage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_insight_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_instance_service.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_instance_service_live.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_intelligence_components.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_intelligence_synthesis.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_introduction_initiatives.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_job_writeback.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_journal.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_legacy_fact_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_local_work_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_loop_stats_accuracy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_mcp_config.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_mcp_server.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_media_read_reference_presentation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_memory_decay.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_memory_formation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_memory_governance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_memory_promotion.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_memory_prune.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_memory_read_hydration.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_memory_response_schemas.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_migrations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_mining.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_model_qualification_cli.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_model_qualification_memory.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_model_qualification_runner.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_model_qualification_structured.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_accepted_local_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_initiative_work.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_input_carrier.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_outcome_judgments.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_request_erasure.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_review_recurrence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_source_image_read.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_source_read.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_native_source_video_read.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_neo4j_backend.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_operator_deck_read_truth.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_ordinary_context_briefings.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_owner_preferences.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_p2_wirings.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_partial_work_rendering.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_patterns.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_pending_work_coverage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_persona.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_persona_setup_result.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_phase_capability_check.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_preset_loop_coupling.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_procedure_source_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_project_event_outbox.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_project_result_reconciliation_phase.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_projects.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_prompt_evals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_proposals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_provenance_population.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_pseudo_agi_production_chain.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_queue_completed_filter.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_queue_contract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_quiet_hours_and_reload.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_reachout_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_recall_hybrid.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_recall_person_boost.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_recall_ranking.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_recall_rerank.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_recall_source_presentation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_recall_unified_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_recency.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_reflection_task_routing.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_rejection_loop.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_relationship_calendar_aggregators.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_relationship_score_refresh.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_relationship_signal_floor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_relationships.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_reply_forecast_callback_order.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_reply_forecast_stops.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_reply_forecasts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_repo_tools.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_reported_worker_status.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_request_capabilities.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_request_work_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_reranker_remote.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_research_orchestrator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_resolve_messaging_handle.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_response_guard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_response_guard_communication_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_response_guard_endpoint.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_response_guard_surface_policy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_router_tiers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_runtime_model_observations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_sandbox.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_secondary_review_contract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_seed_retirement.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_selected_autonomy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_self_directed_thinker.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_self_initiatives.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_self_judgment_opt_in.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_self_judgment_premises.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_self_judgments.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_self_model.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_self_perspective.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_selfhood_benchmark.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_session_reports.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_shared_facts.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_shared_local_undertaking.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_short_source_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_sidecar.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_signals_attribution.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_situation_spine.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_skill_approval.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_skill_attribution.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_skill_sandbox.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_skill_synthesis.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_skill_synthesis_wiring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_skills_memory.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_social_context_flow.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_social_transport.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_annotation_claim_survivors.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_annotations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_appraisals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_attribution.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_audio.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_audio_claims.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_claim_budget.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_claim_diagnostics.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_claim_media_eligibility.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_claim_projection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_claim_review.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_claim_subject_basis.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_document_read.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_documents.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_episode_admission.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_episode_memory.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_episode_revisions.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_event_precision.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_excerpt_lineage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_image_read.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_media.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_memory_backup.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_time_query.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_source_video.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_sqlite_connection_ownership.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_supervised_rung.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_surprise.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_sweep_fixes.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_synthesis.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_telemetry_staleness.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_temporal.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_temporal_followups.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_temporal_index.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_test_environment_isolation.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_thinking_phase.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_thought_function_routing.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tick_phase_budget.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tier_endpoints.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_timeline.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_approvals.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_asymmetry.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_context.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_cross_gate.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_eligibility.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_epistemic_guard.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_exposure.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_kill_switch.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_level_coherence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_leveled.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_levels.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_source_corrections.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_taint.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom2_wiring.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_event_lineage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_extractor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_arcs.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_boundary_corpus.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_fact_adapters.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_outbound_integration.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_recipient_audit.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_recipient_simulator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_visibility.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_p8_visibility_store.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tom_source_lineage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tool_handlers_graph.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tool_provenance.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_tool_surface.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_toolsmith.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_transport_ingress.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_transport_ingress_api.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_trust_configure.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_trust_scopes.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_trust_scopes_p2.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_turn_idempotency_ledger.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_turn_idempotency_v2.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_turn_ner_entities.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_turn_source_erasure.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_turn_source_evidence.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_turn_survivor_delivery.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_validation_sweep_fixes.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_vector_vacuum.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_wizard_autonomy.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_work_ancestry_projection.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_work_control_production_blockers.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_work_control_v1.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_work_orders.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_work_read_surface_authority.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_work_source_coverage.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_worker_handler_boundaries.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_worker_heartbeat_truth.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_worker_http_authority.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_worker_integration.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_worker_lifecycle_durability.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_workers_governor.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_workers_install.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_workspace.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_context_query.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_entity_reinforcement.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_llm_extract.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_model_prune.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_observations.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_populator.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_quality.py +0 -0
- {apsimo-1.3.0 → apsimo-1.3.2}/tests/test_world_supervised.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apsimo
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Persistent identity, memory and autonomy for AI agents
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -28,7 +28,7 @@ Requires-Dist: pandas>=2.0; extra == "vectors"
|
|
|
28
28
|
Requires-Dist: pyarrow>=15.0; extra == "vectors"
|
|
29
29
|
Requires-Dist: lancedb>=0.10; extra == "vectors"
|
|
30
30
|
Provides-Extra: hermes
|
|
31
|
-
Requires-Dist: apsimo-hermes<2,>=1.3.
|
|
31
|
+
Requires-Dist: apsimo-hermes<2,>=1.3.2; extra == "hermes"
|
|
32
32
|
Provides-Extra: mcp
|
|
33
33
|
Requires-Dist: mcp[cli]<2,>=1.0; extra == "mcp"
|
|
34
34
|
Provides-Extra: lancedb
|
|
@@ -961,6 +961,7 @@ def compatible_scopes(method: str, path: str) -> frozenset[str]:
|
|
|
961
961
|
if (method.upper(), path) in WORK_READ_SURFACE_V1 or (method.upper(), path) in {
|
|
962
962
|
("POST", "/v1/host/learning/correction"),
|
|
963
963
|
("POST", "/v1/host/response-guard/check"),
|
|
964
|
+
("GET", "/v1/host/contacts/resolve"),
|
|
964
965
|
}:
|
|
965
966
|
return _API_ACCESS_COMPATIBILITY
|
|
966
967
|
return _NO_COMPATIBILITY_SCOPES
|
|
@@ -1105,6 +1106,7 @@ def required_scope(method: str, path: str) -> str:
|
|
|
1105
1106
|
return "charter:approval-decide"
|
|
1106
1107
|
return "api:access"
|
|
1107
1108
|
exact = {
|
|
1109
|
+
("GET", "/v1/host/contacts/resolve"): "turns:resolve-sender",
|
|
1108
1110
|
("GET", "/v1/host/admin/auth/status"): "auth:admin",
|
|
1109
1111
|
("GET", "/v1/host/contact-policy"): "contacts:policy-read",
|
|
1110
1112
|
("POST", "/v1/host/response-guard/check"): "response-guard:check",
|
|
@@ -3109,10 +3109,14 @@ async def context_assemble(
|
|
|
3109
3109
|
_per = _comms_log.last_per_channel(contact_id)
|
|
3110
3110
|
if _per:
|
|
3111
3111
|
_chs = ", ".join(f"{ch} {str(v['ts'])[:10]}" for ch, v in _per.items())
|
|
3112
|
-
_bits.append(f"
|
|
3112
|
+
_bits.append(f"Recorded channels: {_chs}.")
|
|
3113
3113
|
_lo = _comms_log.last_outbound(contact_id)
|
|
3114
3114
|
if _lo:
|
|
3115
|
-
_bits.append(
|
|
3115
|
+
_bits.append(
|
|
3116
|
+
f"Last recorded outgoing message: {_lo['channel']} on {str(_lo['ts'])[:10]}. "
|
|
3117
|
+
"This summary includes conversation replies; it does not establish "
|
|
3118
|
+
"proactive outreach or delivery."
|
|
3119
|
+
)
|
|
3116
3120
|
if _commitment_store is not None:
|
|
3117
3121
|
try:
|
|
3118
3122
|
_cm = _commitment_store.list(person_id=contact_id, status=["pending", "overdue"], limit=5)
|
|
@@ -3907,6 +3911,26 @@ async def forget_turn_sources(body: SourceForgetRequest, request: Request = None
|
|
|
3907
3911
|
"host_reconciliation": "pending_until_each_host_connects"}
|
|
3908
3912
|
|
|
3909
3913
|
|
|
3914
|
+
async def _resolve_scoped_sender_contact(authority, gateway: str, address: str):
|
|
3915
|
+
"""Read one verified handle within the credential's existing grants."""
|
|
3916
|
+
platform = gateway.strip().lower()
|
|
3917
|
+
if (not authority.authenticated or not authority.has_scope('turns:resolve-sender')
|
|
3918
|
+
or platform not in authority.turn_ingress_platforms):
|
|
3919
|
+
raise HTTPException(status_code=403, detail='Sender resolution is outside this transport grant')
|
|
3920
|
+
if _contacts_store is None:
|
|
3921
|
+
raise HTTPException(status_code=503, detail='Contact store not initialized')
|
|
3922
|
+
from apsimo.contacts.identity_links import normalized_handle
|
|
3923
|
+
try:
|
|
3924
|
+
normalized_gateway, normalized_address = normalized_handle(platform, address)
|
|
3925
|
+
contact = await _contacts_store.resolve_verified_handles(
|
|
3926
|
+
normalized_gateway, [normalized_address])
|
|
3927
|
+
except ValueError:
|
|
3928
|
+
raise HTTPException(status_code=400, detail='Invalid sender handle') from None
|
|
3929
|
+
if contact is None or contact.contact_id not in authority.person_ids:
|
|
3930
|
+
raise HTTPException(status_code=404, detail='No enrolled contact for that handle')
|
|
3931
|
+
return contact
|
|
3932
|
+
|
|
3933
|
+
|
|
3910
3934
|
async def _ingest_turn_idempotently(
|
|
3911
3935
|
body: TurnSyncRequest,
|
|
3912
3936
|
request: Request | None = None,
|
|
@@ -3918,9 +3942,23 @@ async def _ingest_turn_idempotently(
|
|
|
3918
3942
|
effects run. This is the server's final defense even when a host retries or
|
|
3919
3943
|
two host integrations accidentally submit the same envelope.
|
|
3920
3944
|
"""
|
|
3945
|
+
resolved_sender_contact_id = None
|
|
3946
|
+
authority = request_authority(request)
|
|
3947
|
+
if (body.sender is not None and not authority.legacy and authority.authenticated
|
|
3948
|
+
and authority.has_scope('turns:resolve-sender')
|
|
3949
|
+
and not (authority.allow_unscoped_api and authority.has_scope('api:access'))
|
|
3950
|
+
and body.sender.platform.strip().lower() not in authority.attested_contact_platforms):
|
|
3951
|
+
# Static transport enrollment cannot inherit the viewer on a failed
|
|
3952
|
+
# lookup, or take the general resolver's canonical-ID/name fallbacks.
|
|
3953
|
+
# Validate before checkpoints, reservations or any source write.
|
|
3954
|
+
contact = await _resolve_scoped_sender_contact(
|
|
3955
|
+
authority, body.sender.platform, body.sender.user_id)
|
|
3956
|
+
resolved_sender_contact_id = contact.contact_id
|
|
3957
|
+
body.context.contact_id = contact.contact_id
|
|
3921
3958
|
turn_id = (body.context.turn_id or "").strip()
|
|
3922
3959
|
if not turn_id:
|
|
3923
|
-
return await _process_turn_sync(body, request=request
|
|
3960
|
+
return await _process_turn_sync(body, request=request,
|
|
3961
|
+
resolved_sender_contact_id=resolved_sender_contact_id), "unkeyed"
|
|
3924
3962
|
if len(turn_id) > 256:
|
|
3925
3963
|
raise HTTPException(
|
|
3926
3964
|
status_code=422,
|
|
@@ -4010,7 +4048,8 @@ async def _ingest_turn_idempotently(
|
|
|
4010
4048
|
), "in_progress"
|
|
4011
4049
|
|
|
4012
4050
|
try:
|
|
4013
|
-
result = await _process_turn_sync(body, request=request
|
|
4051
|
+
result = await _process_turn_sync(body, request=request,
|
|
4052
|
+
resolved_sender_contact_id=resolved_sender_contact_id)
|
|
4014
4053
|
except BaseException as exc:
|
|
4015
4054
|
ledger.mark_ambiguous(turn_id, digest, exc)
|
|
4016
4055
|
raise
|
|
@@ -4177,6 +4216,8 @@ async def turns_sync_v2(
|
|
|
4177
4216
|
async def _process_turn_sync(
|
|
4178
4217
|
body: TurnSyncRequest,
|
|
4179
4218
|
request: Request | None = None,
|
|
4219
|
+
*,
|
|
4220
|
+
resolved_sender_contact_id: str | None = None,
|
|
4180
4221
|
) -> TurnSyncResponse:
|
|
4181
4222
|
# Keep direct blocks for canonical source storage. All existing text-only
|
|
4182
4223
|
# cognition consumers receive only explicit text, never repr(base64/URLs).
|
|
@@ -4221,7 +4262,11 @@ async def _process_turn_sync(
|
|
|
4221
4262
|
from apsimo.identity.participants import (
|
|
4222
4263
|
SYSTEM_CONTACT_ID, ParticipantResolver, is_machine_turn,
|
|
4223
4264
|
)
|
|
4224
|
-
if
|
|
4265
|
+
if resolved_sender_contact_id is not None:
|
|
4266
|
+
body.context.contact_id = resolved_sender_contact_id
|
|
4267
|
+
_resolution_method = "verified_handle"
|
|
4268
|
+
_resolved_human_sender = True
|
|
4269
|
+
elif body.sender is not None and _contacts_store is not None:
|
|
4225
4270
|
_res = await ParticipantResolver(_contacts_store).resolve(
|
|
4226
4271
|
platform=body.sender.platform,
|
|
4227
4272
|
user_id=body.sender.user_id,
|
|
@@ -6282,7 +6327,7 @@ async def capture_introduction(body: ContactIntroRequest) -> ContactIntroRespons
|
|
|
6282
6327
|
|
|
6283
6328
|
|
|
6284
6329
|
@router.get("/contacts/resolve", response_model=ContactResponse)
|
|
6285
|
-
async def resolve_contact_by_handle(gateway: str, address: str, create: bool = False) -> ContactResponse:
|
|
6330
|
+
async def resolve_contact_by_handle(gateway: str, address: str, request: Request, create: bool = False) -> ContactResponse:
|
|
6286
6331
|
"""Resolve a contact from a messaging handle (v0.21.2).
|
|
6287
6332
|
|
|
6288
6333
|
Registered BEFORE /contacts/{contact_id} so it isn't shadowed by the
|
|
@@ -6298,6 +6343,14 @@ async def resolve_contact_by_handle(gateway: str, address: str, create: bool = F
|
|
|
6298
6343
|
if _contacts_store is None:
|
|
6299
6344
|
raise HTTPException(status_code=404, detail="Contact store not initialized")
|
|
6300
6345
|
try:
|
|
6346
|
+
authority = request_authority(request)
|
|
6347
|
+
if not authority.legacy and not (
|
|
6348
|
+
authority.allow_unscoped_api and authority.has_scope('api:access')):
|
|
6349
|
+
# Fresh native profiles resolve only explicitly enrolled accounts.
|
|
6350
|
+
# The memory provider's legacy create=true hint cannot provision a
|
|
6351
|
+
# contact or expand the credential's person/transport grants here.
|
|
6352
|
+
contact = await _resolve_scoped_sender_contact(authority, gateway, address)
|
|
6353
|
+
return ContactResponse(**contact.to_dict())
|
|
6301
6354
|
# Normalized, cross-gateway phone-identity resolution (a number is one contact regardless of
|
|
6302
6355
|
# the transport it arrived on). find_by_handle stays exact-match for dedup callers.
|
|
6303
6356
|
contact = await _contacts_store.resolve_messaging_handle(gateway, address)
|
|
@@ -53,6 +53,7 @@ def main() -> None:
|
|
|
53
53
|
# Backward compatibility
|
|
54
54
|
init_p.add_argument("--host-framework", choices=["openclaw", "hermes", "claude-code", "codex", "crush", "standalone"], help="Host framework (deprecated: use --agent-harness or --mcp-harnesses)")
|
|
55
55
|
init_p.add_argument("--contact-name", help="Contact name for this user")
|
|
56
|
+
init_p.add_argument("--owner-handle", action="append", metavar="CHANNEL=SENDER_ID", help="Enroll your exact Hermes sender ID when creating a private instance; repeat for each account")
|
|
56
57
|
init_p.add_argument("--bind", default="127.0.0.1", help="Sidecar bind address (0.0.0.0 for all interfaces)")
|
|
57
58
|
init_p.add_argument("--port", type=int, default=7777, help="Sidecar port")
|
|
58
59
|
init_p.add_argument("--tier", type=int, choices=range(0, 8), metavar="TIER", help="Embedding tier (0-7)")
|
|
@@ -70,6 +70,21 @@ class RecallSelector:
|
|
|
70
70
|
seen.add(key)
|
|
71
71
|
unique.append(row)
|
|
72
72
|
quotations = unique
|
|
73
|
+
def repeats_request(row):
|
|
74
|
+
# An exact repeat contributes no independent answer evidence. Keep
|
|
75
|
+
# it available as supplementary context, without classifying other
|
|
76
|
+
# questions, promoting speakers or changing its source bytes.
|
|
77
|
+
return bool(isinstance(query, str) and query.strip()
|
|
78
|
+
and row.get("kind") == "source_quote"
|
|
79
|
+
and row.get("epistemic_state") == "quotation"
|
|
80
|
+
and row.get("scope") == "person" and row.get("contact_id")
|
|
81
|
+
and row.get("role") in {"user", "assistant"}
|
|
82
|
+
and isinstance(row.get("content"), str)
|
|
83
|
+
and row["content"].strip() == query.strip()
|
|
84
|
+
and not any(row.get(key) for key in (
|
|
85
|
+
"atomic_evidence", "validity_status", "procedure_context",
|
|
86
|
+
"source_context", "_annotation_ids")))
|
|
87
|
+
|
|
73
88
|
# Media is an independent candidate producer. Appending its first hit
|
|
74
89
|
# after every text hit can exclude it from the bounded reranker before
|
|
75
90
|
# relevance is assessed. Fuse its rank independently; it still shares
|
|
@@ -82,10 +97,17 @@ class RecallSelector:
|
|
|
82
97
|
candidates = fuse_candidates(
|
|
83
98
|
beliefs, text, limit=len(beliefs) + len(quotations),
|
|
84
99
|
confidence_weighting=False, additional=(media,))
|
|
100
|
+
# Do this before bounded reranking, so repeated requests do not crowd
|
|
101
|
+
# out answer-bearing candidates before their relevance can be judged.
|
|
102
|
+
candidates.sort(key=repeats_request)
|
|
85
103
|
ranked = await self.rerank(
|
|
86
104
|
query, candidates, limit, confidence_weighting=False,
|
|
87
105
|
candidate_limit=max(1, 4 * limit))
|
|
88
106
|
ranked.sort(key=lambda row: row.get("relevance", 0), reverse=True)
|
|
107
|
+
# A semantic reranker can score the identical question highest. Preserve
|
|
108
|
+
# its abstention decisions and substantive order, then place only exact
|
|
109
|
+
# unqualified request repeats after the remaining evidence.
|
|
110
|
+
ranked.sort(key=repeats_request)
|
|
89
111
|
return pack_memory_context(ranked, limit=limit, max_chars=max_chars)
|
|
90
112
|
|
|
91
113
|
async def rerank(
|
|
@@ -1947,11 +1947,11 @@ def run_init(root_dir: str | None = None, args=None) -> int:
|
|
|
1947
1947
|
root_dir: Root directory for config files
|
|
1948
1948
|
args: Parsed argparse Namespace for non-interactive mode
|
|
1949
1949
|
"""
|
|
1950
|
-
if (getattr(args, 'preferences_only', False) or getattr(args, 'preview', False)
|
|
1950
|
+
if (getattr(args, 'owner_handle', None) or getattr(args, 'preferences_only', False) or getattr(args, 'preview', False)
|
|
1951
1951
|
or getattr(args, 'whatsapp_read_receipts', None) is not None):
|
|
1952
1952
|
if (getattr(args, 'no_harness', False) or getattr(args, 'mcp_harnesses', None)
|
|
1953
1953
|
or getattr(args, 'host_framework', None) not in (None, 'hermes')):
|
|
1954
|
-
print('Hermes profile
|
|
1954
|
+
print('Hermes profile options cannot be combined with another harness setup.')
|
|
1955
1955
|
return 1
|
|
1956
1956
|
from apsimo.setup_hermes import run
|
|
1957
1957
|
return run(root_dir, args)
|
|
@@ -58,6 +58,33 @@ def _json(value):
|
|
|
58
58
|
return json.dumps(value, indent=2, ensure_ascii=False) + '\n'
|
|
59
59
|
|
|
60
60
|
|
|
61
|
+
def _owner_handles(args, ask, noninteractive):
|
|
62
|
+
"""Local enrollment binds exact accounts; it does not configure channels."""
|
|
63
|
+
from .contacts.identity_links import normalized_handle
|
|
64
|
+
supplied = getattr(args, 'owner_handle', None)
|
|
65
|
+
values = list(supplied or [])
|
|
66
|
+
if not supplied and not noninteractive:
|
|
67
|
+
print('Optionally identify your own messaging accounts using Hermes sender IDs, not display names or group IDs.')
|
|
68
|
+
print('For example: telegram=123456789. Hermes continues to configure and authenticate each channel.')
|
|
69
|
+
while value := ask('Your account CHANNEL=SENDER_ID (blank to finish)'):
|
|
70
|
+
values.append(value)
|
|
71
|
+
handles, platforms = [], set()
|
|
72
|
+
for value in values:
|
|
73
|
+
platform, separator, address = value.partition('=')
|
|
74
|
+
platform, address = platform.strip().lower(), address.strip()
|
|
75
|
+
if (not separator or not re.fullmatch(r'[a-z0-9][a-z0-9_.-]{0,63}', platform)
|
|
76
|
+
or platform in {'cli', 'internal', 'system', 'background_review', 'colony_task'}
|
|
77
|
+
or any(ord(char) < 32 or ord(char) == 127 for char in address)):
|
|
78
|
+
raise ValueError('--owner-handle requires CHANNEL=SENDER_ID for your authenticated messaging account')
|
|
79
|
+
gateway, address = normalized_handle(platform, address)
|
|
80
|
+
if not address or address == '+':
|
|
81
|
+
raise ValueError('--owner-handle requires a nonempty sender ID')
|
|
82
|
+
if (gateway, address) not in handles:
|
|
83
|
+
handles.append((gateway, address))
|
|
84
|
+
platforms.add(platform)
|
|
85
|
+
return handles, sorted(platforms)
|
|
86
|
+
|
|
87
|
+
|
|
61
88
|
def _receipt_preference(config, choice):
|
|
62
89
|
"""Project one native shared key, respecting Hermes' existing YAML layouts.
|
|
63
90
|
|
|
@@ -563,7 +590,7 @@ def run(root_dir=None, args=None):
|
|
|
563
590
|
if root_dir or any(getattr(args, name, None) for name in (
|
|
564
591
|
'start', 'refresh_adapter', 'replace_memory_provider', 'local_work',
|
|
565
592
|
'native_goals', 'native_reviews', 'model_url', 'model', 'adapter_wheel', 'agent_name',
|
|
566
|
-
'agent_values', 'timezone', 'quiet_hours', 'contact_name', 'encrypt',
|
|
593
|
+
'agent_values', 'timezone', 'quiet_hours', 'contact_name', 'owner_handle', 'encrypt',
|
|
567
594
|
'passphrase', 'claim_genesis', 'mcp_harnesses', 'no_harness')) or (
|
|
568
595
|
getattr(args, 'host_framework', None) not in (None, 'hermes')):
|
|
569
596
|
raise ValueError('--preferences-only cannot be combined with instance or setup options')
|
|
@@ -593,6 +620,8 @@ def run(root_dir=None, args=None):
|
|
|
593
620
|
if any((home/name).exists() for name in ('colony-memory.json', 'apsimo-memory.json')):
|
|
594
621
|
raise ValueError('Existing native Apsimo settings need an explicit migration; select a new home')
|
|
595
622
|
if (state/'instance.json').exists():
|
|
623
|
+
if getattr(args, 'owner_handle', None):
|
|
624
|
+
raise ValueError('--owner-handle is for a new private instance; existing owner bindings are retained')
|
|
596
625
|
manifest = json.loads((state/'instance.json').read_text())
|
|
597
626
|
if manifest.get('hermes_home') != str(home):
|
|
598
627
|
raise ValueError('This instance belongs to another Hermes home')
|
|
@@ -652,6 +681,7 @@ def run(root_dir=None, args=None):
|
|
|
652
681
|
_preflight_outbox(home, resources)
|
|
653
682
|
binding = _adapter_binding(python, resources)
|
|
654
683
|
owner_name = ask('Your name', getattr(args, 'contact_name', None) or os.environ.get('USER', 'Owner'), True)
|
|
684
|
+
owner_handles, owner_platforms = _owner_handles(args, ask, noninteractive)
|
|
655
685
|
agent_name = ask('Agent name', getattr(args, 'agent_name', None) or 'Assistant', True)
|
|
656
686
|
agent_preferences = _agent_preferences(ask, args, config)
|
|
657
687
|
endpoint = _endpoint(ask('Local model API root', getattr(args, 'model_url', None), True))
|
|
@@ -726,7 +756,11 @@ def run(root_dir=None, args=None):
|
|
|
726
756
|
store = SQLiteContactStore(ContactsConfig(sqlite_path=str(staged/'contacts.db')))
|
|
727
757
|
await store.connect()
|
|
728
758
|
try:
|
|
729
|
-
|
|
759
|
+
contact_id = await setup.build_owner_contact(store, owner_name)
|
|
760
|
+
for index, (gateway, address) in enumerate(owner_handles):
|
|
761
|
+
await store.add_handle(contact_id, gateway, address,
|
|
762
|
+
is_primary=index == 0, source='wizard', verified=True)
|
|
763
|
+
return contact_id
|
|
730
764
|
finally:
|
|
731
765
|
await store.close()
|
|
732
766
|
owner_id = asyncio.run(owner())
|
|
@@ -750,9 +784,11 @@ def run(root_dir=None, args=None):
|
|
|
750
784
|
values = {('APSIMO_'+key[7:] if key.startswith('COLONY_') else key):value for key,value in values.items()}
|
|
751
785
|
_private_write(staged/'.env', _native_environment(None, values))
|
|
752
786
|
principal = {'principal': 'hermes-local', 'status': 'active', 'viewer_person_id': owner_id,
|
|
753
|
-
'audiences': ['viewer'], 'allow_unscoped_api': False, 'turn_ingress_platforms': ['cli'],
|
|
787
|
+
'audiences': ['viewer'], 'allow_unscoped_api': False, 'turn_ingress_platforms': ['cli', *owner_platforms],
|
|
754
788
|
'scopes': ['context:read', 'memory:read', 'memory:search', 'memory:write', 'turns:write'],
|
|
755
789
|
'credentials': [{'id': 'initial', 'secret': key, 'status': 'active'}]}
|
|
790
|
+
if owner_handles:
|
|
791
|
+
principal['scopes'].append('turns:resolve-sender')
|
|
756
792
|
_private_write(staged/'api-keyring.json', _json({'version': 1, 'principals': [principal]}))
|
|
757
793
|
model_configuration = {'provider': 'local', 'baseUrl': endpoint,
|
|
758
794
|
'apiKey': model_key, 'localHosts': local_hosts,
|
|
@@ -857,6 +893,8 @@ def run(root_dir=None, args=None):
|
|
|
857
893
|
print(f'Private agent configured in {home}; state in {state}.')
|
|
858
894
|
print('Adapter loading: ' + binding['mode'] + ' (canonical artifact bytes verified).')
|
|
859
895
|
print('Canonical memory capture and recollection are enabled for new Hermes sessions.')
|
|
896
|
+
if owner_handles:
|
|
897
|
+
print('Owner accounts enrolled for: ' + ', '.join(owner_platforms) + '. Channel configuration and delivery still belong to Hermes.')
|
|
860
898
|
print('Hermes hook output spill allowance is at least 65536 characters or already disabled; retrieval budgets are unchanged.')
|
|
861
899
|
print('Source memory, temporal claims, contacts, commitments and self state persist without a graph.')
|
|
862
900
|
print('Graph/vector recall and consequential background work are optional and currently disabled.')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: apsimo
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.2
|
|
4
4
|
Summary: Persistent identity, memory and autonomy for AI agents
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Requires-Python: >=3.11
|
|
@@ -28,7 +28,7 @@ Requires-Dist: pandas>=2.0; extra == "vectors"
|
|
|
28
28
|
Requires-Dist: pyarrow>=15.0; extra == "vectors"
|
|
29
29
|
Requires-Dist: lancedb>=0.10; extra == "vectors"
|
|
30
30
|
Provides-Extra: hermes
|
|
31
|
-
Requires-Dist: apsimo-hermes<2,>=1.3.
|
|
31
|
+
Requires-Dist: apsimo-hermes<2,>=1.3.2; extra == "hermes"
|
|
32
32
|
Provides-Extra: mcp
|
|
33
33
|
Requires-Dist: mcp[cli]<2,>=1.0; extra == "mcp"
|
|
34
34
|
Provides-Extra: lancedb
|
|
@@ -707,6 +707,7 @@ tests/test_doctor.py
|
|
|
707
707
|
tests/test_document_memory_guard.py
|
|
708
708
|
tests/test_duckduckgo_provider.py
|
|
709
709
|
tests/test_embedding_generations.py
|
|
710
|
+
tests/test_enrolled_sender_turns.py
|
|
710
711
|
tests/test_ensure_channel_id.py
|
|
711
712
|
tests/test_env_risk.py
|
|
712
713
|
tests/test_event_broadcasts.py
|
|
@@ -832,6 +833,7 @@ tests/test_reachout_policy.py
|
|
|
832
833
|
tests/test_recall_hybrid.py
|
|
833
834
|
tests/test_recall_person_boost.py
|
|
834
835
|
tests/test_recall_ranking.py
|
|
836
|
+
tests/test_recall_request_repetition.py
|
|
835
837
|
tests/test_recall_rerank.py
|
|
836
838
|
tests/test_recall_source_presentation.py
|
|
837
839
|
tests/test_recall_unified_context.py
|
|
@@ -860,6 +862,7 @@ tests/test_router_tiers.py
|
|
|
860
862
|
tests/test_runtime_model_observations.py
|
|
861
863
|
tests/test_sandbox.py
|
|
862
864
|
tests/test_scoped_api_authority.py
|
|
865
|
+
tests/test_scoped_contact_resolution.py
|
|
863
866
|
tests/test_secondary_review_contract.py
|
|
864
867
|
tests/test_seed_retirement.py
|
|
865
868
|
tests/test_selected_autonomy.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "apsimo"
|
|
7
|
-
version = "1.3.
|
|
7
|
+
version = "1.3.2"
|
|
8
8
|
description = "Persistent identity, memory and autonomy for AI agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -29,7 +29,7 @@ dependencies = [
|
|
|
29
29
|
graph = ["neo4j>=5.18"]
|
|
30
30
|
neo4j = ["neo4j>=5.18"]
|
|
31
31
|
vectors = ["sentence-transformers>=3.0", "pandas>=2.0", "pyarrow>=15.0", "lancedb>=0.10"]
|
|
32
|
-
hermes = ["apsimo-hermes>=1.3.
|
|
32
|
+
hermes = ["apsimo-hermes>=1.3.2,<2"]
|
|
33
33
|
mcp = ["mcp[cli]>=1.0,<2"]
|
|
34
34
|
lancedb = ["lancedb>=0.6", "pyarrow>=14.0", "pandas>=2.0"]
|
|
35
35
|
postgres = ["asyncpg>=0.29"]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Fresh transport grants admit only enrolled senders before source storage."""
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
import sqlite3
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from fastapi import FastAPI
|
|
8
|
+
import httpx
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from apsimo import setup
|
|
12
|
+
from apsimo.api.middleware import ApiKeyMiddleware
|
|
13
|
+
from apsimo.api.routers import host
|
|
14
|
+
from apsimo.contacts.config import ContactsConfig
|
|
15
|
+
from apsimo.contacts.store import SQLiteContactStore
|
|
16
|
+
from apsimo.turns import TurnIdempotencyLedger
|
|
17
|
+
from test_native_setup import args, isolated_platform_environment # Shared isolated wizard fixtures.
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@pytest.mark.parametrize('version', ['v1', 'v2'])
|
|
21
|
+
def test_enrolled_sender_checked_before_turn_reservation(args, monkeypatch, version):
|
|
22
|
+
args.owner_handle = ['telegram=123456789']
|
|
23
|
+
assert setup.run_init(None, args) == 0
|
|
24
|
+
state = Path(args.hermes_home)/'apsimo'
|
|
25
|
+
principal = json.loads((state/'api-keyring.json').read_text())['principals'][0]
|
|
26
|
+
owner = principal['viewer_person_id']
|
|
27
|
+
monkeypatch.setenv('COLONY_STATE_DIR', str(state))
|
|
28
|
+
monkeypatch.setenv('COLONY_IDENTITY_SHADOW_CONTACTS', 'false')
|
|
29
|
+
for name in ('_graph', '_presence_store', '_context_provenance', '_telemetry', '_p8_runtime'):
|
|
30
|
+
monkeypatch.setattr(host, name, None)
|
|
31
|
+
ledger = TurnIdempotencyLedger(state/'turn-idempotency.db')
|
|
32
|
+
|
|
33
|
+
async def exercise():
|
|
34
|
+
store = SQLiteContactStore(ContactsConfig(sqlite_path=str(state/'contacts.db')))
|
|
35
|
+
await store.connect()
|
|
36
|
+
monkeypatch.setattr(host, '_contacts_store', store)
|
|
37
|
+
try:
|
|
38
|
+
guest = await store.create(display_name='Other account')
|
|
39
|
+
await store.add_handle(guest.contact_id, 'telegram', '987654321', verified=True)
|
|
40
|
+
await store.add_handle(owner, 'telegram', 'unverified', verified=False)
|
|
41
|
+
before_contacts = await store.list()
|
|
42
|
+
app = FastAPI()
|
|
43
|
+
app.include_router(host.router)
|
|
44
|
+
app.include_router(host.v2_router)
|
|
45
|
+
app.add_middleware(ApiKeyMiddleware, keyring_path=str(state/'api-keyring.json'))
|
|
46
|
+
headers = {'Authorization': 'Bearer ' + principal['credentials'][0]['secret']}
|
|
47
|
+
|
|
48
|
+
async def send(client, turn_id, platform, sender):
|
|
49
|
+
body = {'identity': {'host_id': 'fixture'},
|
|
50
|
+
'context': {'contact_id': owner if sender is None else 'body-selected-person',
|
|
51
|
+
'session_id': 'enrolled-source',
|
|
52
|
+
'channel_id': platform + ':fixture', 'turn_id': turn_id}}
|
|
53
|
+
if sender is not None:
|
|
54
|
+
body['sender'] = {'platform': platform, 'user_id': sender}
|
|
55
|
+
message = {'role': 'user', 'content': 'The archive reference is violet.'}
|
|
56
|
+
body.update(user_message=message, source_only=True)
|
|
57
|
+
if version == 'v1':
|
|
58
|
+
return await client.post('/v1/host/turns/sync', json=body)
|
|
59
|
+
return await client.put('/v2/host/turns/' + turn_id, json=body)
|
|
60
|
+
|
|
61
|
+
async with httpx.AsyncClient(transport=httpx.ASGITransport(app=app),
|
|
62
|
+
base_url='http://fixture', headers=headers) as client:
|
|
63
|
+
denied = [('unknown', 'telegram', 'unknown', 404),
|
|
64
|
+
('canonical-id', 'telegram', owner, 404),
|
|
65
|
+
('other-person', 'telegram', '987654321', 404),
|
|
66
|
+
('unverified', 'telegram', 'unverified', 404),
|
|
67
|
+
('wrong-channel', 'whatsapp', '123456789', 403)]
|
|
68
|
+
for turn_id, platform, sender, code in denied:
|
|
69
|
+
response = await send(client, turn_id, platform, sender)
|
|
70
|
+
assert response.status_code == code, (turn_id, response.text)
|
|
71
|
+
with sqlite3.connect(ledger.db_path) as db:
|
|
72
|
+
assert db.execute('SELECT count(*) FROM turn_sources').fetchone()[0] == 0
|
|
73
|
+
assert db.execute('SELECT count(*) FROM turn_ingestion').fetchone()[0] == 0
|
|
74
|
+
assert await store.list() == before_contacts
|
|
75
|
+
response = await send(client, 'known-owner', 'telegram', '123456789')
|
|
76
|
+
assert response.status_code == (200 if version == 'v1' else 201), response.text
|
|
77
|
+
assert response.json()['source_recorded'] is True
|
|
78
|
+
replay = await send(client, 'known-owner', 'telegram', '123456789')
|
|
79
|
+
assert replay.status_code == 200 and replay.json()['source_recorded'] is True
|
|
80
|
+
with sqlite3.connect(ledger.db_path) as db:
|
|
81
|
+
rows = db.execute('SELECT contact_id,messages_json FROM turn_sources').fetchall()
|
|
82
|
+
assert len(rows) == 1 and rows[0][0] == owner
|
|
83
|
+
assert json.loads(rows[0][1])[0]['content'] == 'The archive reference is violet.'
|
|
84
|
+
# Native CLI has no human sender ID. Its exact viewer binding
|
|
85
|
+
# still permits capture without inventing a transport handle.
|
|
86
|
+
response = await send(client, 'senderless-cli', 'cli', None)
|
|
87
|
+
assert response.status_code == (200 if version == 'v1' else 201), response.text
|
|
88
|
+
assert response.json()['source_recorded'] is True
|
|
89
|
+
with sqlite3.connect(ledger.db_path) as db:
|
|
90
|
+
assert db.execute('SELECT contact_id FROM turn_sources WHERE turn_id=?',
|
|
91
|
+
('senderless-cli',)).fetchone() == (owner,)
|
|
92
|
+
finally:
|
|
93
|
+
await store.close()
|
|
94
|
+
asyncio.run(exercise())
|
|
@@ -1197,7 +1197,8 @@ def test_colony_client_uses_one_absolute_deadline_across_http_phases():
|
|
|
1197
1197
|
assert elapsed < 0.20
|
|
1198
1198
|
|
|
1199
1199
|
|
|
1200
|
-
|
|
1200
|
+
@pytest.mark.parametrize('channel_id', ['', 'email:thread-739'])
|
|
1201
|
+
def test_colony_client_absolute_deadline_transport_accepts_exact_put(channel_id):
|
|
1201
1202
|
module = _load_client("colony_hermes_client_deadline_success_test")
|
|
1202
1203
|
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
1203
1204
|
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
@@ -1242,6 +1243,7 @@ def test_colony_client_absolute_deadline_transport_accepts_exact_put():
|
|
|
1242
1243
|
session_id="session-1",
|
|
1243
1244
|
contact_id="cid-owner",
|
|
1244
1245
|
turn_id="turn/one",
|
|
1246
|
+
channel_id=channel_id,
|
|
1245
1247
|
timeout_seconds=0.20,
|
|
1246
1248
|
) is True
|
|
1247
1249
|
finally:
|
|
@@ -1260,6 +1262,7 @@ def test_colony_client_absolute_deadline_transport_accepts_exact_put():
|
|
|
1260
1262
|
"contact_id": "cid-owner",
|
|
1261
1263
|
"session_id": "session-1",
|
|
1262
1264
|
"turn_id": "turn/one",
|
|
1265
|
+
**({"channel_id": channel_id} if channel_id else {}),
|
|
1263
1266
|
},
|
|
1264
1267
|
"identity": {"host_id": "hermes"},
|
|
1265
1268
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Guided native init preserves profiles and creates one private scoped instance."""
|
|
2
2
|
import json
|
|
3
|
+
import asyncio
|
|
3
4
|
import os
|
|
4
5
|
import socket
|
|
5
6
|
from pathlib import Path
|
|
@@ -152,6 +153,98 @@ def test_new_private_instance_uses_canonical_resources_and_scoped_authority(args
|
|
|
152
153
|
assert before == ((home/'config.yaml').read_bytes(), (state/'api-keyring.json').read_bytes())
|
|
153
154
|
|
|
154
155
|
|
|
156
|
+
def test_enrolled_owner_accounts_resolve_through_the_generated_scoped_api(args, monkeypatch):
|
|
157
|
+
from fastapi import FastAPI
|
|
158
|
+
from apsimo.api.middleware import ApiKeyMiddleware
|
|
159
|
+
from apsimo.api.routers import host
|
|
160
|
+
from apsimo.contacts.config import ContactsConfig
|
|
161
|
+
from apsimo.contacts.store import SQLiteContactStore
|
|
162
|
+
|
|
163
|
+
home = Path(args.hermes_home)
|
|
164
|
+
home.mkdir(mode=0o700)
|
|
165
|
+
channels = {'telegram': {'enabled': True, 'allowed_users': ['123456789']}}
|
|
166
|
+
(home/'config.yaml').write_text(yaml.safe_dump(channels))
|
|
167
|
+
args.owner_handle = ['telegram=123456789', 'sms=+1 (202) 555-0198', 'telegram=123456789']
|
|
168
|
+
assert setup.run_init(None, args) == 0
|
|
169
|
+
state = home/'apsimo'
|
|
170
|
+
config = yaml.safe_load((home/'config.yaml').read_text())
|
|
171
|
+
assert config['telegram'] == channels['telegram']
|
|
172
|
+
assert config['plugins']['apsimo']['attested_system_platforms'] == ['cli']
|
|
173
|
+
principal = json.loads((state/'api-keyring.json').read_text())['principals'][0]
|
|
174
|
+
assert principal['turn_ingress_platforms'] == ['cli', 'sms', 'telegram']
|
|
175
|
+
assert 'turns:resolve-sender' in principal['scopes']
|
|
176
|
+
assert principal['allow_unscoped_api'] is False
|
|
177
|
+
assert 'api:access' not in principal['scopes']
|
|
178
|
+
owner_id = principal['viewer_person_id']
|
|
179
|
+
|
|
180
|
+
async def exercise():
|
|
181
|
+
store = SQLiteContactStore(ContactsConfig(sqlite_path=str(state/'contacts.db')))
|
|
182
|
+
await store.connect()
|
|
183
|
+
monkeypatch.setattr(host, '_contacts_store', store)
|
|
184
|
+
try:
|
|
185
|
+
handles = await store.get_handles(owner_id)
|
|
186
|
+
assert len(handles) == 2 and all(row.verified and row.source == 'wizard' for row in handles)
|
|
187
|
+
guest = await store.create(display_name='Other person')
|
|
188
|
+
await store.add_handle(guest.contact_id, 'telegram', '987654321', verified=True)
|
|
189
|
+
await store.add_handle(owner_id, 'telegram', '111111111', verified=False)
|
|
190
|
+
before = (await store.list(), await store.get_handles(owner_id))
|
|
191
|
+
app = FastAPI()
|
|
192
|
+
app.add_middleware(ApiKeyMiddleware, keyring_path=str(state/'api-keyring.json'))
|
|
193
|
+
app.include_router(host.router)
|
|
194
|
+
headers = {'Authorization': 'Bearer ' + principal['credentials'][0]['secret']}
|
|
195
|
+
async with httpx.AsyncClient(transport=httpx.ASGITransport(app=app), base_url='http://setup') as client:
|
|
196
|
+
for gateway, address, create, status in [
|
|
197
|
+
('telegram', '123456789', False, 200),
|
|
198
|
+
('telegram', '123456789', True, 200), # Memory provider's existing read call.
|
|
199
|
+
('sms', '+1 (202) 555-0198', True, 200),
|
|
200
|
+
('telegram', 'unknown', True, 404),
|
|
201
|
+
('telegram', '987654321', False, 404),
|
|
202
|
+
('telegram', '111111111', False, 404),
|
|
203
|
+
('telegram', '+12025550198', False, 404), # No inferred cross-channel authority.
|
|
204
|
+
('whatsapp', '123456789', False, 403),
|
|
205
|
+
]:
|
|
206
|
+
response = await client.get('/v1/host/contacts/resolve', headers=headers,
|
|
207
|
+
params={'gateway': gateway, 'address': address, 'create': str(create).lower()})
|
|
208
|
+
assert response.status_code == status, response.text
|
|
209
|
+
if status == 200:
|
|
210
|
+
assert response.json()['contact_id'] == owner_id
|
|
211
|
+
denied = await client.get('/v1/host/contacts/resolve',
|
|
212
|
+
params={'gateway': 'telegram', 'address': '123456789'})
|
|
213
|
+
assert denied.status_code == 401
|
|
214
|
+
assert before == (await store.list(), await store.get_handles(owner_id))
|
|
215
|
+
finally:
|
|
216
|
+
await store.close()
|
|
217
|
+
asyncio.run(exercise())
|
|
218
|
+
|
|
219
|
+
retained = ((state/'api-keyring.json').read_bytes(), (home/'config.yaml').read_bytes(),
|
|
220
|
+
(state/'contacts.db').read_bytes())
|
|
221
|
+
assert setup.run_init(None, args) == 1 # Enrollment arguments are never silently ignored on rerun.
|
|
222
|
+
assert retained == ((state/'api-keyring.json').read_bytes(), (home/'config.yaml').read_bytes(),
|
|
223
|
+
(state/'contacts.db').read_bytes())
|
|
224
|
+
args.owner_handle = None
|
|
225
|
+
assert setup.run_init(None, args) == 0
|
|
226
|
+
assert retained == ((state/'api-keyring.json').read_bytes(), (home/'config.yaml').read_bytes(),
|
|
227
|
+
(state/'contacts.db').read_bytes())
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@pytest.mark.parametrize('handle', ['telegram', '=123', 'telegram=', 'sms=letters',
|
|
231
|
+
'cli=owner', 'telegram=abc\n123', 'telegram=' + 'x' * 513])
|
|
232
|
+
def test_bad_owner_enrollment_stops_before_probe_or_state(args, handle, monkeypatch):
|
|
233
|
+
args.owner_handle = [handle]
|
|
234
|
+
probe = Mock(side_effect=AssertionError('Invalid enrollment must precede model probing'))
|
|
235
|
+
monkeypatch.setattr(setup_hermes, '_verify_local_endpoint', probe)
|
|
236
|
+
assert setup.run_init(None, args) == 1
|
|
237
|
+
probe.assert_not_called()
|
|
238
|
+
assert not Path(args.hermes_home).exists()
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def test_guided_owner_enrollment_uses_the_same_normalized_bindings():
|
|
242
|
+
answers = iter(['email=Owner@Example.org', 'rcs=+1 (202) 555-0198', ''])
|
|
243
|
+
handles, platforms = setup_hermes._owner_handles(SimpleNamespace(), lambda *a: next(answers), False)
|
|
244
|
+
assert handles == [('email', 'owner@example.org'), ('sms', '+12025550198')]
|
|
245
|
+
assert platforms == ['email', 'rcs']
|
|
246
|
+
|
|
247
|
+
|
|
155
248
|
def test_writable_ancestor_stops_before_endpoint_probe_or_attachment(args, tmp_path, monkeypatch, capsys):
|
|
156
249
|
shared = tmp_path/'shared-parent'
|
|
157
250
|
shared.mkdir(mode=0o775)
|