apsimo 1.3.0__tar.gz → 1.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (999) hide show
  1. {apsimo-1.3.0 → apsimo-1.3.1}/PKG-INFO +2 -2
  2. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/authority.py +2 -0
  3. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/host.py +53 -4
  4. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cli.py +1 -0
  5. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/setup.py +2 -2
  6. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/setup_hermes.py +41 -3
  7. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo.egg-info/PKG-INFO +2 -2
  8. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo.egg-info/SOURCES.txt +2 -0
  9. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo.egg-info/requires.txt +1 -1
  10. {apsimo-1.3.0 → apsimo-1.3.1}/pyproject.toml +2 -2
  11. apsimo-1.3.1/tests/test_enrolled_sender_turns.py +94 -0
  12. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_setup.py +93 -0
  13. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_scoped_api_authority.py +11 -9
  14. apsimo-1.3.1/tests/test_scoped_contact_resolution.py +48 -0
  15. {apsimo-1.3.0 → apsimo-1.3.1}/LICENSE +0 -0
  16. {apsimo-1.3.0 → apsimo-1.3.1}/README.md +0 -0
  17. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/__init__.py +0 -0
  18. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/__main__.py +0 -0
  19. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/agent/__init__.py +0 -0
  20. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/agent/client.py +0 -0
  21. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/agent/models.py +0 -0
  22. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/agents/__init__.py +0 -0
  23. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/agents/models.py +0 -0
  24. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/agents/store.py +0 -0
  25. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/agents/websocket.py +0 -0
  26. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/__init__.py +0 -0
  27. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/auth_telemetry.py +0 -0
  28. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/contact_grants.py +0 -0
  29. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/middleware.py +0 -0
  30. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/__init__.py +0 -0
  31. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/commitment_work.py +0 -0
  32. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/context_gate.py +0 -0
  33. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/executions.py +0 -0
  34. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/followup_plans.py +0 -0
  35. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/governed_actions.py +0 -0
  36. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/initiative_work.py +0 -0
  37. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/mining.py +0 -0
  38. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/observations.py +0 -0
  39. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/social_state.py +0 -0
  40. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/task_queue.py +0 -0
  41. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/temporal_followups.py +0 -0
  42. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/transport.py +0 -0
  43. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/routers/transport_ingress_api.py +0 -0
  44. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/schemas/__init__.py +0 -0
  45. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/api/schemas/host.py +0 -0
  46. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/autonomy/cli.py +0 -0
  47. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/autonomy/condition_worker.py +0 -0
  48. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/autonomy/config.py +0 -0
  49. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/autonomy/loop.py +0 -0
  50. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/autonomy/registry.py +0 -0
  51. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/autonomy/scheduler.py +0 -0
  52. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/autonomy/synthesis.py +0 -0
  53. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/backup.py +0 -0
  54. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/__init__.py +0 -0
  55. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/contradictions.py +0 -0
  56. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/decay.py +0 -0
  57. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/engine.py +0 -0
  58. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/models.py +0 -0
  59. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/promotion.py +0 -0
  60. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/resolve.py +0 -0
  61. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/source_claims.py +0 -0
  62. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/source_projection.py +0 -0
  63. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/source_time.py +0 -0
  64. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/beliefs/store.py +0 -0
  65. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/aggregators.py +0 -0
  66. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/composer.py +0 -0
  67. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/config.py +0 -0
  68. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/delivery.py +0 -0
  69. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/engagement.py +0 -0
  70. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/engine.py +0 -0
  71. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/enhancer.py +0 -0
  72. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/models.py +0 -0
  73. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/scheduler.py +0 -0
  74. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/briefings/store.py +0 -0
  75. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/__init__.py +0 -0
  76. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/block.py +0 -0
  77. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/cli.py +0 -0
  78. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/genesis.py +0 -0
  79. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/identity.py +0 -0
  80. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/keys.py +0 -0
  81. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/local_keys.py +0 -0
  82. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/manager.py +0 -0
  83. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/node.py +0 -0
  84. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/plugin_transactions.py +0 -0
  85. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/protocol.py +0 -0
  86. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/state_machine.py +0 -0
  87. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/storage.py +0 -0
  88. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/transactions.py +0 -0
  89. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/chain/validation.py +0 -0
  90. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/channels/__init__.py +0 -0
  91. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/channels/manifest.py +0 -0
  92. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/channels/migrations/001_channels_schema.sql +0 -0
  93. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/channels/phone_gateways.py +0 -0
  94. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/channels/presence.py +0 -0
  95. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/channels/router.py +0 -0
  96. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/channels/store.py +0 -0
  97. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/__init__.py +0 -0
  98. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/charter.py +0 -0
  99. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/drive_governance.py +0 -0
  100. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/evidence_pipeline.py +0 -0
  101. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/external_events.py +0 -0
  102. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/goal_spine.py +0 -0
  103. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/introspection.py +0 -0
  104. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/prompt.py +0 -0
  105. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/runtime.py +0 -0
  106. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/cognition/trigger.py +0 -0
  107. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/commitments/__init__.py +0 -0
  108. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/commitments/local_work.py +0 -0
  109. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/commitments/store.py +0 -0
  110. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/commitments/work.py +0 -0
  111. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/compat.py +0 -0
  112. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/compression/__init__.py +0 -0
  113. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/connectors/__init__.py +0 -0
  114. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/connectors/base.py +0 -0
  115. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/connectors/caldav_calendar.py +0 -0
  116. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/connectors/fs_documents.py +0 -0
  117. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/connectors/imap_email.py +0 -0
  118. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/connectors/manager.py +0 -0
  119. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/connectors/webhook_pull.py +0 -0
  120. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/__init__.py +0 -0
  121. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/comms.py +0 -0
  122. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/config.py +0 -0
  123. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/exporters/__init__.py +0 -0
  124. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/exporters/vcard.py +0 -0
  125. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/identity_links.py +0 -0
  126. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/importer.py +0 -0
  127. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/importers/__init__.py +0 -0
  128. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/importers/batch.py +0 -0
  129. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/importers/macos_contacts.py +0 -0
  130. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/migrations/001_contacts_schema.sql +0 -0
  131. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/migrations/002_trust_scopes.sql +0 -0
  132. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/migrations/003_open_gateway_enum.sql +0 -0
  133. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/migrations/004_contact_provision_operations.sql +0 -0
  134. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/migrations/005_identity_links.sql +0 -0
  135. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/models.py +0 -0
  136. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/scoring.py +0 -0
  137. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/store.py +0 -0
  138. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/transport_ingress.py +0 -0
  139. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contacts/world_bridge.py +0 -0
  140. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contextgate/__init__.py +0 -0
  141. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contextgate/chunker.py +0 -0
  142. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contextgate/estimate.py +0 -0
  143. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contextgate/gate.py +0 -0
  144. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/contextgate/retrieve.py +0 -0
  145. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/delivery/__init__.py +0 -0
  146. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/delivery/bridge.py +0 -0
  147. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/delivery/channels.py +0 -0
  148. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/delivery/classification.py +0 -0
  149. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/delivery/rate_limiter.py +0 -0
  150. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/delivery/reachout_policy.py +0 -0
  151. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directed/__init__.py +0 -0
  152. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directed/audit.py +0 -0
  153. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directed/intake.py +0 -0
  154. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directed/models.py +0 -0
  155. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directed/service.py +0 -0
  156. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directives/__init__.py +0 -0
  157. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directives/evidence.py +0 -0
  158. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directives/extractor.py +0 -0
  159. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directives/guard.py +0 -0
  160. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directives/models.py +0 -0
  161. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directives/service.py +0 -0
  162. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/directives/store.py +0 -0
  163. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/doctor.py +0 -0
  164. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/environment.py +0 -0
  165. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/events/__init__.py +0 -0
  166. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/events/broadcaster.py +0 -0
  167. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/events/bus.py +0 -0
  168. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/events/journal.py +0 -0
  169. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/events/stream.py +0 -0
  170. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/events/types.py +0 -0
  171. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/execution_results.py +0 -0
  172. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feedback/__init__.py +0 -0
  173. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feedback/store.py +0 -0
  174. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/__init__.py +0 -0
  175. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/cli.py +0 -0
  176. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/engine.py +0 -0
  177. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/example-feed.yaml +0 -0
  178. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/hermes_cron.py +0 -0
  179. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/manager.py +0 -0
  180. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/spec.py +0 -0
  181. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/feeds/template.py +0 -0
  182. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/__init__.py +0 -0
  183. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/audit.py +0 -0
  184. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/communication_policy.py +0 -0
  185. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/config.py +0 -0
  186. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/context_provenance.py +0 -0
  187. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/env_risk.py +0 -0
  188. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/guard_audit.py +0 -0
  189. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/__init__.py +0 -0
  190. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/base.py +0 -0
  191. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/l1_recipient.py +0 -0
  192. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/l2_pii.py +0 -0
  193. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/l3_cross_context.py +0 -0
  194. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/l4_trust_tier.py +0 -0
  195. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/l5_injection.py +0 -0
  196. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/l6_review.py +0 -0
  197. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/l7_delay.py +0 -0
  198. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/layers/tom2_epistemic.py +0 -0
  199. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/models.py +0 -0
  200. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/pending_dispatch.py +0 -0
  201. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/pipeline.py +0 -0
  202. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/rejection.py +0 -0
  203. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/response_guard.py +0 -0
  204. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/rulesets/injection_v1.yaml +0 -0
  205. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/surface_policy.py +0 -0
  206. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/gate/taint.py +0 -0
  207. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/genesis.json +0 -0
  208. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/__init__.py +0 -0
  209. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/config.py +0 -0
  210. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/decomposer.py +0 -0
  211. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/engine.py +0 -0
  212. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/inference.py +0 -0
  213. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/models.py +0 -0
  214. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/priority.py +0 -0
  215. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/queue_bridge.py +0 -0
  216. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/replan.py +0 -0
  217. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/schema.sql +0 -0
  218. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/goals/store.py +0 -0
  219. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/governed_actions.py +0 -0
  220. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/harness_integration/__init__.py +0 -0
  221. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/harness_integration/context.py +0 -0
  222. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/harness_integration/skills.py +0 -0
  223. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity/__init__.py +0 -0
  224. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity/participants.py +0 -0
  225. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity/resolver.py +0 -0
  226. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/__init__.py +0 -0
  227. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/builder.py +0 -0
  228. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/corpus.py +0 -0
  229. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/models.py +0 -0
  230. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/runner.py +0 -0
  231. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/__init__.py +0 -0
  232. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/briefings.py +0 -0
  233. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/chain.py +0 -0
  234. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/goals.py +0 -0
  235. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/memory.py +0 -0
  236. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/neo4j_cognition.py +0 -0
  237. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/relationship.py +0 -0
  238. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/sessions.py +0 -0
  239. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/skills.py +0 -0
  240. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/task_queue.py +0 -0
  241. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/seeders/world_model.py +0 -0
  242. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/self_query.py +0 -0
  243. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/self_reflection.py +0 -0
  244. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/skill.py +0 -0
  245. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/identity_bootstrap/verifier.py +0 -0
  246. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/__init__.py +0 -0
  247. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/action_registry.py +0 -0
  248. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/approval_authority.py +0 -0
  249. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/approval_policy.py +0 -0
  250. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/assignment.py +0 -0
  251. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/backup_evidence.py +0 -0
  252. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/context_freshness.py +0 -0
  253. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/models.py +0 -0
  254. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/native_work.py +0 -0
  255. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/standing_approvals.py +0 -0
  256. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/store.py +0 -0
  257. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/initiatives/temporal_followup.py +0 -0
  258. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/__init__.py +0 -0
  259. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/__init__.py +0 -0
  260. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/gap_detector.py +0 -0
  261. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/metalearner.py +0 -0
  262. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/metrics_collector.py +0 -0
  263. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/performance_index.py +0 -0
  264. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/registry.py +0 -0
  265. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/strategy_adjuster.py +0 -0
  266. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/cognition/types.py +0 -0
  267. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/__init__.py +0 -0
  268. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/anomaly_detector.py +0 -0
  269. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/initiative_engine.py +0 -0
  270. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/preference_learner.py +0 -0
  271. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/research_orchestrator.py +0 -0
  272. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/self_directed_thinker.py +0 -0
  273. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/self_reflector.py +0 -0
  274. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/session_continuity.py +0 -0
  275. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/task_planner.py +0 -0
  276. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/components/tool_learner.py +0 -0
  277. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/__init__.py +0 -0
  278. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/client.py +0 -0
  279. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/consolidator.py +0 -0
  280. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/distiller.py +0 -0
  281. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/migrations.py +0 -0
  282. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/queries.py +0 -0
  283. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/recall.py +0 -0
  284. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/reconciler.py +0 -0
  285. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/schema.py +0 -0
  286. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/graph/selection.py +0 -0
  287. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/learning/__init__.py +0 -0
  288. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/learning/continuous_learner.py +0 -0
  289. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/learning/feedback_store.py +0 -0
  290. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/mind_model/__init__.py +0 -0
  291. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/mind_model/graph_baseline.py +0 -0
  292. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/mind_model/signal_collector.py +0 -0
  293. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/relationships/__init__.py +0 -0
  294. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/relationships/profiler.py +0 -0
  295. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/relationships/scorer.py +0 -0
  296. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/relationships/signal_floor.py +0 -0
  297. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/relationships/trust_tiers.py +0 -0
  298. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/synthesis/__init__.py +0 -0
  299. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/synthesis/connection_discoverer.py +0 -0
  300. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/synthesis/cross_domain_analyzer.py +0 -0
  301. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/synthesis/insight_deliverer.py +0 -0
  302. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/synthesis/insight_store.py +0 -0
  303. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/synthesis/insight_validator.py +0 -0
  304. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/synthesis/novelty_scorer.py +0 -0
  305. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/turn_middleware/__init__.py +0 -0
  306. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/intelligence/turn_middleware/memory_sync.py +0 -0
  307. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mcp/__init__.py +0 -0
  308. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mcp/__main__.py +0 -0
  309. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mcp/config.py +0 -0
  310. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mcp/server.py +0 -0
  311. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/migrations.py +0 -0
  312. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mining/__init__.py +0 -0
  313. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mining/corpus.py +0 -0
  314. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mining/escalations.py +0 -0
  315. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mining/models.py +0 -0
  316. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/mining/store.py +0 -0
  317. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/models/__init__.py +0 -0
  318. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/models/memory.py +0 -0
  319. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/models/mesh.py +0 -0
  320. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/models/person.py +0 -0
  321. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/models/signal.py +0 -0
  322. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/observations/__init__.py +0 -0
  323. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/observations/store.py +0 -0
  324. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/patterns/__init__.py +0 -0
  325. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/patterns/extract.py +0 -0
  326. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/patterns/store.py +0 -0
  327. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/persona/__init__.py +0 -0
  328. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/persona/engine.py +0 -0
  329. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/persona/manifest.py +0 -0
  330. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/projects/__init__.py +0 -0
  331. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/projects/engine.py +0 -0
  332. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/projects/event_outbox.py +0 -0
  333. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/projects/models.py +0 -0
  334. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/projects/planner.py +0 -0
  335. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/projects/store.py +0 -0
  336. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/proposals/__init__.py +0 -0
  337. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/proposals/engine.py +0 -0
  338. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/proposals/models.py +0 -0
  339. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/__init__.py +0 -0
  340. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/cases.py +0 -0
  341. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/cli.py +0 -0
  342. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/memory_cases.py +0 -0
  343. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/records.py +0 -0
  344. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/report.py +0 -0
  345. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/runner.py +0 -0
  346. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/qualification/structured_cases.py +0 -0
  347. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/__init__.py +0 -0
  348. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/executor.py +0 -0
  349. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/loop.py +0 -0
  350. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/native_tools/__init__.py +0 -0
  351. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/native_tools/calculate.py +0 -0
  352. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/native_tools/file_ops.py +0 -0
  353. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/native_tools/web_search.py +0 -0
  354. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/reasoning/tool_policy.py +0 -0
  355. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/redact/__init__.py +0 -0
  356. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/repos/__init__.py +0 -0
  357. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/repos/mirrors.py +0 -0
  358. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/__init__.py +0 -0
  359. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/artifact.py +0 -0
  360. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/gatherer.py +0 -0
  361. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/pipeline.py +0 -0
  362. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/__init__.py +0 -0
  363. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/base.py +0 -0
  364. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/brave.py +0 -0
  365. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/cache.py +0 -0
  366. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/duckduckgo.py +0 -0
  367. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/orchestrator.py +0 -0
  368. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/serpapi.py +0 -0
  369. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/search/tavily.py +0 -0
  370. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/research/synthesizer.py +0 -0
  371. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/__init__.py +0 -0
  372. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/complexity_scorer.py +0 -0
  373. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/endpoints.py +0 -0
  374. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/fallback.py +0 -0
  375. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/functions.py +0 -0
  376. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/native_policy.py +0 -0
  377. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/router.py +0 -0
  378. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/self_learning.py +0 -0
  379. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/router/tiers.py +0 -0
  380. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sandbox/__init__.py +0 -0
  381. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sandbox/backend.py +0 -0
  382. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sandbox/manager.py +0 -0
  383. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/scope_bounds.py +0 -0
  384. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/__init__.py +0 -0
  385. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/backends/__init__.py +0 -0
  386. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/backends/base.py +0 -0
  387. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/backends/env.py +0 -0
  388. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/backends/keyring.py +0 -0
  389. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/backends/onepassword.py +0 -0
  390. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/cli.py +0 -0
  391. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/manager.py +0 -0
  392. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/migration.py +0 -0
  393. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/secrets/types.py +0 -0
  394. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/seed.py +0 -0
  395. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/__init__.py +0 -0
  396. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/appraisals.py +0 -0
  397. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/benchmark.py +0 -0
  398. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/brief.py +0 -0
  399. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/event_concerns.py +0 -0
  400. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/execution_forecasts.py +0 -0
  401. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/expectations.py +0 -0
  402. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/experiments.py +0 -0
  403. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/journal.py +0 -0
  404. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/judgments.py +0 -0
  405. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/native_outcomes.py +0 -0
  406. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/params.py +0 -0
  407. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/perspective.py +0 -0
  408. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/reconcile.py +0 -0
  409. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/reply_forecasts.py +0 -0
  410. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/runtime_forecasts.py +0 -0
  411. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/runtime_models.py +0 -0
  412. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/settlement.py +0 -0
  413. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/situation.py +0 -0
  414. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/store.py +0 -0
  415. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/supervised.py +0 -0
  416. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/thinker.py +0 -0
  417. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/trust.py +0 -0
  418. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/self_model/workspace.py +0 -0
  419. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/server.py +0 -0
  420. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/services/__init__.py +0 -0
  421. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/services/agent_bridge.py +0 -0
  422. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/services/initiative_executor.py +0 -0
  423. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/services/instance.py +0 -0
  424. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sessions/__init__.py +0 -0
  425. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sessions/config.py +0 -0
  426. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sessions/context_loader.py +0 -0
  427. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sessions/federation_session.py +0 -0
  428. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sessions/isolated_session.py +0 -0
  429. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sessions/reports.py +0 -0
  430. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/sessions/store.py +0 -0
  431. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/setup_local_work.py +0 -0
  432. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/setup_native_goals.py +0 -0
  433. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/setup_native_reviews.py +0 -0
  434. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/__init__.py +0 -0
  435. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/base.py +0 -0
  436. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/budget.py +0 -0
  437. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executor.py +0 -0
  438. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executors/__init__.py +0 -0
  439. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executors/behavioral_correction.py +0 -0
  440. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executors/capability_gap.py +0 -0
  441. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executors/data_quality.py +0 -0
  442. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executors/knowledge_acquisition.py +0 -0
  443. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executors/operational_hygiene.py +0 -0
  444. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/executors/subsystem_health.py +0 -0
  445. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/hermes_export.py +0 -0
  446. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/index.py +0 -0
  447. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/learning/__init__.py +0 -0
  448. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/learning/novelty_detector.py +0 -0
  449. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/learning/pattern_extractor.py +0 -0
  450. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/learning/triggers.py +0 -0
  451. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/loader.py +0 -0
  452. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/migrations/002_progressive_loading.sql +0 -0
  453. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/migrations/backfill_triggers.py +0 -0
  454. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/models.py +0 -0
  455. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/packager.py +0 -0
  456. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/protocols.py +0 -0
  457. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/registry.py +0 -0
  458. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/runtime.py +0 -0
  459. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/sandbox_runner.py +0 -0
  460. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/scheduler.py +0 -0
  461. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/schema.py +0 -0
  462. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/security/__init__.py +0 -0
  463. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/security/guards.py +0 -0
  464. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills/security/scanner.py +0 -0
  465. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills_memory/__init__.py +0 -0
  466. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills_memory/distill.py +0 -0
  467. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills_memory/models.py +0 -0
  468. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills_memory/retrieve.py +0 -0
  469. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/skills_memory/store.py +0 -0
  470. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/surprise/__init__.py +0 -0
  471. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/surprise/accumulation.py +0 -0
  472. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/surprise/scorer.py +0 -0
  473. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/surprise/store.py +0 -0
  474. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/__init__.py +0 -0
  475. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/action_receipts.py +0 -0
  476. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/approval_relay_canary.py +0 -0
  477. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/config.py +0 -0
  478. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/contract.py +0 -0
  479. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/events.py +0 -0
  480. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/governor.py +0 -0
  481. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/handlers/__init__.py +0 -0
  482. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/handlers/base.py +0 -0
  483. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/handlers/inference.py +0 -0
  484. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/handlers/monitoring.py +0 -0
  485. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/handlers/registry.py +0 -0
  486. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/handlers/subtask_handler.py +0 -0
  487. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/handlers/system_maintenance.py +0 -0
  488. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/mesh_integration.py +0 -0
  489. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/models.py +0 -0
  490. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/queue_manager.py +0 -0
  491. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/routing.py +0 -0
  492. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/scheduler.py +0 -0
  493. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/schema.sql +0 -0
  494. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/work_control.py +0 -0
  495. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/task_queue/worker.py +0 -0
  496. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/telemetry.py +0 -0
  497. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/__init__.py +0 -0
  498. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/affect.py +0 -0
  499. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/approvals.py +0 -0
  500. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/arcs.py +0 -0
  501. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/asymmetry.py +0 -0
  502. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/eligibility.py +0 -0
  503. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/engagement.py +0 -0
  504. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/exposure.py +0 -0
  505. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/extractor.py +0 -0
  506. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/fact_adapters.py +0 -0
  507. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/facts.py +0 -0
  508. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/integration.py +0 -0
  509. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/leveled.py +0 -0
  510. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/levels.py +0 -0
  511. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/recipient_audit.py +0 -0
  512. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/recipient_simulator.py +0 -0
  513. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/source_lineage.py +0 -0
  514. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/tom2.py +0 -0
  515. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/visibility.py +0 -0
  516. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tom/visibility_store.py +0 -0
  517. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tools/__init__.py +0 -0
  518. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tools/definitions.py +0 -0
  519. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/tools/handlers.py +0 -0
  520. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/toolsmith/__init__.py +0 -0
  521. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/toolsmith/authority.py +0 -0
  522. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/toolsmith/engine.py +0 -0
  523. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/toolsmith/integrity.py +0 -0
  524. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/toolsmith/miner.py +0 -0
  525. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/toolsmith/policy.py +0 -0
  526. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/toolsmith/registry.py +0 -0
  527. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/__init__.py +0 -0
  528. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/audio.py +0 -0
  529. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/documents.py +0 -0
  530. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/executions.py +0 -0
  531. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/hermes_history.py +0 -0
  532. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/hermes_kanban.py +0 -0
  533. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/hermes_work.py +0 -0
  534. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/idempotency.py +0 -0
  535. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/local_work.py +0 -0
  536. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/media.py +0 -0
  537. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/reported_workers.py +0 -0
  538. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/source_annotations.py +0 -0
  539. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/source_attribution.py +0 -0
  540. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/source_read.py +0 -0
  541. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/source_vectors.py +0 -0
  542. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/turns/video.py +0 -0
  543. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/util/autonomy_preset.py +0 -0
  544. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/util/instance.py +0 -0
  545. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/util/model_output.py +0 -0
  546. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/util/quiet_hours.py +0 -0
  547. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/util/session_safety.py +0 -0
  548. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/util/temporal.py +0 -0
  549. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/__init__.py +0 -0
  550. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/backfill.py +0 -0
  551. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/caption.py +0 -0
  552. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/collections.py +0 -0
  553. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/config.py +0 -0
  554. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/embedder.py +0 -0
  555. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/image_preprocess.py +0 -0
  556. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/image_store.py +0 -0
  557. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/indexes.py +0 -0
  558. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/migrate.py +0 -0
  559. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/multimodal_provider.py +0 -0
  560. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/multimodal_types.py +0 -0
  561. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/openai_provider.py +0 -0
  562. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/query.py +0 -0
  563. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/reranker.py +0 -0
  564. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/safety_image.py +0 -0
  565. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/scanner.py +0 -0
  566. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/setup.py +0 -0
  567. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/store.py +0 -0
  568. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/vector/tiers.py +0 -0
  569. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/work_orders.py +0 -0
  570. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/workers/__init__.py +0 -0
  571. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/workers/agent_bridge.py +0 -0
  572. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/workers/colony_worker.py +0 -0
  573. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/workers/queue_worker.py +0 -0
  574. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/workers/skills_sync.py +0 -0
  575. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/__init__.py +0 -0
  576. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/causal_maintenance.py +0 -0
  577. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/causal_policy.py +0 -0
  578. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/causal_query.py +0 -0
  579. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/confidence.py +0 -0
  580. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/config.py +0 -0
  581. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/constants.py +0 -0
  582. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/entities.py +0 -0
  583. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/expectation_resolvers.py +0 -0
  584. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/__init__.py +0 -0
  585. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/base.py +0 -0
  586. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/conversation_extractor.py +0 -0
  587. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/detector.py +0 -0
  588. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/document_extractor.py +0 -0
  589. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/formats/__init__.py +0 -0
  590. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/formats/csv_fmt.py +0 -0
  591. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/formats/html_fmt.py +0 -0
  592. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/formats/json_fmt.py +0 -0
  593. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/formats/pdf.py +0 -0
  594. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/formats/text.py +0 -0
  595. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/llm_extractor.py +0 -0
  596. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/extraction/pipeline.py +0 -0
  597. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/integrations/__init__.py +0 -0
  598. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/integrations/mind_model_bridge.py +0 -0
  599. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/integrations/social_intel_bridge.py +0 -0
  600. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/jobs/__init__.py +0 -0
  601. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/jobs/extraction_job.py +0 -0
  602. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/llm_extract.py +0 -0
  603. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/neo4j/__init__.py +0 -0
  604. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/neo4j/backend.py +0 -0
  605. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/observations.py +0 -0
  606. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/populator.py +0 -0
  607. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/postgres/__init__.py +0 -0
  608. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/postgres/backend.py +0 -0
  609. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/relationships.py +0 -0
  610. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/resolution/__init__.py +0 -0
  611. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/resolution/entity_resolver.py +0 -0
  612. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/resolution/merge_audit.py +0 -0
  613. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/resolution/merge_workflow.py +0 -0
  614. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/source_reports.py +0 -0
  615. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/sqlite/__init__.py +0 -0
  616. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/sqlite/backend.py +0 -0
  617. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/sqlite/schema.sql +0 -0
  618. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo/world_model/store.py +0 -0
  619. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo.egg-info/dependency_links.txt +0 -0
  620. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo.egg-info/entry_points.txt +0 -0
  621. {apsimo-1.3.0 → apsimo-1.3.1}/apsimo.egg-info/top_level.txt +0 -0
  622. {apsimo-1.3.0 → apsimo-1.3.1}/colony_sidecar/__init__.py +0 -0
  623. {apsimo-1.3.0 → apsimo-1.3.1}/setup.cfg +0 -0
  624. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_accepted_local_work.py +0 -0
  625. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_adaptive_params.py +0 -0
  626. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_affect.py +0 -0
  627. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_action_routing.py +0 -0
  628. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_api.py +0 -0
  629. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_bridge.py +0 -0
  630. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_bridge_service.py +0 -0
  631. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_sdk.py +0 -0
  632. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_sensor_loop.py +0 -0
  633. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_snapshot.py +0 -0
  634. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_agent_store.py +0 -0
  635. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_annotated_recall_reinforcement.py +0 -0
  636. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_answer_source_lineage.py +0 -0
  637. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_appraisal_incident_decisions.py +0 -0
  638. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_approval_gate.py +0 -0
  639. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_approval_relay_canary.py +0 -0
  640. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_apsimo_compat.py +0 -0
  641. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_apsimo_harness_guidance.py +0 -0
  642. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_assignment_engine.py +0 -0
  643. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_audit_cleanup.py +0 -0
  644. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_auth_coverage.py +0 -0
  645. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_auth_migration_readiness.py +0 -0
  646. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_authz_scope_api.py +0 -0
  647. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_autonomy_preset.py +0 -0
  648. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_backup.py +0 -0
  649. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_backup_receipt_evidence.py +0 -0
  650. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_beliefs.py +0 -0
  651. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_bind_auth_guard.py +0 -0
  652. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_boundary_fail_closed.py +0 -0
  653. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_bounded_approval_authority.py +0 -0
  654. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_briefing_aggregators.py +0 -0
  655. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_canonical_scoped_context.py +0 -0
  656. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_canonical_source_read.py +0 -0
  657. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_causal_extract.py +0 -0
  658. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_causal_falsifiability.py +0 -0
  659. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_causal_maintenance.py +0 -0
  660. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_causal_policy.py +0 -0
  661. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_causal_query.py +0 -0
  662. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_causal_query_only_guard.py +0 -0
  663. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_chain_keys.py +0 -0
  664. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_channel_preferences.py +0 -0
  665. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_channel_registry.py +0 -0
  666. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_channel_store.py +0 -0
  667. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition.py +0 -0
  668. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_evidence_pipeline.py +0 -0
  669. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_evidence_server_wiring.py +0 -0
  670. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_goal_spine.py +0 -0
  671. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_observability.py +0 -0
  672. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_p4_controlled_learning.py +0 -0
  673. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_p4_server_integration.py +0 -0
  674. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_p6_p7_server_wiring.py +0 -0
  675. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_p7_drive_governance.py +0 -0
  676. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_phase_b_runtime.py +0 -0
  677. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_phase_c_scheduler.py +0 -0
  678. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_cognition_server_wiring.py +0 -0
  679. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_colony_memory_provider.py +0 -0
  680. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_commitment_resolution.py +0 -0
  681. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_commitment_resolution_downgrade.py +0 -0
  682. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_commitment_resolution_schema.py +0 -0
  683. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_commitment_work.py +0 -0
  684. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_commitments.py +0 -0
  685. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_competence_reconciliation.py +0 -0
  686. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_compression.py +0 -0
  687. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_concern_resolution_receipts.py +0 -0
  688. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_condition_producer.py +0 -0
  689. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_connectors.py +0 -0
  690. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_contact_fact_recall.py +0 -0
  691. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_contact_policy_projection.py +0 -0
  692. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_contact_provisioning.py +0 -0
  693. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_contact_timezone.py +0 -0
  694. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_contacts_intro.py +0 -0
  695. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_contacts_persistence.py +0 -0
  696. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_context_gate.py +0 -0
  697. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_context_phase1.py +0 -0
  698. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_context_provenance.py +0 -0
  699. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_conversation_presence.py +0 -0
  700. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_conversation_turn_concerns.py +0 -0
  701. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_current_work_recall_selection.py +0 -0
  702. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_delivery_bridge_503.py +0 -0
  703. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_delivery_gateway_identity.py +0 -0
  704. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_delivery_reachout_routing.py +0 -0
  705. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_directed.py +0 -0
  706. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_directed_envelope.py +0 -0
  707. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_directed_reports.py +0 -0
  708. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_directed_trust.py +0 -0
  709. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_directive_sources.py +0 -0
  710. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_directives.py +0 -0
  711. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_distill.py +0 -0
  712. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_doctor.py +0 -0
  713. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_document_memory_guard.py +0 -0
  714. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_duckduckgo_provider.py +0 -0
  715. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_embedding_generations.py +0 -0
  716. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_ensure_channel_id.py +0 -0
  717. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_env_risk.py +0 -0
  718. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_event_broadcasts.py +0 -0
  719. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_event_bus_types.py +0 -0
  720. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_event_concerns.py +0 -0
  721. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_event_stream_reliability.py +0 -0
  722. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_execution_forecasts.py +0 -0
  723. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_execution_input_purpose.py +0 -0
  724. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_execution_registry.py +0 -0
  725. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_expectations.py +0 -0
  726. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_expectations_v2.py +0 -0
  727. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_experiments.py +0 -0
  728. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_external_cognition_events.py +0 -0
  729. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_external_event_concerns.py +0 -0
  730. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_facts_backfill.py +0 -0
  731. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_feedback.py +0 -0
  732. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_followup_plans.py +0 -0
  733. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_forecast_learning.py +0 -0
  734. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_function_routing.py +0 -0
  735. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_gap_generators.py +0 -0
  736. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_genesis_manifest.py +0 -0
  737. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_global_pause.py +0 -0
  738. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_goal_dispatch_availability.py +0 -0
  739. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_goal_inference_provenance.py +0 -0
  740. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_goal_reader_imports.py +0 -0
  741. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_governed_actions.py +0 -0
  742. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_governed_research_handoff.py +0 -0
  743. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_graduated_approvals.py +0 -0
  744. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_grant_envelope.py +0 -0
  745. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_graph_reindex_metadata.py +0 -0
  746. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_guard_audit.py +0 -0
  747. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_guard_chat_mode.py +0 -0
  748. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_guard_derive_context.py +0 -0
  749. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_guard_enforce_policy.py +0 -0
  750. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_export.py +0 -0
  751. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_general_governance.py +0 -0
  752. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_history_import.py +0 -0
  753. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_native_tool_authority.py +0 -0
  754. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_plugin_contract.py +0 -0
  755. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_plugin_event_lifecycle.py +0 -0
  756. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_plugin_event_replay.py +0 -0
  757. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_plugin_guard_shadow.py +0 -0
  758. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_plugin_signals.py +0 -0
  759. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_plugin_turn_id.py +0 -0
  760. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_queue_stats_projection.py +0 -0
  761. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_setup.py +0 -0
  762. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_turn_outbox.py +0 -0
  763. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hermes_work_projection.py +0 -0
  764. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_host_input_provenance.py +0 -0
  765. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_hostworker_agreement.py +0 -0
  766. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_identity_continuity.py +0 -0
  767. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_identity_corrections.py +0 -0
  768. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_inference_context_gate.py +0 -0
  769. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_initiative_engine.py +0 -0
  770. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_initiative_evidence.py +0 -0
  771. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_initiative_executor.py +0 -0
  772. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_initiative_feedback.py +0 -0
  773. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_initiative_pipeline_v016.py +0 -0
  774. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_initiative_retry.py +0 -0
  775. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_initiative_store.py +0 -0
  776. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_input_source_lineage.py +0 -0
  777. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_insight_store.py +0 -0
  778. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_instance_service.py +0 -0
  779. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_instance_service_live.py +0 -0
  780. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_intelligence_components.py +0 -0
  781. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_intelligence_synthesis.py +0 -0
  782. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_introduction_initiatives.py +0 -0
  783. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_job_writeback.py +0 -0
  784. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_journal.py +0 -0
  785. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_legacy_fact_context.py +0 -0
  786. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_local_work_context.py +0 -0
  787. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_loop_stats_accuracy.py +0 -0
  788. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_mcp_config.py +0 -0
  789. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_mcp_server.py +0 -0
  790. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_media_read_reference_presentation.py +0 -0
  791. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_memory_decay.py +0 -0
  792. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_memory_formation.py +0 -0
  793. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_memory_governance.py +0 -0
  794. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_memory_promotion.py +0 -0
  795. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_memory_prune.py +0 -0
  796. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_memory_read_hydration.py +0 -0
  797. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_memory_response_schemas.py +0 -0
  798. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_migrations.py +0 -0
  799. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_mining.py +0 -0
  800. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_model_qualification_cli.py +0 -0
  801. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_model_qualification_memory.py +0 -0
  802. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_model_qualification_runner.py +0 -0
  803. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_model_qualification_structured.py +0 -0
  804. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_accepted_local_work.py +0 -0
  805. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_initiative_work.py +0 -0
  806. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_input_carrier.py +0 -0
  807. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_outcome_judgments.py +0 -0
  808. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_request_erasure.py +0 -0
  809. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_review_recurrence.py +0 -0
  810. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_source_image_read.py +0 -0
  811. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_source_read.py +0 -0
  812. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_native_source_video_read.py +0 -0
  813. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_neo4j_backend.py +0 -0
  814. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_operator_deck_read_truth.py +0 -0
  815. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_ordinary_context_briefings.py +0 -0
  816. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_owner_preferences.py +0 -0
  817. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_p2_wirings.py +0 -0
  818. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_partial_work_rendering.py +0 -0
  819. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_patterns.py +0 -0
  820. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_pending_work_coverage.py +0 -0
  821. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_persona.py +0 -0
  822. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_persona_setup_result.py +0 -0
  823. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_phase_capability_check.py +0 -0
  824. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_preset_loop_coupling.py +0 -0
  825. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_procedure_source_context.py +0 -0
  826. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_project_event_outbox.py +0 -0
  827. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_project_result_reconciliation_phase.py +0 -0
  828. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_projects.py +0 -0
  829. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_prompt_evals.py +0 -0
  830. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_proposals.py +0 -0
  831. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_provenance_population.py +0 -0
  832. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_pseudo_agi_production_chain.py +0 -0
  833. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_queue_completed_filter.py +0 -0
  834. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_queue_contract.py +0 -0
  835. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_quiet_hours_and_reload.py +0 -0
  836. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_reachout_policy.py +0 -0
  837. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_recall_hybrid.py +0 -0
  838. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_recall_person_boost.py +0 -0
  839. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_recall_ranking.py +0 -0
  840. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_recall_rerank.py +0 -0
  841. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_recall_source_presentation.py +0 -0
  842. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_recall_unified_context.py +0 -0
  843. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_recency.py +0 -0
  844. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_reflection_task_routing.py +0 -0
  845. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_rejection_loop.py +0 -0
  846. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_relationship_calendar_aggregators.py +0 -0
  847. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_relationship_score_refresh.py +0 -0
  848. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_relationship_signal_floor.py +0 -0
  849. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_relationships.py +0 -0
  850. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_reply_forecast_callback_order.py +0 -0
  851. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_reply_forecast_stops.py +0 -0
  852. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_reply_forecasts.py +0 -0
  853. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_repo_tools.py +0 -0
  854. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_reported_worker_status.py +0 -0
  855. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_request_capabilities.py +0 -0
  856. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_request_work_context.py +0 -0
  857. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_reranker_remote.py +0 -0
  858. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_research_orchestrator.py +0 -0
  859. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_resolve_messaging_handle.py +0 -0
  860. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_response_guard.py +0 -0
  861. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_response_guard_communication_policy.py +0 -0
  862. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_response_guard_endpoint.py +0 -0
  863. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_response_guard_surface_policy.py +0 -0
  864. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_router_tiers.py +0 -0
  865. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_runtime_model_observations.py +0 -0
  866. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_sandbox.py +0 -0
  867. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_secondary_review_contract.py +0 -0
  868. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_seed_retirement.py +0 -0
  869. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_selected_autonomy.py +0 -0
  870. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_self_directed_thinker.py +0 -0
  871. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_self_initiatives.py +0 -0
  872. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_self_judgment_opt_in.py +0 -0
  873. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_self_judgment_premises.py +0 -0
  874. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_self_judgments.py +0 -0
  875. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_self_model.py +0 -0
  876. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_self_perspective.py +0 -0
  877. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_selfhood_benchmark.py +0 -0
  878. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_session_reports.py +0 -0
  879. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_shared_facts.py +0 -0
  880. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_shared_local_undertaking.py +0 -0
  881. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_short_source_context.py +0 -0
  882. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_sidecar.py +0 -0
  883. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_signals_attribution.py +0 -0
  884. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_situation_spine.py +0 -0
  885. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_skill_approval.py +0 -0
  886. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_skill_attribution.py +0 -0
  887. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_skill_sandbox.py +0 -0
  888. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_skill_synthesis.py +0 -0
  889. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_skill_synthesis_wiring.py +0 -0
  890. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_skills_memory.py +0 -0
  891. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_social_context_flow.py +0 -0
  892. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_social_transport.py +0 -0
  893. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_annotation_claim_survivors.py +0 -0
  894. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_annotations.py +0 -0
  895. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_appraisals.py +0 -0
  896. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_attribution.py +0 -0
  897. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_audio.py +0 -0
  898. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_audio_claims.py +0 -0
  899. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_claim_budget.py +0 -0
  900. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_claim_diagnostics.py +0 -0
  901. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_claim_media_eligibility.py +0 -0
  902. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_claim_projection.py +0 -0
  903. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_claim_review.py +0 -0
  904. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_claim_subject_basis.py +0 -0
  905. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_document_read.py +0 -0
  906. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_documents.py +0 -0
  907. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_episode_admission.py +0 -0
  908. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_episode_memory.py +0 -0
  909. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_episode_revisions.py +0 -0
  910. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_event_precision.py +0 -0
  911. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_excerpt_lineage.py +0 -0
  912. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_image_read.py +0 -0
  913. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_media.py +0 -0
  914. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_memory_backup.py +0 -0
  915. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_time_query.py +0 -0
  916. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_vectors.py +0 -0
  917. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_source_video.py +0 -0
  918. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_sqlite_connection_ownership.py +0 -0
  919. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_supervised_rung.py +0 -0
  920. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_surprise.py +0 -0
  921. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_sweep_fixes.py +0 -0
  922. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_synthesis.py +0 -0
  923. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_telemetry_staleness.py +0 -0
  924. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_temporal.py +0 -0
  925. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_temporal_followups.py +0 -0
  926. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_temporal_index.py +0 -0
  927. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_test_environment_isolation.py +0 -0
  928. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_thinking_phase.py +0 -0
  929. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_thought_function_routing.py +0 -0
  930. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tick_phase_budget.py +0 -0
  931. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tier_endpoints.py +0 -0
  932. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_timeline.py +0 -0
  933. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_approvals.py +0 -0
  934. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_asymmetry.py +0 -0
  935. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_context.py +0 -0
  936. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_cross_gate.py +0 -0
  937. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_eligibility.py +0 -0
  938. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_epistemic_guard.py +0 -0
  939. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_exposure.py +0 -0
  940. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_kill_switch.py +0 -0
  941. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_level_coherence.py +0 -0
  942. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_leveled.py +0 -0
  943. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_levels.py +0 -0
  944. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_source_corrections.py +0 -0
  945. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_store.py +0 -0
  946. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_taint.py +0 -0
  947. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom2_wiring.py +0 -0
  948. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_event_lineage.py +0 -0
  949. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_extractor.py +0 -0
  950. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_arcs.py +0 -0
  951. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_boundary_corpus.py +0 -0
  952. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_fact_adapters.py +0 -0
  953. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_outbound_integration.py +0 -0
  954. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_recipient_audit.py +0 -0
  955. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_recipient_simulator.py +0 -0
  956. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_server_integration.py +0 -0
  957. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_visibility.py +0 -0
  958. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_p8_visibility_store.py +0 -0
  959. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tom_source_lineage.py +0 -0
  960. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tool_handlers_graph.py +0 -0
  961. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tool_provenance.py +0 -0
  962. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_tool_surface.py +0 -0
  963. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_toolsmith.py +0 -0
  964. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_transport_ingress.py +0 -0
  965. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_transport_ingress_api.py +0 -0
  966. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_trust_configure.py +0 -0
  967. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_trust_scopes.py +0 -0
  968. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_trust_scopes_p2.py +0 -0
  969. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_turn_idempotency_ledger.py +0 -0
  970. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_turn_idempotency_v2.py +0 -0
  971. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_turn_ner_entities.py +0 -0
  972. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_turn_source_erasure.py +0 -0
  973. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_turn_source_evidence.py +0 -0
  974. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_turn_survivor_delivery.py +0 -0
  975. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_validation_sweep_fixes.py +0 -0
  976. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_vector_vacuum.py +0 -0
  977. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_wizard_autonomy.py +0 -0
  978. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_work_ancestry_projection.py +0 -0
  979. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_work_control_production_blockers.py +0 -0
  980. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_work_control_v1.py +0 -0
  981. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_work_orders.py +0 -0
  982. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_work_read_surface_authority.py +0 -0
  983. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_work_source_coverage.py +0 -0
  984. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_worker_handler_boundaries.py +0 -0
  985. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_worker_heartbeat_truth.py +0 -0
  986. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_worker_http_authority.py +0 -0
  987. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_worker_integration.py +0 -0
  988. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_worker_lifecycle_durability.py +0 -0
  989. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_workers_governor.py +0 -0
  990. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_workers_install.py +0 -0
  991. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_workspace.py +0 -0
  992. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_world_context_query.py +0 -0
  993. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_world_entity_reinforcement.py +0 -0
  994. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_world_llm_extract.py +0 -0
  995. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_world_model_prune.py +0 -0
  996. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_world_observations.py +0 -0
  997. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_world_populator.py +0 -0
  998. {apsimo-1.3.0 → apsimo-1.3.1}/tests/test_world_quality.py +0 -0
  999. {apsimo-1.3.0 → apsimo-1.3.1}/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.0
3
+ Version: 1.3.1
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.0; extra == "hermes"
31
+ Requires-Dist: apsimo-hermes<2,>=1.3.1; 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",
@@ -3907,6 +3907,26 @@ async def forget_turn_sources(body: SourceForgetRequest, request: Request = None
3907
3907
  "host_reconciliation": "pending_until_each_host_connects"}
3908
3908
 
3909
3909
 
3910
+ async def _resolve_scoped_sender_contact(authority, gateway: str, address: str):
3911
+ """Read one verified handle within the credential's existing grants."""
3912
+ platform = gateway.strip().lower()
3913
+ if (not authority.authenticated or not authority.has_scope('turns:resolve-sender')
3914
+ or platform not in authority.turn_ingress_platforms):
3915
+ raise HTTPException(status_code=403, detail='Sender resolution is outside this transport grant')
3916
+ if _contacts_store is None:
3917
+ raise HTTPException(status_code=503, detail='Contact store not initialized')
3918
+ from apsimo.contacts.identity_links import normalized_handle
3919
+ try:
3920
+ normalized_gateway, normalized_address = normalized_handle(platform, address)
3921
+ contact = await _contacts_store.resolve_verified_handles(
3922
+ normalized_gateway, [normalized_address])
3923
+ except ValueError:
3924
+ raise HTTPException(status_code=400, detail='Invalid sender handle') from None
3925
+ if contact is None or contact.contact_id not in authority.person_ids:
3926
+ raise HTTPException(status_code=404, detail='No enrolled contact for that handle')
3927
+ return contact
3928
+
3929
+
3910
3930
  async def _ingest_turn_idempotently(
3911
3931
  body: TurnSyncRequest,
3912
3932
  request: Request | None = None,
@@ -3918,9 +3938,23 @@ async def _ingest_turn_idempotently(
3918
3938
  effects run. This is the server's final defense even when a host retries or
3919
3939
  two host integrations accidentally submit the same envelope.
3920
3940
  """
3941
+ resolved_sender_contact_id = None
3942
+ authority = request_authority(request)
3943
+ if (body.sender is not None and not authority.legacy and authority.authenticated
3944
+ and authority.has_scope('turns:resolve-sender')
3945
+ and not (authority.allow_unscoped_api and authority.has_scope('api:access'))
3946
+ and body.sender.platform.strip().lower() not in authority.attested_contact_platforms):
3947
+ # Static transport enrollment cannot inherit the viewer on a failed
3948
+ # lookup, or take the general resolver's canonical-ID/name fallbacks.
3949
+ # Validate before checkpoints, reservations or any source write.
3950
+ contact = await _resolve_scoped_sender_contact(
3951
+ authority, body.sender.platform, body.sender.user_id)
3952
+ resolved_sender_contact_id = contact.contact_id
3953
+ body.context.contact_id = contact.contact_id
3921
3954
  turn_id = (body.context.turn_id or "").strip()
3922
3955
  if not turn_id:
3923
- return await _process_turn_sync(body, request=request), "unkeyed"
3956
+ return await _process_turn_sync(body, request=request,
3957
+ resolved_sender_contact_id=resolved_sender_contact_id), "unkeyed"
3924
3958
  if len(turn_id) > 256:
3925
3959
  raise HTTPException(
3926
3960
  status_code=422,
@@ -4010,7 +4044,8 @@ async def _ingest_turn_idempotently(
4010
4044
  ), "in_progress"
4011
4045
 
4012
4046
  try:
4013
- result = await _process_turn_sync(body, request=request)
4047
+ result = await _process_turn_sync(body, request=request,
4048
+ resolved_sender_contact_id=resolved_sender_contact_id)
4014
4049
  except BaseException as exc:
4015
4050
  ledger.mark_ambiguous(turn_id, digest, exc)
4016
4051
  raise
@@ -4177,6 +4212,8 @@ async def turns_sync_v2(
4177
4212
  async def _process_turn_sync(
4178
4213
  body: TurnSyncRequest,
4179
4214
  request: Request | None = None,
4215
+ *,
4216
+ resolved_sender_contact_id: str | None = None,
4180
4217
  ) -> TurnSyncResponse:
4181
4218
  # Keep direct blocks for canonical source storage. All existing text-only
4182
4219
  # cognition consumers receive only explicit text, never repr(base64/URLs).
@@ -4221,7 +4258,11 @@ async def _process_turn_sync(
4221
4258
  from apsimo.identity.participants import (
4222
4259
  SYSTEM_CONTACT_ID, ParticipantResolver, is_machine_turn,
4223
4260
  )
4224
- if body.sender is not None and _contacts_store is not None:
4261
+ if resolved_sender_contact_id is not None:
4262
+ body.context.contact_id = resolved_sender_contact_id
4263
+ _resolution_method = "verified_handle"
4264
+ _resolved_human_sender = True
4265
+ elif body.sender is not None and _contacts_store is not None:
4225
4266
  _res = await ParticipantResolver(_contacts_store).resolve(
4226
4267
  platform=body.sender.platform,
4227
4268
  user_id=body.sender.user_id,
@@ -6282,7 +6323,7 @@ async def capture_introduction(body: ContactIntroRequest) -> ContactIntroRespons
6282
6323
 
6283
6324
 
6284
6325
  @router.get("/contacts/resolve", response_model=ContactResponse)
6285
- async def resolve_contact_by_handle(gateway: str, address: str, create: bool = False) -> ContactResponse:
6326
+ async def resolve_contact_by_handle(gateway: str, address: str, request: Request, create: bool = False) -> ContactResponse:
6286
6327
  """Resolve a contact from a messaging handle (v0.21.2).
6287
6328
 
6288
6329
  Registered BEFORE /contacts/{contact_id} so it isn't shadowed by the
@@ -6298,6 +6339,14 @@ async def resolve_contact_by_handle(gateway: str, address: str, create: bool = F
6298
6339
  if _contacts_store is None:
6299
6340
  raise HTTPException(status_code=404, detail="Contact store not initialized")
6300
6341
  try:
6342
+ authority = request_authority(request)
6343
+ if not authority.legacy and not (
6344
+ authority.allow_unscoped_api and authority.has_scope('api:access')):
6345
+ # Fresh native profiles resolve only explicitly enrolled accounts.
6346
+ # The memory provider's legacy create=true hint cannot provision a
6347
+ # contact or expand the credential's person/transport grants here.
6348
+ contact = await _resolve_scoped_sender_contact(authority, gateway, address)
6349
+ return ContactResponse(**contact.to_dict())
6301
6350
  # Normalized, cross-gateway phone-identity resolution (a number is one contact regardless of
6302
6351
  # the transport it arrived on). find_by_handle stays exact-match for dedup callers.
6303
6352
  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)")
@@ -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 preferences cannot be combined with another harness setup.')
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
- return await setup.build_owner_contact(store, owner_name)
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.0
3
+ Version: 1.3.1
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.0; extra == "hermes"
31
+ Requires-Dist: apsimo-hermes<2,>=1.3.1; 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
@@ -860,6 +861,7 @@ tests/test_router_tiers.py
860
861
  tests/test_runtime_model_observations.py
861
862
  tests/test_sandbox.py
862
863
  tests/test_scoped_api_authority.py
864
+ tests/test_scoped_contact_resolution.py
863
865
  tests/test_secondary_review_contract.py
864
866
  tests/test_seed_retirement.py
865
867
  tests/test_selected_autonomy.py
@@ -35,7 +35,7 @@ beautifulsoup4>=4.12
35
35
  neo4j>=5.18
36
36
 
37
37
  [hermes]
38
- apsimo-hermes<2,>=1.3.0
38
+ apsimo-hermes<2,>=1.3.1
39
39
 
40
40
  [lancedb]
41
41
  lancedb>=0.6
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "apsimo"
7
- version = "1.3.0"
7
+ version = "1.3.1"
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.0,<2"]
32
+ hermes = ["apsimo-hermes>=1.3.1,<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())
@@ -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)
@@ -545,11 +545,13 @@ async def test_turn_contact_is_validated_before_idempotent_ingestion(tmp_path, g
545
545
 
546
546
 
547
547
  @pytest.mark.asyncio
548
- async def test_sender_resolving_adapter_discards_initial_contact_claim(tmp_path, graph):
548
+ async def test_sender_resolving_adapter_cannot_inherit_viewer_without_contact_store(tmp_path, graph):
549
549
  keyring = tmp_path / "keys.json"
550
- _write_keyring(keyring, [_principal(scopes=[
550
+ principal = _principal(scopes=[
551
551
  "turns:write", "turns:resolve-sender"
552
- ])])
552
+ ])
553
+ principal['turn_ingress_platforms'] = ['example-chat']
554
+ _write_keyring(keyring, [principal])
553
555
  app = _app(keyring)
554
556
  payload = _turn_payload("body-claim", "sender-turn")
555
557
  payload["sender"] = {
@@ -563,10 +565,10 @@ async def test_sender_resolving_adapter_discards_initial_contact_claim(tmp_path,
563
565
  json=payload,
564
566
  )
565
567
 
566
- assert response.status_code == 200
567
- # No contacts store is wired in this focused test, so the resolver cannot
568
- # map the sender further. The untrusted body claim is still gone.
569
- assert graph.turn_calls[0]["contact_id"] == "contact-owner"
568
+ assert response.status_code == 503
569
+ # Unavailable identity resolution cannot turn an unknown sender into the
570
+ # credential's default viewer or run ordinary conversation effects.
571
+ assert graph.turn_calls == []
570
572
 
571
573
 
572
574
  @pytest.mark.asyncio
@@ -930,8 +932,8 @@ async def test_resolved_sender_in_static_grant_needs_no_dynamic_platform_grant(
930
932
  from apsimo.events import journal as event_journal
931
933
 
932
934
  class Contacts:
933
- async def resolve_messaging_handle(self, platform, user_id):
934
- assert (platform, user_id) == ("voice", "owner-voice-handle")
935
+ async def resolve_verified_handles(self, platform, user_ids):
936
+ assert (platform, user_ids) == ("voice", ["owner-voice-handle"])
935
937
  return SimpleNamespace(contact_id="contact-owner")
936
938
 
937
939
  async def record_interaction(self, _contact_id):
@@ -0,0 +1,48 @@
1
+ """The focused sender resolver preserves explicitly broad legacy clients."""
2
+ import json
3
+
4
+ from fastapi import FastAPI
5
+ import httpx
6
+ import pytest
7
+
8
+ from apsimo.api.middleware import ApiKeyMiddleware
9
+ from apsimo.api.routers import host
10
+ from apsimo.contacts.config import ContactsConfig
11
+ from apsimo.contacts.store import SQLiteContactStore
12
+
13
+
14
+ @pytest.mark.asyncio
15
+ async def test_legacy_resolver_scope_compatibility_is_explicit(tmp_path, monkeypatch):
16
+ store = SQLiteContactStore(ContactsConfig(sqlite_path=str(tmp_path/'contacts.db')))
17
+ await store.connect()
18
+ monkeypatch.setattr(host, '_contacts_store', store)
19
+ try:
20
+ owner = await store.create(display_name='Owner')
21
+ await store.add_handle(owner.contact_id, 'telegram', '123456789', verified=True)
22
+ keyring = tmp_path/'keyring.json'
23
+ keyring.write_text(json.dumps({'version': 1, 'principals': [{
24
+ 'principal': name, 'status': 'active', 'viewer_person_id': owner.contact_id,
25
+ 'audiences': ['viewer'], 'allow_unscoped_api': broad, 'scopes': ['api:access'],
26
+ 'credentials': [{'id': 'test', 'status': 'active', 'secret': name + '-secret'}],
27
+ } for name, broad in [('broad', True), ('restricted', False)]]}))
28
+ keyring.chmod(0o600)
29
+ app = FastAPI()
30
+ app.add_middleware(ApiKeyMiddleware, keyring_path=str(keyring), api_key='legacy-secret')
31
+ app.include_router(host.router)
32
+ async with httpx.AsyncClient(transport=httpx.ASGITransport(app=app), base_url='http://test') as client:
33
+ for secret, status in [('legacy-secret', 200), ('broad-secret', 200), ('restricted-secret', 403)]:
34
+ response = await client.get('/v1/host/contacts/resolve',
35
+ headers={'Authorization': 'Bearer ' + secret},
36
+ params={'gateway': 'telegram', 'address': '123456789'})
37
+ assert response.status_code == status, response.text
38
+ if status == 200:
39
+ assert response.json()['contact_id'] == owner.contact_id
40
+ # Retain the previously explicit broad provisioning behavior.
41
+ response = await client.get('/v1/host/contacts/resolve',
42
+ headers={'Authorization': 'Bearer broad-secret'},
43
+ params={'gateway': 'telegram', 'address': '987654321', 'create': 'true'})
44
+ assert response.status_code == 200, response.text
45
+ assert response.json()['contact_id'] != owner.contact_id
46
+ assert response.json()['interaction_allowed'] is False
47
+ finally:
48
+ await store.close()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes