AbstractRuntime 0.8.4__tar.gz → 0.9.0__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 (689) hide show
  1. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/.github/workflows/ci.yml +53 -0
  2. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/CHANGELOG.md +28 -2
  3. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/PKG-INFO +5 -5
  4. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/README.md +1 -1
  5. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/README.md +1 -1
  6. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/api.md +12 -2
  7. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/automations.md +3 -2
  8. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/faq.md +6 -4
  9. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/getting-started.md +1 -1
  10. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/integrations/abstractcore.md +39 -6
  11. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/llms-full.txt +63 -17
  12. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/llms.txt +4 -4
  13. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/pyproject.toml +4 -4
  14. abstractruntime-0.9.0/release-notes.md +23 -0
  15. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/commands.py +39 -1
  16. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/controller.py +14 -0
  17. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/runtime.py +15 -0
  18. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/tools.py +28 -0
  19. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/__init__.py +14 -0
  20. abstractruntime-0.9.0/src/abstractruntime/integrations/abstractcore/command_sandbox_host.py +29 -0
  21. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/effect_handlers.py +4 -0
  22. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/local_helper_tools.py +28 -3
  23. abstractruntime-0.9.0/src/abstractruntime/integrations/abstractcore/server_facade.py +32 -0
  24. abstractruntime-0.9.0/src/abstractruntime/integrations/abstractcore/structured_facade.py +51 -0
  25. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/tool_executor.py +30 -4
  26. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/workspace_scoped_tools.py +161 -23
  27. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/utils/workspace_paths.py +48 -2
  28. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/compiler.py +10 -1
  29. abstractruntime-0.9.0/tests/test_abstractcore_server_facade.py +72 -0
  30. abstractruntime-0.9.0/tests/test_abstractcore_structured_facade.py +54 -0
  31. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_commands.py +38 -0
  32. abstractruntime-0.9.0/tests/test_automation_occurrence_input_resolver.py +92 -0
  33. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_tool_approval.py +4 -1
  34. abstractruntime-0.9.0/tests/test_command_sandbox_host_facade.py +27 -0
  35. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_packaging_extras.py +3 -3
  36. abstractruntime-0.9.0/tests/test_r12_workspace_sandbox.py +373 -0
  37. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_shell_tool_exposure.py +3 -1
  38. abstractruntime-0.9.0/tests/test_workspace_context_allowed_workspaces.py +75 -0
  39. abstractruntime-0.9.0/tests/test_workspace_writable_paths.py +69 -0
  40. abstractruntime-0.8.4/release-notes.md +0 -2
  41. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/.github/workflows/release.yml +0 -0
  42. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/.gitignore +0 -0
  43. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/ACKNOWLEDGMENTS.md +0 -0
  44. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/CODE_OF_CONDUCT.md +0 -0
  45. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/CONTRIBUTING.md +0 -0
  46. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/LICENSE +0 -0
  47. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/ROADMAP.md +0 -0
  48. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/SECURITY.md +0 -0
  49. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/0001_layered_coupling_with_abstractcore.md +0 -0
  50. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/0002_execution_modes_local_remote_hybrid.md +0 -0
  51. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/0003_provenance_tamper_evident_hash_chain.md +0 -0
  52. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/0004_runtime_owns_run_scoped_media_execution_truth.md +0 -0
  53. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/0005_runtime_owns_abstractcore_host_discovery_queries.md +0 -0
  54. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/0006_runtime_owns_durable_abstractcore_bloc_prompt_cache.md +0 -0
  55. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/0007_runtime_relays_core_owned_model_residency_truth.md +0 -0
  56. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/adr/README.md +0 -0
  57. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/architecture.md +0 -0
  58. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/artifacts.md +0 -0
  59. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/README.md +0 -0
  60. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/001_runtime_kernel.md +0 -0
  61. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/002_persistence_and_ledger.md +0 -0
  62. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0030_runtime_host_facades_for_comms_telegram_and_tool_specs.md +0 -0
  63. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0032_runtime_durable_outbound_comms_truth.md +0 -0
  64. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0033_runtime_host_local_prompt_cache_export_import_surface.md +0 -0
  65. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0035_model_residency_provider_truth_for_local_http_clients.md +0 -0
  66. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0037_visualflow_generate_music_node_compiler_parity.md +0 -0
  67. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0039_runtime_music_structure_prompt_bool_contract.md +0 -0
  68. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/003_wait_primitives.md +0 -0
  69. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0040_task_agnostic_local_residency_listing.md +0 -0
  70. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0041_runtime_hardware_extras_avoid_nonpermissive_document_stacks.md +0 -0
  71. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0042_core_vision_upscale_and_parameter_surface.md +0 -0
  72. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0043_runtime_vision_adapter_and_batch_surface.md +0 -0
  73. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/004_scheduler_driver.md +0 -0
  74. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/005_abstractcore_integration.md +0 -0
  75. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/006_snapshots_bookmarks.md +0 -0
  76. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/007_provenance_hash_chain.md +0 -0
  77. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/009_artifact_store.md +0 -0
  78. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/010_examples_and_composition.md +0 -0
  79. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/011_subworkflow_support.md +0 -0
  80. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/012_run_store_query_and_scheduler_support.md +0 -0
  81. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/013_effect_retries_and_idempotency.md +0 -0
  82. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/016_runtime_aware_parameters.md +0 -0
  83. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/019_runtime_host_facade_for_core_operator_surfaces.md +0 -0
  84. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/020_runtime_gateway_install_boundary.md +0 -0
  85. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/021_runtime_gateway_env_namespace_cleanup.md +0 -0
  86. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/022_model_residency_control_plane.md +0 -0
  87. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/023_truthful_local_media_residency_boundaries.md +0 -0
  88. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/024_runtime_owned_run_scoped_media_execution.md +0 -0
  89. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/026_runtime_host_discovery_facade_for_core_catalogs.md +0 -0
  90. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/027_runtime_durable_bloc_prompt_cache_facade.md +0 -0
  91. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/028_runtime_bloc_kv_lifecycle_and_pruning.md +0 -0
  92. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/029_runtime_music_generation_and_discovery_via_abstractcore.md +0 -0
  93. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0846_mlx_instance_scheduling_and_execution_controls.md +0 -0
  94. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/completed/0847_automations_v1_controller_contracts_occurrences_triggers.md +0 -0
  95. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/001_integrations_abstractcore.md +0 -0
  96. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/001_runtime_kernel.md +0 -0
  97. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/002_persistence_and_ledger.md +0 -0
  98. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/002_snapshots_bookmarks.md +0 -0
  99. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/0034_agent_runtime_convenience_constructor.md +0 -0
  100. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/003_provenance_ledger_chain.md +0 -0
  101. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/003_wait_resume_and_scheduler.md +0 -0
  102. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/004_effect_handlers_and_integrations.md +0 -0
  103. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/004_tests.md +0 -0
  104. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/005_docs_updates.md +0 -0
  105. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/005_examples_and_composition.md +0 -0
  106. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/006_ai_fingerprint_and_provenance.md +0 -0
  107. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/DEPRECATED_README.md +0 -0
  108. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/README.md +0 -0
  109. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/deprecated/abstractruntime_docs_final_02a7373b.plan.md +0 -0
  110. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/0070_standalone_wui_browser_session_security_contract.md +0 -0
  111. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/008_signatures_and_keys.md +0 -0
  112. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/014_remote_tool_worker_executor.md +0 -0
  113. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/017_limit_warnings_and_observability.md +0 -0
  114. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/018_workspace_access_policy_for_media_and_tools.md +0 -0
  115. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/0233_real_run_cancellation.md +0 -0
  116. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/025_runtime_retention_and_purge_contract.md +0 -0
  117. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/026_context_checkpoint_self_compression.md +0 -0
  118. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/027_quote_provenance_discipline.md +0 -0
  119. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/028_selective_artifact_rehydration.md +0 -0
  120. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/0845_session_prompt_cache_resume_and_purge_contract.md +0 -0
  121. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/0848_automations_v2_external_event_inbox_and_run_triggers.md +0 -0
  122. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_portability/0065_portable_process_and_lock_layer.md +0 -0
  123. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_portability/0066_portable_io_and_media_reader.md +0 -0
  124. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_portability/README.md +0 -0
  125. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0044_meta_analysis_record.md +0 -0
  126. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0045_crash_replay_harness_and_ordering_invariant.md +0 -0
  127. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0046_per_run_driver_exclusion.md +0 -0
  128. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0047_indexed_idempotency_lookup.md +0 -0
  129. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0048_durable_io_unification.md +0 -0
  130. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0049_llm_client_mechanical_split.md +0 -0
  131. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0050_control_sidecar_all_writers.md +0 -0
  132. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0051_runtime_owned_durable_event_mailbox.md +0 -0
  133. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0052_sync_store_event_loop_tripwire.md +0 -0
  134. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0053_bounded_run_vars_growth.md +0 -0
  135. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0054_runtime_health_counters.md +0 -0
  136. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0055_jsonl_store_honesty.md +0 -0
  137. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0064_prompt_cache_fingerprint_stability.md +0 -0
  138. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0067_durable_write_discipline.md +0 -0
  139. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/0068_hot_path_store_reads.md +0 -0
  140. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/planned/runtime_systemic_reliability/README.md +0 -0
  141. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/0031_runtime_tool_spec_adapters_for_gateway_and_mcp.md +0 -0
  142. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/0036_local_media_residency_bridge_to_core_residency.md +0 -0
  143. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/0038_core_server_pool_residency_affinity.md +0 -0
  144. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/0069_document_renderer_professional_figures.md +0 -0
  145. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0056_schema_version_and_quarantine_loading.md +0 -0
  146. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0057_trust_boundary_stamp_registry.md +0 -0
  147. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0058_terminal_run_archival_helper.md +0 -0
  148. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0059_memory_span_handler_extraction.md +0 -0
  149. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0060_visualflow_compiler_decomposition.md +0 -0
  150. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0061_root_api_deprecation_machinery.md +0 -0
  151. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0062_dependency_honesty_extras.md +0 -0
  152. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/0063_b3_envelope_lane_unification.md +0 -0
  153. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/backlog/proposed/runtime_systemic_reliability/README.md +0 -0
  154. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/email.md +0 -0
  155. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/entity-runtime.md +0 -0
  156. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/evidence.md +0 -0
  157. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/limits.md +0 -0
  158. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/manual_testing.md +0 -0
  159. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/mcp-worker.md +0 -0
  160. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/proposal.md +0 -0
  161. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/provenance.md +0 -0
  162. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/snapshots.md +0 -0
  163. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/tool-approval.md +0 -0
  164. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/tools-comms.md +0 -0
  165. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/troubleshooting.md +0 -0
  166. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/docs/workflow-bundles.md +0 -0
  167. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/01_hello_world.py +0 -0
  168. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/02_ask_user.py +0 -0
  169. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/03_wait_until.py +0 -0
  170. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/04_multi_step.py +0 -0
  171. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/05_persistence.py +0 -0
  172. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/06_llm_integration.py +0 -0
  173. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/07_react_agent.py +0 -0
  174. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/examples/README.md +0 -0
  175. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/mkdocs.yml +0 -0
  176. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/pytest.ini +0 -0
  177. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/scripts/backfill_diary_edges.py +0 -0
  178. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/scripts/generate_llms_full.py +0 -0
  179. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/__init__.py +0 -0
  180. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automation_queries.py +0 -0
  181. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/__init__.py +0 -0
  182. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/adapters.py +0 -0
  183. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/attention.py +0 -0
  184. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/bundle.py +0 -0
  185. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/bundles/automation-controller/flows/controller.json +0 -0
  186. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/bundles/automation-controller/manifest.json +0 -0
  187. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/ledger.py +0 -0
  188. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/models.py +0 -0
  189. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/automations/service.py +0 -0
  190. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/__init__.py +0 -0
  191. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/config.py +0 -0
  192. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/effect_cancellation.py +0 -0
  193. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/event_keys.py +0 -0
  194. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/health.py +0 -0
  195. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/live_deltas.py +0 -0
  196. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/models.py +0 -0
  197. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/policy.py +0 -0
  198. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/progress_channel.py +0 -0
  199. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/run_attribution.py +0 -0
  200. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/run_identity.py +0 -0
  201. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/run_lifecycle.py +0 -0
  202. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/spec.py +0 -0
  203. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/tool_scope.py +0 -0
  204. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/core/vars.py +0 -0
  205. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/documents/__init__.py +0 -0
  206. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/documents/charts.py +0 -0
  207. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/documents/docx.py +0 -0
  208. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/documents/pdf.py +0 -0
  209. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/email/__init__.py +0 -0
  210. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/email/actions.py +0 -0
  211. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/email/automations.py +0 -0
  212. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/email/binding.py +0 -0
  213. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/email/feeder.py +0 -0
  214. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/email/frame.py +0 -0
  215. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/email/inbox.py +0 -0
  216. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/evidence/__init__.py +0 -0
  217. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/evidence/recorder.py +0 -0
  218. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/history_bundle.py +0 -0
  219. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/__init__.py +0 -0
  220. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/act_only.py +0 -0
  221. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/chat.py +0 -0
  222. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/communities.py +0 -0
  223. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/diary.py +0 -0
  224. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/digest.py +0 -0
  225. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/entity_runtime.py +0 -0
  226. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/fingerprint.py +0 -0
  227. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/lease.py +0 -0
  228. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/life.py +0 -0
  229. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/memory_reader.py +0 -0
  230. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/night_voice.py +0 -0
  231. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/phase_graph.py +0 -0
  232. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/phase_spec.py +0 -0
  233. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/prelude.py +0 -0
  234. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/prompt_overlay.py +0 -0
  235. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/reflection.py +0 -0
  236. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/spec/entity_phases.vendored.json +0 -0
  237. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/substrate.py +0 -0
  238. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/tool_effects.py +0 -0
  239. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/tool_policy.py +0 -0
  240. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/identity/visit_workflow.py +0 -0
  241. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/__init__.py +0 -0
  242. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/agora_tools.py +0 -0
  243. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/comms_facade.py +0 -0
  244. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/config_facade.py +0 -0
  245. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/constants.py +0 -0
  246. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/data_registry_facade.py +0 -0
  247. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/default_tools.py +0 -0
  248. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/discovery_facade.py +0 -0
  249. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/discovery_queries.py +0 -0
  250. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/email_facade.py +0 -0
  251. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/embeddings_client.py +0 -0
  252. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/factory.py +0 -0
  253. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/host_facade.py +0 -0
  254. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/llm_client.py +0 -0
  255. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/logging.py +0 -0
  256. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/mcp_facade.py +0 -0
  257. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/mcp_worker.py +0 -0
  258. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/media_subprocess.py +0 -0
  259. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/observability.py +0 -0
  260. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/output_specs.py +0 -0
  261. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/run_facade.py +0 -0
  262. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/session_attachments.py +0 -0
  263. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/summarizer.py +0 -0
  264. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/telegram_facade.py +0 -0
  265. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/tool_effects.py +0 -0
  266. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractcore/tool_inventory_facade.py +0 -0
  267. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractmemory/__init__.py +0 -0
  268. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractmemory/brain_handlers.py +0 -0
  269. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractmemory/effect_handlers.py +0 -0
  270. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractmemory/identity_support.py +0 -0
  271. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/integrations/abstractmemory/seam_handlers.py +0 -0
  272. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/__init__.py +0 -0
  273. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/active_context.py +0 -0
  274. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/active_memory.py +0 -0
  275. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/compaction.py +0 -0
  276. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/kg_packets.py +0 -0
  277. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/memact_composer.py +0 -0
  278. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/recall_levels.py +0 -0
  279. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/memory/token_budget.py +0 -0
  280. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/rendering/__init__.py +0 -0
  281. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/rendering/agent_trace_report.py +0 -0
  282. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/rendering/json_stringify.py +0 -0
  283. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/scheduler/__init__.py +0 -0
  284. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/scheduler/convenience.py +0 -0
  285. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/scheduler/multi_store.py +0 -0
  286. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/scheduler/registry.py +0 -0
  287. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/scheduler/scheduler.py +0 -0
  288. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/session_history.py +0 -0
  289. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/session_turns.py +0 -0
  290. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/__init__.py +0 -0
  291. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/artifacts.py +0 -0
  292. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/base.py +0 -0
  293. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/commands.py +0 -0
  294. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/in_memory.py +0 -0
  295. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/json_files.py +0 -0
  296. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/lease.py +0 -0
  297. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/ledger_chain.py +0 -0
  298. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/ledger_slim.py +0 -0
  299. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/observable.py +0 -0
  300. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/offloading.py +0 -0
  301. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/serialize.py +0 -0
  302. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/snapshots.py +0 -0
  303. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/sqlite.py +0 -0
  304. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/storage/steer_sidecar.py +0 -0
  305. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/triggers/__init__.py +0 -0
  306. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/triggers/email_received.py +0 -0
  307. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/triggers/manual.py +0 -0
  308. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/triggers/protocol.py +0 -0
  309. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/triggers/registry.py +0 -0
  310. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/triggers/schedule.py +0 -0
  311. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/turn_grounding.py +0 -0
  312. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/utils/__init__.py +0 -0
  313. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/utils/atomic_files.py +0 -0
  314. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/utils/file_filters.py +0 -0
  315. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/__init__.py +0 -0
  316. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/__init__.py +0 -0
  317. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/agent_adapter.py +0 -0
  318. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/context_adapter.py +0 -0
  319. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/control_adapter.py +0 -0
  320. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/effect_adapter.py +0 -0
  321. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/event_adapter.py +0 -0
  322. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/function_adapter.py +0 -0
  323. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/memact_adapter.py +0 -0
  324. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/subflow_adapter.py +0 -0
  325. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/adapters/variable_adapter.py +0 -0
  326. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/flow.py +0 -0
  327. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/__init__.py +0 -0
  328. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/agent_ids.py +0 -0
  329. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/builtins.py +0 -0
  330. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/code_executor.py +0 -0
  331. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/execution_metrics.py +0 -0
  332. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/executor.py +0 -0
  333. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/function_library.py +0 -0
  334. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/models.py +0 -0
  335. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/multi_entry_lowering.py +0 -0
  336. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/visualflow_compiler/visual/pin_expressions.py +0 -0
  337. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/workflow_bundle/__init__.py +0 -0
  338. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/workflow_bundle/models.py +0 -0
  339. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/workflow_bundle/packer.py +0 -0
  340. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/workflow_bundle/reader.py +0 -0
  341. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/src/abstractruntime/workflow_bundle/registry.py +0 -0
  342. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/README.md +0 -0
  343. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/automation_harness.py +0 -0
  344. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/conftest.py +0 -0
  345. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/email_wp2_support.py +0 -0
  346. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/live_email/conftest.py +0 -0
  347. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/live_email/live_email_support.py +0 -0
  348. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/live_email/test_email_live_runtime.py +0 -0
  349. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_abstractcore_comms_facade.py +0 -0
  350. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_abstractcore_discovery_facade.py +0 -0
  351. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_abstractcore_host_facade.py +0 -0
  352. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_abstractcore_run_facade.py +0 -0
  353. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_abstractcore_telegram_facade.py +0 -0
  354. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_active_context_policy.py +0 -0
  355. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_active_memory.py +0 -0
  356. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_agora_agent_alias_identity.py +0 -0
  357. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_agora_tools_http.py +0 -0
  358. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_analyze_media_addressing_and_walling.py +0 -0
  359. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_answer_user_effect.py +0 -0
  360. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_artifacts.py +0 -0
  361. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_controller.py +0 -0
  362. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_controller_recovery.py +0 -0
  363. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_definition.py +0 -0
  364. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_discussion_isolation.py +0 -0
  365. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_email_results.py +0 -0
  366. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_growing_context.py +0 -0
  367. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_index.py +0 -0
  368. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_next_fire.py +0 -0
  369. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_occurrence_recovery.py +0 -0
  370. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_replay_read_only.py +0 -0
  371. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_retry.py +0 -0
  372. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_session_turns.py +0 -0
  373. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_automation_status.py +0 -0
  374. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_browser_probe_target_walling.py +0 -0
  375. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_budget_law_no_unrequested_caps.py +0 -0
  376. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_capability_default_reasoning.py +0 -0
  377. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_chat_summarizer_integration.py +0 -0
  378. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_code_node_restricted_python.py +0 -0
  379. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_command_store.py +0 -0
  380. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_compaction_helpers.py +0 -0
  381. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_compaction_summarizer_route.py +0 -0
  382. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_config_facade_models_engines.py +0 -0
  383. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_control_adapter_while.py +0 -0
  384. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_controller_bundle_packaged.py +0 -0
  385. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_crash_ordering_inversions.py +0 -0
  386. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_create_if_absent.py +0 -0
  387. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_data_registry_facade.py +0 -0
  388. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_default_tools_camera_gating.py +0 -0
  389. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_default_tools_comms_gating.py +0 -0
  390. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_default_tools_include_skim_files.py +0 -0
  391. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_default_tools_include_skim_folders.py +0 -0
  392. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_default_tools_include_skim_web.py +0 -0
  393. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_default_tools_search_files_executor.py +0 -0
  394. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_diary_capture.py +0 -0
  395. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_diary_write_rescue.py +0 -0
  396. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_directory_lease.py +0 -0
  397. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_disabled_toolsets_seam.py +0 -0
  398. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_discovery_survives_unbuildable_default.py +0 -0
  399. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_discovery_tts_unavailable_reason.py +0 -0
  400. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_discovery_voice_openai_api_key.py +0 -0
  401. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_discussion_session_anchor.py +0 -0
  402. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_document_markdown_tables.py +0 -0
  403. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_document_renderers_hr_quote.py +0 -0
  404. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_durable_toolsets.py +0 -0
  405. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_durable_write_discipline.py +0 -0
  406. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_e2e_tool_calls_idempotency_lmstudio.py +0 -0
  407. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_effect_cancellation.py +0 -0
  408. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_effect_issuance_idempotency.py +0 -0
  409. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_effect_payload_stays_json_serializable.py +0 -0
  410. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_election_consequence_teaching.py +0 -0
  411. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_email_binding_and_refiner.py +0 -0
  412. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_email_gate_fixes.py +0 -0
  413. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_email_inbox_and_trigger.py +0 -0
  414. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_email_regate_fixes.py +0 -0
  415. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_email_review_fixes.py +0 -0
  416. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_email_self_trigger_loop.py +0 -0
  417. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_email_toolset_and_walls.py +0 -0
  418. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_emergence_experiment.py +0 -0
  419. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_emit_event_uses_wait_index.py +0 -0
  420. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_emit_event_without_workflow_registry.py +0 -0
  421. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_endpoint_profile_route_context.py +0 -0
  422. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_awake_memory_fixes.py +0 -0
  423. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_brain_effects.py +0 -0
  424. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_chat_driver.py +0 -0
  425. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_chat_tools_reflection.py +0 -0
  426. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_diary.py +0 -0
  427. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_execute_tool.py +0 -0
  428. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_fetch_url_tool.py +0 -0
  429. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_history_window.py +0 -0
  430. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_life_loop.py +0 -0
  431. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_memory_richness.py +0 -0
  432. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_phase_graph_conformance.py +0 -0
  433. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_react_visit_window.py +0 -0
  434. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_recent_memories.py +0 -0
  435. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_runtime.py +0 -0
  436. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_search_memory.py +0 -0
  437. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_sleep_bound_and_yield_attribution.py +0 -0
  438. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_substrate_resolution.py +0 -0
  439. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_visit_honesty.py +0 -0
  440. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_workspace_cap.py +0 -0
  441. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_entity_workspace_tools.py +0 -0
  442. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_event_wait_index.py +0 -0
  443. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_every_path_bearing_tool_is_walled.py +0 -0
  444. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_evidence_recorder.py +0 -0
  445. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_evidence_recorder_post_policy_envelope.py +0 -0
  446. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_execute_command_output_offload.py +0 -0
  447. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_execution_capability_discovery.py +0 -0
  448. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_explicit_eject_other_clients.py +0 -0
  449. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_factory_default_retry_policy.py +0 -0
  450. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_factory_timeouts_default_to_abstractcore_config.py +0 -0
  451. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_format_repair_nudge.py +0 -0
  452. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_fresh_install_no_provider.py +0 -0
  453. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_gateway_facades_c4899.py +0 -0
  454. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_git_read_only_refiner.py +0 -0
  455. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_hf_process_residency_merge.py +0 -0
  456. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_history_window_multimodal.py +0 -0
  457. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_hot_path_store_reads.py +0 -0
  458. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_indexed_idempotency_lookup.py +0 -0
  459. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_integration_abstractcore.py +0 -0
  460. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_integrations_abstractcore.py +0 -0
  461. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_json_file_run_store_children_index.py +0 -0
  462. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_json_run_cache_bound.py +0 -0
  463. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_json_store_scan_memo.py +0 -0
  464. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_jsonl_ledger_recovery.py +0 -0
  465. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_kg_learn_and_recall_contract.py +0 -0
  466. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_ledger_chain.py +0 -0
  467. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_ledger_record_slimming.py +0 -0
  468. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_ledger_subscription.py +0 -0
  469. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_live_token_deltas.py +0 -0
  470. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_media_artifact_refs.py +0 -0
  471. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_media_artifact_refs_persist_across_restart.py +0 -0
  472. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_media_uses_source_path_label.py +0 -0
  473. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_payload_shape_refusal.py +0 -0
  474. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_requires_prompt.py +0 -0
  475. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_response_schema_normalization.py +0 -0
  476. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_structured_output_fallback.py +0 -0
  477. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_text_phase_progress.py +0 -0
  478. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_truncation_retry_contract.py +0 -0
  479. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_use_context_appends_turn.py +0 -0
  480. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_call_verbatim_payload_capture.py +0 -0
  481. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_client_grounding_tail.py +0 -0
  482. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_client_media_artifacts.py +0 -0
  483. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_client_system_context.py +0 -0
  484. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_client_tool_call_parsing.py +0 -0
  485. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_retry_classification.py +0 -0
  486. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_llm_streaming_on_token.py +0 -0
  487. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_local_helper_tool_exposure.py +0 -0
  488. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_local_residency_host_sweep.py +0 -0
  489. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_local_runtime_timeout_kwarg_policy.py +0 -0
  490. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_max_iterations_ceiling.py +0 -0
  491. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_mcp_remote_tool_executor.py +0 -0
  492. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_mcp_runs_untrusted_and_facade.py +0 -0
  493. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_mcp_worker_logging.py +0 -0
  494. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_mcp_worker_security.py +0 -0
  495. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_mcp_worker_stdio.py +0 -0
  496. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_media_artifact_resolution.py +0 -0
  497. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_media_capability_default_routing.py +0 -0
  498. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_media_only_requests_skip_text_client.py +0 -0
  499. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_media_subprocess.py +0 -0
  500. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memact_composer_from_kg_result.py +0 -0
  501. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_appraise_handler.py +0 -0
  502. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_communities.py +0 -0
  503. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_kg_assert_attributes_defaults.py +0 -0
  504. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_kg_packets.py +0 -0
  505. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_kg_predicate_aliasing.py +0 -0
  506. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_kg_query_packetization_restart.py +0 -0
  507. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_kg_query_recall_level_policy.py +0 -0
  508. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_kg_semantic_query_ranking.py +0 -0
  509. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_note_effect.py +0 -0
  510. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_query_effect.py +0 -0
  511. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_query_rich_filters.py +0 -0
  512. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_scope_and_rehydrate_effect.py +0 -0
  513. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_seam_handlers.py +0 -0
  514. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_seam_sqlite_durability.py +0 -0
  515. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_memory_tag_effect.py +0 -0
  516. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_mlx_generation_serialization.py +0 -0
  517. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_mlx_process_residency_merge.py +0 -0
  518. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_model_eject_cancel.py +0 -0
  519. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_model_residency_clean_switch.py +0 -0
  520. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_model_residency_control_plane.py +0 -0
  521. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_model_residency_lock_and_context_estimate.py +0 -0
  522. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_multi_store_scheduler.py +0 -0
  523. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_multimodal_abstractcore_integration.py +0 -0
  524. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_native_mlx_application_wiring.py +0 -0
  525. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_native_mlx_execution_controls_live.py +0 -0
  526. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_native_tool_channel.py +0 -0
  527. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_night_voice.py +0 -0
  528. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_no_default_provider_refusal_ux.py +0 -0
  529. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_offload_answer_chain_c4978.py +0 -0
  530. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_offloaded_node_traces_report_unknown_not_zero.py +0 -0
  531. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_offloading.py +0 -0
  532. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_parallel_readonly_tool_execution.py +0 -0
  533. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_pause_resume.py +0 -0
  534. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_pdf_unicode_rendering.py +0 -0
  535. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_personal_cycle.py +0 -0
  536. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_phantom_attachment_index.py +0 -0
  537. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_phase_graph_artifact_control.py +0 -0
  538. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_phase_graph_obedience.py +0 -0
  539. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_phase_vocabulary_migration.py +0 -0
  540. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_pooled_client_strips_construction_cache_key.py +0 -0
  541. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_prompt_cache_export_import.py +0 -0
  542. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_prompt_cache_fingerprint_stability.py +0 -0
  543. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_prompt_cache_modules.py +0 -0
  544. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_prompt_cache_posture_inheritance.py +0 -0
  545. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_prompt_cache_thinking_and_prompt_only.py +0 -0
  546. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_prompt_overlay.py +0 -0
  547. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_provider_endpoint_profile_resolution.py +0 -0
  548. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_provider_pin_routing_isolation.py +0 -0
  549. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_queryable_run_store.py +0 -0
  550. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_read_file_fallback_to_session_attachments.py +0 -0
  551. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_read_idle_threading.py +0 -0
  552. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_readoption_experiment.py +0 -0
  553. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_real_integration.py +0 -0
  554. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_realize_election.py +0 -0
  555. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_recall_levels_policy.py +0 -0
  556. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_remote_client_cancel.py +0 -0
  557. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_remote_llm_client.py +0 -0
  558. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_remote_speculation_defaults.py +0 -0
  559. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_rendering_agent_trace_report.py +0 -0
  560. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_rendering_json_stringify.py +0 -0
  561. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_report_branding.py +0 -0
  562. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_resident_media_generation.py +0 -0
  563. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_resume_concurrent_same_wait.py +0 -0
  564. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_retry_idempotency.py +0 -0
  565. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_run_history_bundle.py +0 -0
  566. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_run_index_workspace_root.py +0 -0
  567. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_run_mutation_lock.py +0 -0
  568. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_run_scoped_tool_policy.py +0 -0
  569. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_run_tool_scope_ceiling.py +0 -0
  570. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_browser_session_boundary.py +0 -0
  571. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_config_max_output_tokens_fallback.py +0 -0
  572. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_default_provider_model_refresh.py +0 -0
  573. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_effect_invocation_trace.py +0 -0
  574. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_health_and_bounded_vars.py +0 -0
  575. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_install_boundary.py +0 -0
  576. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_llm_call_grounding_in_ledger.py +0 -0
  577. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_node_traces.py +0 -0
  578. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_start_seeds_tool_support.py +0 -0
  579. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_runtime_tick_step_gate.py +0 -0
  580. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_scheduler.py +0 -0
  581. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_send_email_refiner.py +0 -0
  582. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_send_email_self_default_policy.py +0 -0
  583. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_session_attachments_registry_and_open_tool.py +0 -0
  584. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_session_history.py +0 -0
  585. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_session_prompt_cache_attribution.py +0 -0
  586. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_session_prompt_cache_visibility.py +0 -0
  587. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_session_route_stamp.py +0 -0
  588. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_session_start_cost.py +0 -0
  589. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_snapshots.py +0 -0
  590. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_speculation_inheritance.py +0 -0
  591. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_speculation_reaches_provider_construction.py +0 -0
  592. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_sqlite_ledger_store.py +0 -0
  593. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_start_subworkflow_async_wait.py +0 -0
  594. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_start_subworkflow_inherit_context_merges_messages.py +0 -0
  595. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_start_subworkflow_workspace_inheritance.py +0 -0
  596. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_steer_sidecar.py +0 -0
  597. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_storage_deletion.py +0 -0
  598. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_structured_output_schema_enum.py +0 -0
  599. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_subworkflow.py +0 -0
  600. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_terminal_effect_completion.py +0 -0
  601. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_terminal_resume_appends_ledger_completion.py +0 -0
  602. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_thinking_inheritance.py +0 -0
  603. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tick_completion_includes_output_in_ledger.py +0 -0
  604. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_approval_executor.py +0 -0
  605. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_approval_resume_executes.py +0 -0
  606. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_approval_wait_key_identity.py +0 -0
  607. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_calls_idempotency_keys.py +0 -0
  608. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_catalog.py +0 -0
  609. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_descriptor_registry.py +0 -0
  610. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_executor_argument_sanitization.py +0 -0
  611. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_executor_error_output_detection.py +0 -0
  612. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_executor_filename_alias.py +0 -0
  613. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_executor_kwarg_canonicalization.py +0 -0
  614. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_executor_read_file_aliases.py +0 -0
  615. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_executor_timeout.py +0 -0
  616. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_inventory_facade.py +0 -0
  617. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_invoke_effect.py +0 -0
  618. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_policy_and_mounts.py +0 -0
  619. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_tool_wait_allowlist_safety.py +0 -0
  620. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_topic_election_world_model.py +0 -0
  621. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_trace_context_propagation.py +0 -0
  622. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_trigger_registry.py +0 -0
  623. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_trigger_schedule_math.py +0 -0
  624. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_turn_grounding_byte_stability.py +0 -0
  625. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_turn_grounding_carriers_a3.py +0 -0
  626. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_vars_query_effect.py +0 -0
  627. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visit_ab_fixture.py +0 -0
  628. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visit_midturn_elections.py +0 -0
  629. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visit_midturn_resume.py +0 -0
  630. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visit_workflow.py +0 -0
  631. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_agent_output_context_includes_messages.py +0 -0
  632. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_agent_skills_block_passthrough.py +0 -0
  633. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_agent_tool_observations_persist_across_restart.py +0 -0
  634. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_agent_use_context_inherits_attachments.py +0 -0
  635. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_agent_use_context_persists_tool_observations.py +0 -0
  636. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_agent_use_context_persists_turn.py +0 -0
  637. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_entity_memory_nodes.py +0 -0
  638. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_flow_end_effect_only_persistence.py +0 -0
  639. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_llm_call_partial_override.py +0 -0
  640. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_llm_call_schema_ref_resolution.py +0 -0
  641. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_memact_compose_node.py +0 -0
  642. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_memory_kg_query_outputs_propagate.py +0 -0
  643. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_memory_kg_resolve_outputs_propagate.py +0 -0
  644. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_multi_entry_loop_overrides.py +0 -0
  645. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_unknown_node_type_refuses.py +0 -0
  646. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visual_wait_event_deadline_passthrough.py +0 -0
  647. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_add_message_builtin.py +0 -0
  648. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_add_message_node_appends_to_active_context.py +0 -0
  649. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_agora_react_agent.py +0 -0
  650. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_call_tool_node.py +0 -0
  651. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_capability_routes_and_thinking.py +0 -0
  652. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_compiler_basic.py +0 -0
  653. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_context_and_builder_nodes.py +0 -0
  654. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_continue_on_error.py +0 -0
  655. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_edit_json_schema_node.py +0 -0
  656. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_event_inbox_react_agent.py +0 -0
  657. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_file_nodes_workspace.py +0 -0
  658. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_function_library.py +0 -0
  659. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_get_element_node.py +0 -0
  660. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_get_random_element_node.py +0 -0
  661. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_get_var_node.py +0 -0
  662. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_has_tools_builtin.py +0 -0
  663. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_llm_call_context_attachments_map_to_media.py +0 -0
  664. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_llm_call_multimodal_output.py +0 -0
  665. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_make_object_node.py +0 -0
  666. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_media_nodes.py +0 -0
  667. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_memory_effect_nodes.py +0 -0
  668. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_memory_source_pins.py +0 -0
  669. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_pin_expressions.py +0 -0
  670. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_prompt_only.py +0 -0
  671. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_random_nodes.py +0 -0
  672. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_schema_enum_switch.py +0 -0
  673. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_string_contains_replace.py +0 -0
  674. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_visualflow_tool_parameters_node.py +0 -0
  675. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_voice_openai_api_key_path.py +0 -0
  676. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_w4_feelings_lens.py +0 -0
  677. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_wait_event_deadline.py +0 -0
  678. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_wait_event_prompt_metadata.py +0 -0
  679. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_wait_until_streak.py +0 -0
  680. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_wait_until_utc_normalization.py +0 -0
  681. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workflow_bundle_registry.py +0 -0
  682. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workspace_builtin_deny.py +0 -0
  683. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workspace_policy_absolute_reanchor.py +0 -0
  684. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workspace_policy_allowlist_mode.py +0 -0
  685. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workspace_policy_mount_virtual_paths.py +0 -0
  686. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workspace_policy_tool_calls_persist_across_restart.py +0 -0
  687. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workspace_prompt_context.py +0 -0
  688. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_workspace_read_only.py +0 -0
  689. {abstractruntime-0.8.4 → abstractruntime-0.9.0}/tests/test_write_chart.py +0 -0
@@ -69,6 +69,59 @@ jobs:
69
69
  tests/test_trigger_registry.py \
70
70
  tests/test_workspace_read_only.py
71
71
 
72
+ # The command sandbox end to end on Linux: run vars -> TOOL_CALLS handler ->
73
+ # `_sandbox` stamp -> AbstractCore's spawning tools inside bubblewrap. The
74
+ # end-to-end tests in tests/test_r12_workspace_sandbox.py skip with their
75
+ # reason on a host without an OS sandbox, so the job above proves nothing
76
+ # about Linux. This job installs bubblewrap, lets it create user namespaces
77
+ # (Ubuntu 24.04 restricts them through AppArmor by default), and FAILS unless
78
+ # every sandbox test ran and passed: a skip here is a red job, never a green one.
79
+ linux-sandbox:
80
+ name: Linux command sandbox (bubblewrap)
81
+ runs-on: ubuntu-latest
82
+ steps:
83
+ - uses: actions/checkout@v4
84
+ - uses: actions/setup-python@v5
85
+ with:
86
+ python-version: "3.12"
87
+ cache: pip
88
+ - name: Install bubblewrap
89
+ run: |
90
+ sudo apt-get update
91
+ sudo apt-get install -y bubblewrap
92
+ # bwrap is not setuid on Ubuntu: it needs unprivileged user namespaces.
93
+ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
94
+ bwrap --version
95
+ bwrap --ro-bind / / --dev /dev --proc /proc -- /bin/true
96
+ uname -r
97
+ - name: Install
98
+ run: |
99
+ python -m pip install -U pip
100
+ python -m pip install -e ".[test]"
101
+ - name: Pytest (sandbox tests must run, not skip)
102
+ run: |
103
+ python -m pytest -rs -p no:cacheprovider \
104
+ tests/test_r12_workspace_sandbox.py tests/test_command_sandbox_host_facade.py \
105
+ --junitxml=sandbox-junit.xml
106
+ - name: Assert the sandbox tests ran
107
+ run: |
108
+ python - <<'PY'
109
+ import sys
110
+ import xml.etree.ElementTree as ET
111
+
112
+ cases = list(ET.parse("sandbox-junit.xml").getroot().iter("testcase"))
113
+ skipped = [c for c in cases if c.find("skipped") is not None]
114
+ failed = [c for c in cases if c.find("failure") is not None or c.find("error") is not None]
115
+ e2e = [c for c in cases if (c.get("name") or "").startswith("test_e2e_")]
116
+ e2e_passed = [c for c in e2e if c not in skipped and c not in failed]
117
+ passed = len(cases) - len(skipped) - len(failed)
118
+ print(f"sandbox tests: {len(cases)} collected, {passed} passed, {len(skipped)} skipped, {len(failed)} failed; end-to-end passed {len(e2e_passed)}/{len(e2e)}")
119
+ for c in skipped:
120
+ print("SKIPPED:", c.get("name"), "-", (c.find("skipped").get("message") or ""))
121
+ if len(e2e) < 7 or len(e2e_passed) != len(e2e) or skipped or failed:
122
+ sys.exit("The sandbox tests did not all run and pass inside bubblewrap on this Linux host.")
123
+ PY
124
+
72
125
  build:
73
126
  name: Build distributions
74
127
  runs-on: ubuntu-latest
@@ -5,9 +5,35 @@ All notable changes to AbstractRuntime will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [0.9.0] - 2026-10-05
9
9
 
10
- Nothing yet.
10
+ ### Added
11
+
12
+ - `Runtime.set_occurrence_input_resolver(fn)`: a host hook called at each automation occurrence's admission, as `fn(definition, input_data) -> input_data`. Its answer is frozen into the occurrence's prepared inputs, so replays stay byte-identical; a non-dict answer fails the admission; with no resolver set nothing changes. AbstractGateway uses it to resolve the workspaces of an automation that follows its owner's default at each run, instead of a snapshot taken at save time. Test: `tests/test_automation_occurrence_input_resolver.py`.
13
+
14
+ - Command sandbox: `execute_command`, `shell_exec`, `local_helper_start` and AbstractAgent's `execute_python` (0.3.18 or newer; an older one fails on the unknown argument and runs nothing) receive the run's effective workspace set as the hidden `_sandbox` argument (`sandbox_stamp(scope)`, built on every call from the same workspace vars the file tools read; `execute_python` starts in the stamp's private workspace; a model- or payload-supplied `_sandbox` is always replaced or dropped), and run inside AbstractCore's OS sandbox (`abstractcore.tools.sandbox`: macOS `sandbox-exec`, Linux `bwrap` or Landlock). `local_helper_start` and the entity exec tool apply it themselves (the entity's workspace and whitelisted mounts). With no sandbox on the host, or an AbstractCore without the sandbox module, the call is refused with one sentence before anything runs and the run continues.
15
+
16
+ - `integrations.abstractcore.command_sandbox_host`: hosts configure the command sandbox through the runtime (`configure_host`, `host_policy`, `host_sandbox_kind`, `KIND_LABELS`, `KIND_NONE`, `reset_host_for_tests`; pure re-exports of `abstractcore.tools.sandbox`), so a host never imports AbstractCore directly. Used by AbstractGateway's `serve`.
17
+ - `MappingToolExecutor` never drops the `_sandbox` stamp: a tool whose signature cannot take it (an AbstractAgent older than 0.3.18) gets a failed result naming the stamp and does not run. Its argument-name normalization never maps a model key (`sandbox`, `registry_namespace`, ...) onto a hidden `_`-prefixed parameter.
18
+ - CI: a `linux-sandbox` job installs bubblewrap on Ubuntu and runs the command-sandbox tests end to end inside it (the end-to-end tests now run inside the host's OS sandbox: macOS `sandbox-exec` or Linux bubblewrap); the job fails when any of them is skipped.
19
+ - `workspace_writable_paths`: writable exceptions inside read-only roots (`workspace_read_only_paths`), the more specific rule winning. The tool scope, `path_is_read_only` and VisualFlow writers honour them; child runs and file nodes inherit the parent's exactly and never add one. Used by AbstractGateway 0.13.0 for "Allow everything, refuse listed workspaces" with a read-only default.
20
+ - `integrations.abstractcore.structured_facade` (also flat from `integrations.abstractcore`): `parse_response_format` and AbstractCore's own `ResponseFormatError`, so hosts check an OpenAI `response_format` without importing AbstractCore. Used by AbstractGateway 0.13.0's `/v1/chat/completions`.
21
+ - Workspace context of a tool-using `LLM_CALL`: after the default working directory (the run's own workspace), `Allowed workspaces:` lists each allowed workspace outside it with its mode (`(read-only)` / `(read & write)`, from `workspace_read_only_paths` and `workspace_writable_paths`), and under `all_except_ignored` `Everything else: (…)`; refused paths are never listed as allowed. Used by AbstractGateway 0.13.0 on every run start.
22
+ - `automation.unarchive`: an archived automation comes back paused with its history intact; a controller that ended because it was archived restarts and parks on its wake wait (observation `automation.unarchived`).
23
+
24
+ ### Changed
25
+
26
+ - Workspace nesting: the most specific row wins. Among `workspace_root`, `workspace_allowed_paths` and `workspace_ignored_paths`, the longest real-path prefix of a path decides (a refusal wins a tie); a refused folder no longer refuses an allowed workspace inside it, and a refused folder inside an allowed one still refuses its subtree. Built-in protection stays absolute. Same rule as AbstractGateway's validation and the sandbox profile.
27
+ - The workspace context now says "Shell commands run inside an OS sandbox limited to these workspaces." and describes refused paths as "Excluded paths (a more specific allowed workspace inside one stays reachable)".
28
+ - Requires AbstractCore 2.25.0 or newer (`abstractcore>=2.25.0` in the base install and the `[apple]`/`[gpu]` extras): the command sandbox and `structured_facade` use it.
29
+
30
+ ### Removed
31
+
32
+ - `workspace_shared_path` / `SHARED_WORKSPACE_KEY` / `shared_workspace_path` (added during 0.9.0 development, never released): AbstractGateway 0.13.0 has no shared workspace any more (round 11), so the workspace context names no "Shared workspace"; the allowed workspaces and their modes are listed as before. A stale key in a run's vars is ignored.
33
+
34
+ ## [0.8.5] - 2026-10-03
35
+
36
+ - Hosts can serve AbstractCore ASGI requests through `integrations.abstractcore.server_facade.serve_core_request`, with independent request-scoped authentication preserved throughout streaming. Requires AbstractCore 2.24.0 or newer.
11
37
 
12
38
  ## [0.8.4] - 2026-10-02
13
39
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: AbstractRuntime
3
- Version: 0.8.4
3
+ Version: 0.9.0
4
4
  Summary: AbstractRuntime: a durable graph runner designed to pair with AbstractCore.
5
5
  Project-URL: AbstractCore (website), https://www.abstractcore.ai/
6
6
  Project-URL: AbstractRuntime (GitHub), https://github.com/lpalbou/abstractruntime
@@ -20,7 +20,7 @@ Classifier: Programming Language :: Python :: 3.11
20
20
  Classifier: Programming Language :: Python :: 3.12
21
21
  Classifier: Programming Language :: Python :: 3.13
22
22
  Requires-Python: >=3.10
23
- Requires-Dist: abstractcore>=2.20.2
23
+ Requires-Dist: abstractcore>=2.25.0
24
24
  Requires-Dist: abstractmemory>=0.3.0
25
25
  Requires-Dist: abstractsemantics>=0.0.5
26
26
  Requires-Dist: anyio<5.0.0,>=4.12.1
@@ -35,14 +35,14 @@ Requires-Dist: reportlab<5.0.0,>=4.0.0
35
35
  Requires-Dist: restrictedpython>=7.0
36
36
  Requires-Dist: unstructured[docx,odt,pptx,rtf,xlsx]<0.19.0,>=0.18.32
37
37
  Provides-Extra: apple
38
- Requires-Dist: abstractcore[apple]>=2.20.2; extra == 'apple'
38
+ Requires-Dist: abstractcore[apple]>=2.25.0; extra == 'apple'
39
39
  Requires-Dist: setuptools<82.0.0,>=80.10.2; extra == 'apple'
40
40
  Provides-Extra: docs
41
41
  Requires-Dist: mkdocs-material>=9.0.0; extra == 'docs'
42
42
  Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
43
43
  Requires-Dist: pymdown-extensions>=10.0; extra == 'docs'
44
44
  Provides-Extra: gpu
45
- Requires-Dist: abstractcore[gpu]>=2.20.2; extra == 'gpu'
45
+ Requires-Dist: abstractcore[gpu]>=2.25.0; extra == 'gpu'
46
46
  Requires-Dist: setuptools<82.0.0,>=77.0.3; extra == 'gpu'
47
47
  Provides-Extra: test
48
48
  Requires-Dist: aiosmtpd<2.0.0,>=1.4.4; extra == 'test'
@@ -83,7 +83,7 @@ Remote-light runtime:
83
83
  pip install abstractruntime
84
84
  ```
85
85
 
86
- The base install includes AbstractCore 2.20.2 or newer (its light install:
86
+ The base install includes AbstractCore 2.24.0 or newer (its light install:
87
87
  remote providers, tools, vision, voice, audio, and music integration), plus the
88
88
  `abstractruntime-mcp-worker` entry point. It keeps inference remote/light by
89
89
  default: local engines such as MLX, vLLM, HuggingFace/Torch, Diffusers, and
@@ -32,7 +32,7 @@ Remote-light runtime:
32
32
  pip install abstractruntime
33
33
  ```
34
34
 
35
- The base install includes AbstractCore 2.20.2 or newer (its light install:
35
+ The base install includes AbstractCore 2.24.0 or newer (its light install:
36
36
  remote providers, tools, vision, voice, audio, and music integration), plus the
37
37
  `abstractruntime-mcp-worker` entry point. It keeps inference remote/light by
38
38
  default: local engines such as MLX, vLLM, HuggingFace/Torch, Diffusers, and
@@ -26,7 +26,7 @@ In this repo, the AbstractCore wiring lives under `src/abstractruntime/integrati
26
26
  - `faq.md` — common questions (recommended)
27
27
  - `manual_testing.md` — manual smoke tests and how to run the test suite
28
28
  - `artifacts.md` — Runtime artifact identity, descriptors, provenance, catalog search, and access stats
29
- - `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
29
+ - `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, the `structured_facade` response_format check for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
30
30
  - `tools-comms.md` — enabling the optional comms toolset (email/WhatsApp/Telegram)
31
31
  - `email.md` — email for each user: run-scoped account binding and the host resolver, sending without asking (self and pre-authorised recipients), the durable event inbox and mail feeder, the `email.received@1` trigger, and the send-email action
32
32
  - `tool-approval.md` — tool risk tiers, the run-policy rank ceiling, and per-call refiners (the `send_email` recipient rule: self and pre-authorised recipients)
@@ -221,7 +221,7 @@ Deep dive: [automations.md](automations.md).
221
221
 
222
222
  ```python
223
223
  from abstractruntime.automations import (
224
- apply_automation_command, # pause / resume / run_now / revise / stop_current / archive
224
+ apply_automation_command, # pause / resume / run_now / revise / stop_current / archive / unarchive
225
225
  create_automation, # -> (automation_id, revision)
226
226
  drive_automation, # standalone run loop
227
227
  get_automation,
@@ -262,6 +262,7 @@ from abstractruntime.email import (
262
262
 
263
263
  - `Runtime.set_email_context_resolver(fn)`: `fn(binding, *, use) -> EmailContext | None` (`use` is `"agent_tool"` or `"action"`; `fn(binding)` also accepted), per runtime, memory only
264
264
  - `Runtime.set_email_binding(binding | None)` / `Runtime.email_binding`: the account occurrences are bound to
265
+ - `Runtime.set_occurrence_input_resolver(fn | None)` / `Runtime.occurrence_input_resolver`: `fn(definition, input_data) -> input_data`, called at each automation occurrence's admission (its run start) and frozen with the occurrence's inputs (a replayed dispatch stays identical); a non-dict answer fails the admission. The gateway re-resolves an automation's "Use my default" workspaces here. None (default): the definition's inputs as stored
265
266
  - `Runtime.set_event_inbox(inbox)` / `Runtime.event_inbox`: required by `email.received@1`
266
267
  - `EmailInboxFeeder(inbox, account_ref=...).poll(ctx, *, now=None, force=False) -> PollReport` and `.status()`
267
268
  - toolsets: `get_default_toolsets(..., email_enabled=True)` (also `list_default_tool_specs`, `build_default_tool_map`, `list_tool_catalog`); no env flag; `list_tool_catalog(email_enabled=False, email_off_reason="not_connected" | "admin_disabled" | "not_available" | "agent_tools_off")`
@@ -269,6 +270,7 @@ from abstractruntime.email import (
269
270
  - approval: the `send_email_recipient@v2` refiner ([tool-approval.md](tool-approval.md#per-call-refiners))
270
271
  - `adopt_legacy_schedule_projection(run)`: read-only summary of a legacy gateway `scheduled:*` root
271
272
  - read-only mounts: `_runtime.workspace_read_only_paths` (absolute folders; file write tools and VisualFlow writers refused inside, reads and command/code tools allowed); helpers `read_only_paths(vars)`, `path_is_read_only(vars, path)` and `READ_ONLY_PATHS_KEY` in `abstractruntime.utils.workspace_paths`
273
+ - writable exceptions inside read-only roots: `workspace_writable_paths` (top-level or `_runtime`; absolute folders). A path is read-only when a read-only root contains it and no writable path inside that root contains it, so the more specific rule wins (a host sets `/` read-only plus the run's folder and its read & write folders for a read-only default). Child runs and VisualFlow file nodes get the parent's exceptions exactly; a child never adds one. Helpers: `writable_paths(vars)`, `is_read_only_target(path, read_only_roots, writable_roots)`, `WRITABLE_PATHS_KEY`.
272
274
  - read-only workspaces: run vars `workspace_read_only: true` (or `_runtime.workspace_read_only: true`); `abstractruntime.integrations.abstractcore.tool_effects.TOOL_EFFECT_CLASSES` classifies every exposable tool as `read`, `write`, `exec`, `delegate`, `comms` or `memory-write`
273
275
 
274
276
  ## Sessions and history
@@ -302,7 +304,7 @@ from Core route resolution and persisted from `LLM_CALL` results.
302
304
 
303
305
  ### AbstractCore (LLM + tools)
304
306
 
305
- Requires: `pip install abstractruntime` (AbstractCore 2.20.2 or newer is part of the base install).
307
+ Requires: `pip install abstractruntime` (AbstractCore 2.24.0 or newer is part of the base install).
306
308
 
307
309
  Implementation: `src/abstractruntime/integrations/abstractcore/*`.
308
310
 
@@ -391,3 +393,11 @@ This provides handlers for `MEMORY_KG_*` effects (opt-in wiring layer).
391
393
  - `architecture.md` — component map + durability invariants
392
394
  - `faq.md` — common questions and gotchas
393
395
  - `integrations/abstractcore.md` — `LLM_CALL` / `TOOL_CALLS` wiring
396
+
397
+ ### Host ASGI serving
398
+
399
+ `abstractruntime.integrations.abstractcore.server_facade.serve_core_request(scope, receive, send, *, token: str, allow_unauthenticated: bool = False)` delegates host-admitted ASGI requests with request-scoped Core authentication. See [host-managed serving](integrations/abstractcore.md#host-managed-serving) for network and credential responsibilities.
400
+
401
+ ### Structured-output checks
402
+
403
+ `abstractruntime.integrations.abstractcore.structured_facade.parse_response_format(raw) -> (kind, schema, name)` checks an OpenAI `response_format` and raises `ResponseFormatError` (AbstractCore's own class, with `.param`) for an unusable one. Both are also exported flat from `abstractruntime.integrations.abstractcore`. Requires AbstractCore 2.25.0 or newer. See [structured-output checks for hosts](integrations/abstractcore.md#structured-output-checks-for-hosts-structured-facade).
@@ -34,7 +34,7 @@ sources), `abstractruntime.automation_queries` (listing), `abstractruntime.sessi
34
34
  ```mermaid
35
35
  flowchart LR
36
36
  Trigger["Trigger source<br/>schedule@1 / manual@1"] -->|"due tick or run now"| Controller["Controller run<br/>(automation id)<br/>vars._meta.automation<br/>vars._runtime.automation"]
37
- Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive"] -->|"decision + wake"| Controller
37
+ Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive / unarchive"] -->|"decision + wake"| Controller
38
38
  Controller -->|"START_SUBWORKFLOW<br/>deterministic run_id"| Occurrence["Occurrence run<br/>role: occurrence<br/>(a session turn)"]
39
39
  Occurrence --> Descendants["Descendant runs<br/>role: descendant"]
40
40
  Occurrence -->|"output: answer, notify"| Controller
@@ -292,6 +292,7 @@ expected_revision=None, now=None)` is the only way to change an automation. It r
292
292
  | `automation.revise` | `payload.changes = {title?, target?, trigger?, context?, policy?}` (at least one). `title`, `target`, `trigger` and `context` are replaced whole; `policy` fields are merged, so a field you do not send keeps its value. The next revision applies from the controller's next step. A changed trigger gets a new binding and is re-armed after now, so no past tick fires; an unchanged trigger keeps its binding. | `invalid_state` when archived or finished; the definition's own reason codes for invalid changes |
293
293
  | `automation.stop_current` | Cancels the running occurrence tree, or its pending retry. The occurrence completes as `cancelled`, quietly. | `invalid_state` when nothing is running |
294
294
  | `automation.archive` | Stops further admissions; the current occurrence finishes and the controller then ends. History is kept and the automation stays listed. Archiving twice is an applied no-op. | — |
295
+ | `automation.unarchive` | Lifts the archive mark and brings the automation back **paused** (send `automation.resume` to re-arm its trigger). A controller that ended because it was archived restarts at `read_definition` and parks on its wake wait; occurrences, ledger and history are untouched. An exhausted or failed automation only loses the archive mark and keeps its status. Unarchiving an automation that is not archived is an applied no-op. | — |
295
296
 
296
297
  Every command can also be rejected with:
297
298
 
@@ -305,7 +306,7 @@ Commands are idempotent per `command_id`. A `command_id` is tied to its whole co
305
306
  `expected_revision`). The `automation.command_result` record, keyed
306
307
  `automation:command_result:<automation_id>:<command_id>`, is the decision. Sending the same command again returns the
307
308
  recorded result with `duplicate: true` and repeats only the follow-ups that are safe to repeat: the observation
308
- record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`), waking the
309
+ record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`, `automation.unarchived`), waking the
309
310
  controller, and cancelling the stopped child. A host that fails to carry out a command itself records the failure
310
311
  with `record_automation_command_result(...)`, passing the same `payload` and `expected_revision` so a later replay is
311
312
  recognized.
@@ -51,7 +51,9 @@ Docs: `getting-started.md`. Code: `src/abstractruntime/core/runtime.py`, `src/ab
51
51
  Create an automation. An automation is a durable controller run that starts the target workflow as a child run (an
52
52
  occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`) or `manual@1` (run now only).
53
53
  `create_automation(...)` creates it, `apply_automation_command(...)` pauses, resumes, runs now, edits, stops the
54
- current occurrence or archives it, and the host drives it like any run (`drive_automation` does this in-process).
54
+ current occurrence, archives it or unarchives it (it comes back paused with its history), and the host drives it
55
+ like any run (`drive_automation` does this in-process). Nothing is deleted: an archived automation keeps its
56
+ occurrences and history and stays listed with status `archived`.
55
57
 
56
58
  The `Scheduler` is different: it is a driver loop that resumes due waits of existing runs. It does not create runs.
57
59
 
@@ -97,9 +99,9 @@ Docs: `automations.md#tool-approval`, `automations.md#waits-on-a-person`.
97
99
 
98
100
  Not through its file tools. A discussion works in its own writable workspace and sees the automation's workspace as
99
101
  a read-only mount (`_runtime.workspace_read_only_paths`): file tools and VisualFlow writers that target a path inside
100
- the mount are refused, reads work. Commands and code (`execute_command`, `execute_python`) are allowed, because the
101
- shell cannot be sandboxed; a command can therefore still change files if it chooses to, so keep tool approval on for
102
- commands where that matters. Every later turn in the discussion session keeps the same setup, whoever starts it, and
102
+ the mount are refused, reads work. Commands and code (`execute_command`, `shell_exec`, `local_helper_start`,
103
+ AbstractAgent's `execute_python`) run inside an OS sandbox built from the same workspaces (macOS `sandbox-exec`, Linux
104
+ `bwrap`/Landlock), so they cannot write into the mount either; on a host with no sandbox they are refused. Every later turn in the discussion session keeps the same setup, whoever starts it, and
103
105
  the discussion never writes back into the automation's session, state or ledger.
104
106
 
105
107
  Docs: `automations.md#discussions`, `automations.md#read-only-mounts`.
@@ -12,7 +12,7 @@ Remote-light runtime:
12
12
  pip install abstractruntime
13
13
  ```
14
14
 
15
- This installs AbstractCore 2.20.2 or newer with remote provider, vision,
15
+ This installs AbstractCore 2.24.0 or newer with remote provider, vision,
16
16
  voice, audio, music, tool, and MCP-worker support. The base install is
17
17
  remote-light: it can route multimodal workflows to hosted or OpenAI-compatible
18
18
  endpoints, but it does not select local inferencer stacks such as MLX, vLLM,
@@ -16,7 +16,7 @@ Implementation pointers (this repo):
16
16
  pip install abstractruntime
17
17
  ```
18
18
 
19
- The base install includes AbstractCore 2.20.0 or newer. That is the supported baseline for the current server auth split (`Authorization` for server auth, `X-AbstractCore-Provider-API-Key` for provider overrides), generated-media contracts, image upscaling, capability catalog, prompt-cache control-plane endpoints (including session attribution via `/acore/prompt_cache/key_meta`), host memory snapshots, the host-wide loaded-model sweep used by residency listings, the process-wide MLX residency report and eject used by model unload, durable bloc prompt-cache helpers, bindings and lifecycle operations, task-aware model residency for text/image/video/TTS/STT, current tool catalog, AbstractCore's public output-selector contract, async/sync text-generation output-selector parity, video generation endpoints, the public local vision-cache catalog helper used by Runtime discovery, vision adapter discovery plus batch/LoRA media controls, and the released shared workspace/file-filter utility surface used by Runtime packaging and integration checks.
19
+ The base install includes AbstractCore 2.24.0 or newer. That is the supported baseline for the current server auth split (`Authorization` for server auth, `X-AbstractCore-Provider-API-Key` for provider overrides), generated-media contracts, image upscaling, capability catalog, prompt-cache control-plane endpoints (including session attribution via `/acore/prompt_cache/key_meta`), host memory snapshots, the host-wide loaded-model sweep used by residency listings, the process-wide MLX residency report and eject used by model unload, durable bloc prompt-cache helpers, bindings and lifecycle operations, task-aware model residency for text/image/video/TTS/STT, current tool catalog, AbstractCore's public output-selector contract, async/sync text-generation output-selector parity, video generation endpoints, the public local vision-cache catalog helper used by Runtime discovery, vision adapter discovery plus batch/LoRA media controls, and the released shared workspace/file-filter utility surface used by Runtime packaging and integration checks.
20
20
 
21
21
  The base install also includes the remote-light media/capability plugins needed
22
22
  for AbstractCore's multimodal `generate(..., output=...)` path. Local
@@ -494,16 +494,18 @@ When a run sets `workspace_root` in its vars, file tools (`read_file`, `write_fi
494
494
  | --- | --- |
495
495
  | `workspace_root` | Base folder for relative paths and the shell's starting folder. Relative roots resolve against `ABSTRACT_WORKSPACE_BASE_DIR` when set. |
496
496
  | `workspace_access_mode` | `workspace_only` (default: paths stay under the root), `workspace_or_allowed` (also under `workspace_allowed_paths`), or `all_except_ignored` (anywhere except `workspace_ignored_paths`). |
497
- | `workspace_allowed_paths` | Extra folders a `workspace_or_allowed` run may use. |
498
- | `workspace_ignored_paths` | The operator's exclusions; always refused. |
497
+ | `workspace_allowed_paths` | Additional workspaces a `workspace_or_allowed` run may use. |
498
+ | `workspace_ignored_paths` | Refused workspaces. A more specific allowed workspace inside one stays reachable (see *Nesting* below). |
499
499
  | `workspace_builtin_deny_prefixes` | The host's own protected folders (for example a gateway's data folder and credential folders), as path prefixes. Anything under one is refused. |
500
500
  | `workspace_builtin_allow` | Exceptions inside the host's protected folders (for example the run's own folder inside the data folder). The operator's `workspace_ignored_paths` still win over them. |
501
+ | `workspace_read_only_paths` / `workspace_writable_paths` | Read-only roots and the writable exceptions inside them (`"/"` = a read-only default). The more specific rule wins. |
501
502
 
502
503
  Lists accept a JSON array, a JSON array pasted as a string, or newline-separated entries.
503
504
 
504
- - When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root, the access mode, the authorized roots and the operator's `workspace_ignored_paths`. The host's built-in deny prefixes and allow entries are enforced but never described to the model, so the system prompt stays identical from turn to turn while the host's folders change, and the prompt cache stays warm. A refused path is reported as `Path is not accessible (protected by the host)` without listing the host's rules.
505
- - Child runs (subworkflows and agent delegation) inherit all six vars unless they set their own; VisualFlow file and document nodes (`read_file`, `write_file`, `read_pdf`, `write_pdf`, `write_docx`, `write_chart`) apply the same scope.
506
- - Shell tools are pinned to their starting folder only. A command can still reach other paths (`cd ..`, absolute paths); the workspace scope is a file-tool policy, not a sandbox.
505
+ - When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root (the run's default working directory); each allowed workspace outside the root with its mode (`(read-only)` or `(read & write)`, from `workspace_read_only_paths` and `workspace_writable_paths`); under `all_except_ignored` the mode of everything else (`Everything else: (read-only)`); the access mode; the authorized roots and the operator's `workspace_ignored_paths`. The host's built-in deny prefixes and allow entries are enforced but never described to the model, so the system prompt stays identical from turn to turn while the host's folders change, and the prompt cache stays warm. A refused path is reported as `Path is not accessible (protected by the host)` without listing the host's rules.
506
+ - Child runs (subworkflows and agent delegation) inherit the workspace vars unless they set their own; VisualFlow file and document nodes (`read_file`, `write_file`, `read_pdf`, `write_pdf`, `write_docx`, `write_chart`) apply the same scope.
507
+ - **Nesting (most specific row wins).** For a path P (symlinks resolved), the candidates are `workspace_root` (read & write), `workspace_allowed_paths` (not under `workspace_only`) and `workspace_ignored_paths`. The longest candidate that contains P decides: a refused entry refuses, the root or an allowed entry allows; a tie between a refused entry and an allowed one (or the root) at the same path refuses; no candidate falls back to the access mode (`all_except_ignored` allows, the others refuse). The host's built-in protection is absolute: under a `workspace_builtin_deny_prefixes` entry and not under a `workspace_builtin_allow` entry is refused whatever the rows say. So refusing `/Users/me` and allowing `/Users/me/project` makes the project reachable and the rest of `/Users/me` refused; a refused folder inside an allowed one refuses that subtree. AbstractGateway applies the same rule when it validates and computes a run's workspaces.
508
+ - **Command sandbox.** `execute_command`, `shell_exec` (the whole persistent session), `local_helper_start` and AbstractAgent's `execute_python` (0.3.18 or newer) start in the workspace and run inside an OS sandbox built from the SAME scope (`sandbox_stamp(scope)`, stamped on every call as the hidden `_sandbox` argument; a model- or payload-supplied value is always replaced). AbstractCore (`abstractcore.tools.sandbox`) applies it: macOS `sandbox-exec`, Linux `bwrap`, or Linux Landlock for "Deny everything, allow listed workspaces". Mapping: `all_except_ignored` → "Allow everything, refuse listed workspaces" (`any_except_denied`), otherwise "Deny everything, allow listed workspaces" (`allowed_only`); a `"/"` read-only root → read-only default; each allowed workspace with its mode; refused paths and the built-in protection as they are. The command string is never parsed — `cd ..`, absolute paths, `$(…)`, symlinks and scripts are stopped by the kernel. With no sandbox on the host, or an AbstractCore without `abstractcore.tools.sandbox`, the command is refused with one sentence and the run continues. The entity exec tool runs inside a sandbox limited to the entity's workspace and its whitelisted mounts. The tool result carries `sandbox: {kind, …}` and a `Sandbox: …` line; the stamp rides the tool call in the run's evidence. Hosts set the host policy (the scrubbed environment commands start from, and whether unsandboxed commands are allowed on a host with no sandbox) once at boot through `abstractruntime.integrations.abstractcore.command_sandbox_host` (`configure_host`, `host_policy`, `host_sandbox_kind`), never by importing AbstractCore.
507
509
 
508
510
  ## Prompt-cache control plane and durable blocs
509
511
 
@@ -1168,3 +1170,34 @@ This is useful when building a `MappingToolExecutor` quickly.
1168
1170
  - `../architecture.md` — effect handler boundaries and durability invariants
1169
1171
  - `../tools-comms.md` — enabling email/WhatsApp/Telegram tools
1170
1172
  - `../adr/0002_execution_modes_local_remote_hybrid.md` — rationale for local/remote/hybrid
1173
+
1174
+ ## Host-managed serving
1175
+
1176
+ Hosts that expose AbstractCore serving routes use
1177
+ `abstractruntime.integrations.abstractcore.server_facade.serve_core_request(scope, receive, send, *, token, allow_unauthenticated=False)`.
1178
+ The facade lazily loads the Core ASGI application and keeps the host's independent
1179
+ inbound authentication policy scoped to the entire response, including streamed
1180
+ bodies. Concurrent requests retain separate policies; cancellation and exceptions
1181
+ restore the previous policy.
1182
+
1183
+ The host owns route admission, network exposure, origin checks, and token storage.
1184
+ Provide a nonempty token even for open access: absent Authorization is allowed when
1185
+ `allow_unauthenticated=True`, while any supplied Authorization must validate.
1186
+ Anonymous callers cannot use server-held cloud credentials; explicit provider
1187
+ keys use `X-AbstractCore-Provider-API-Key`. This serving facade does not create
1188
+ durable Runtime runs. The AbstractCore server dependencies must be installed.
1189
+
1190
+ ## Structured-output checks for hosts (structured facade)
1191
+
1192
+ A host that accepts an OpenAI `response_format` checks it before any model sees it with
1193
+ `abstractruntime.integrations.abstractcore.structured_facade` (also exported flat from
1194
+ `abstractruntime.integrations.abstractcore`):
1195
+
1196
+ - `parse_response_format(raw)` returns `(kind, schema, name)`, where kind is `"text"`,
1197
+ `"json_object"` or `"json_schema"` and schema is `None` unless kind is `"json_schema"`.
1198
+ - `ResponseFormatError` is AbstractCore's own error class, so `except ResponseFormatError`
1199
+ catches exactly what Core raises; `.param` names the offending field
1200
+ (`"response_format"` or a nested name such as `"response_format.type"`).
1201
+
1202
+ AbstractCore is imported on first use; it needs AbstractCore 2.25.0 or newer. AbstractGateway's
1203
+ `/v1/chat/completions` uses this facade, so the gateway never imports AbstractCore itself.
@@ -81,7 +81,7 @@ Remote-light runtime:
81
81
  pip install abstractruntime
82
82
  ```
83
83
 
84
- The base install includes AbstractCore 2.20.2 or newer (its light install:
84
+ The base install includes AbstractCore 2.24.0 or newer (its light install:
85
85
  remote providers, tools, vision, voice, audio, and music integration), plus the
86
86
  `abstractruntime-mcp-worker` entry point. It keeps inference remote/light by
87
87
  default: local engines such as MLX, vLLM, HuggingFace/Torch, Diffusers, and
@@ -287,7 +287,7 @@ Remote-light runtime:
287
287
  pip install abstractruntime
288
288
  ```
289
289
 
290
- This installs AbstractCore 2.20.2 or newer with remote provider, vision,
290
+ This installs AbstractCore 2.24.0 or newer with remote provider, vision,
291
291
  voice, audio, music, tool, and MCP-worker support. The base install is
292
292
  remote-light: it can route multimodal workflows to hosted or OpenAI-compatible
293
293
  endpoints, but it does not select local inferencer stacks such as MLX, vLLM,
@@ -1086,7 +1086,7 @@ Deep dive: [automations.md](automations.md).
1086
1086
 
1087
1087
  ```python
1088
1088
  from abstractruntime.automations import (
1089
- apply_automation_command, # pause / resume / run_now / revise / stop_current / archive
1089
+ apply_automation_command, # pause / resume / run_now / revise / stop_current / archive / unarchive
1090
1090
  create_automation, # -> (automation_id, revision)
1091
1091
  drive_automation, # standalone run loop
1092
1092
  get_automation,
@@ -1127,6 +1127,7 @@ from abstractruntime.email import (
1127
1127
 
1128
1128
  - `Runtime.set_email_context_resolver(fn)`: `fn(binding, *, use) -> EmailContext | None` (`use` is `"agent_tool"` or `"action"`; `fn(binding)` also accepted), per runtime, memory only
1129
1129
  - `Runtime.set_email_binding(binding | None)` / `Runtime.email_binding`: the account occurrences are bound to
1130
+ - `Runtime.set_occurrence_input_resolver(fn | None)` / `Runtime.occurrence_input_resolver`: `fn(definition, input_data) -> input_data`, called at each automation occurrence's admission (its run start) and frozen with the occurrence's inputs (a replayed dispatch stays identical); a non-dict answer fails the admission. The gateway re-resolves an automation's "Use my default" workspaces here. None (default): the definition's inputs as stored
1130
1131
  - `Runtime.set_event_inbox(inbox)` / `Runtime.event_inbox`: required by `email.received@1`
1131
1132
  - `EmailInboxFeeder(inbox, account_ref=...).poll(ctx, *, now=None, force=False) -> PollReport` and `.status()`
1132
1133
  - toolsets: `get_default_toolsets(..., email_enabled=True)` (also `list_default_tool_specs`, `build_default_tool_map`, `list_tool_catalog`); no env flag; `list_tool_catalog(email_enabled=False, email_off_reason="not_connected" | "admin_disabled" | "not_available" | "agent_tools_off")`
@@ -1134,6 +1135,7 @@ from abstractruntime.email import (
1134
1135
  - approval: the `send_email_recipient@v2` refiner ([tool-approval.md](tool-approval.md#per-call-refiners))
1135
1136
  - `adopt_legacy_schedule_projection(run)`: read-only summary of a legacy gateway `scheduled:*` root
1136
1137
  - read-only mounts: `_runtime.workspace_read_only_paths` (absolute folders; file write tools and VisualFlow writers refused inside, reads and command/code tools allowed); helpers `read_only_paths(vars)`, `path_is_read_only(vars, path)` and `READ_ONLY_PATHS_KEY` in `abstractruntime.utils.workspace_paths`
1138
+ - writable exceptions inside read-only roots: `workspace_writable_paths` (top-level or `_runtime`; absolute folders). A path is read-only when a read-only root contains it and no writable path inside that root contains it, so the more specific rule wins (a host sets `/` read-only plus the run's folder and its read & write folders for a read-only default). Child runs and VisualFlow file nodes get the parent's exceptions exactly; a child never adds one. Helpers: `writable_paths(vars)`, `is_read_only_target(path, read_only_roots, writable_roots)`, `WRITABLE_PATHS_KEY`.
1137
1139
  - read-only workspaces: run vars `workspace_read_only: true` (or `_runtime.workspace_read_only: true`); `abstractruntime.integrations.abstractcore.tool_effects.TOOL_EFFECT_CLASSES` classifies every exposable tool as `read`, `write`, `exec`, `delegate`, `comms` or `memory-write`
1138
1140
 
1139
1141
  ## Sessions and history
@@ -1167,7 +1169,7 @@ from Core route resolution and persisted from `LLM_CALL` results.
1167
1169
 
1168
1170
  ### AbstractCore (LLM + tools)
1169
1171
 
1170
- Requires: `pip install abstractruntime` (AbstractCore 2.20.2 or newer is part of the base install).
1172
+ Requires: `pip install abstractruntime` (AbstractCore 2.24.0 or newer is part of the base install).
1171
1173
 
1172
1174
  Implementation: `src/abstractruntime/integrations/abstractcore/*`.
1173
1175
 
@@ -1257,6 +1259,14 @@ This provides handlers for `MEMORY_KG_*` effects (opt-in wiring layer).
1257
1259
  - `faq.md` — common questions and gotchas
1258
1260
  - `integrations/abstractcore.md` — `LLM_CALL` / `TOOL_CALLS` wiring
1259
1261
 
1262
+ ### Host ASGI serving
1263
+
1264
+ `abstractruntime.integrations.abstractcore.server_facade.serve_core_request(scope, receive, send, *, token: str, allow_unauthenticated: bool = False)` delegates host-admitted ASGI requests with request-scoped Core authentication. See [host-managed serving](integrations/abstractcore.md#host-managed-serving) for network and credential responsibilities.
1265
+
1266
+ ### Structured-output checks
1267
+
1268
+ `abstractruntime.integrations.abstractcore.structured_facade.parse_response_format(raw) -> (kind, schema, name)` checks an OpenAI `response_format` and raises `ResponseFormatError` (AbstractCore's own class, with `.param`) for an unusable one. Both are also exported flat from `abstractruntime.integrations.abstractcore`. Requires AbstractCore 2.25.0 or newer. See [structured-output checks for hosts](integrations/abstractcore.md#structured-output-checks-for-hosts-structured-facade).
1269
+
1260
1270
 
1261
1271
  ==============================================================================
1262
1272
  # FILE: docs/faq.md
@@ -1315,7 +1325,9 @@ Docs: `getting-started.md`. Code: `src/abstractruntime/core/runtime.py`, `src/ab
1315
1325
  Create an automation. An automation is a durable controller run that starts the target workflow as a child run (an
1316
1326
  occurrence) on each trigger: `schedule@1` (fixed UTC intervals such as `5m` or `24h`) or `manual@1` (run now only).
1317
1327
  `create_automation(...)` creates it, `apply_automation_command(...)` pauses, resumes, runs now, edits, stops the
1318
- current occurrence or archives it, and the host drives it like any run (`drive_automation` does this in-process).
1328
+ current occurrence, archives it or unarchives it (it comes back paused with its history), and the host drives it
1329
+ like any run (`drive_automation` does this in-process). Nothing is deleted: an archived automation keeps its
1330
+ occurrences and history and stays listed with status `archived`.
1319
1331
 
1320
1332
  The `Scheduler` is different: it is a driver loop that resumes due waits of existing runs. It does not create runs.
1321
1333
 
@@ -1361,9 +1373,9 @@ Docs: `automations.md#tool-approval`, `automations.md#waits-on-a-person`.
1361
1373
 
1362
1374
  Not through its file tools. A discussion works in its own writable workspace and sees the automation's workspace as
1363
1375
  a read-only mount (`_runtime.workspace_read_only_paths`): file tools and VisualFlow writers that target a path inside
1364
- the mount are refused, reads work. Commands and code (`execute_command`, `execute_python`) are allowed, because the
1365
- shell cannot be sandboxed; a command can therefore still change files if it chooses to, so keep tool approval on for
1366
- commands where that matters. Every later turn in the discussion session keeps the same setup, whoever starts it, and
1376
+ the mount are refused, reads work. Commands and code (`execute_command`, `shell_exec`, `local_helper_start`,
1377
+ AbstractAgent's `execute_python`) run inside an OS sandbox built from the same workspaces (macOS `sandbox-exec`, Linux
1378
+ `bwrap`/Landlock), so they cannot write into the mount either; on a host with no sandbox they are refused. Every later turn in the discussion session keeps the same setup, whoever starts it, and
1367
1379
  the discussion never writes back into the automation's session, state or ledger.
1368
1380
 
1369
1381
  Docs: `automations.md#discussions`, `automations.md#read-only-mounts`.
@@ -1978,7 +1990,7 @@ Implementation pointers (this repo):
1978
1990
  pip install abstractruntime
1979
1991
  ```
1980
1992
 
1981
- The base install includes AbstractCore 2.20.0 or newer. That is the supported baseline for the current server auth split (`Authorization` for server auth, `X-AbstractCore-Provider-API-Key` for provider overrides), generated-media contracts, image upscaling, capability catalog, prompt-cache control-plane endpoints (including session attribution via `/acore/prompt_cache/key_meta`), host memory snapshots, the host-wide loaded-model sweep used by residency listings, the process-wide MLX residency report and eject used by model unload, durable bloc prompt-cache helpers, bindings and lifecycle operations, task-aware model residency for text/image/video/TTS/STT, current tool catalog, AbstractCore's public output-selector contract, async/sync text-generation output-selector parity, video generation endpoints, the public local vision-cache catalog helper used by Runtime discovery, vision adapter discovery plus batch/LoRA media controls, and the released shared workspace/file-filter utility surface used by Runtime packaging and integration checks.
1993
+ The base install includes AbstractCore 2.24.0 or newer. That is the supported baseline for the current server auth split (`Authorization` for server auth, `X-AbstractCore-Provider-API-Key` for provider overrides), generated-media contracts, image upscaling, capability catalog, prompt-cache control-plane endpoints (including session attribution via `/acore/prompt_cache/key_meta`), host memory snapshots, the host-wide loaded-model sweep used by residency listings, the process-wide MLX residency report and eject used by model unload, durable bloc prompt-cache helpers, bindings and lifecycle operations, task-aware model residency for text/image/video/TTS/STT, current tool catalog, AbstractCore's public output-selector contract, async/sync text-generation output-selector parity, video generation endpoints, the public local vision-cache catalog helper used by Runtime discovery, vision adapter discovery plus batch/LoRA media controls, and the released shared workspace/file-filter utility surface used by Runtime packaging and integration checks.
1982
1994
 
1983
1995
  The base install also includes the remote-light media/capability plugins needed
1984
1996
  for AbstractCore's multimodal `generate(..., output=...)` path. Local
@@ -2456,16 +2468,18 @@ When a run sets `workspace_root` in its vars, file tools (`read_file`, `write_fi
2456
2468
  | --- | --- |
2457
2469
  | `workspace_root` | Base folder for relative paths and the shell's starting folder. Relative roots resolve against `ABSTRACT_WORKSPACE_BASE_DIR` when set. |
2458
2470
  | `workspace_access_mode` | `workspace_only` (default: paths stay under the root), `workspace_or_allowed` (also under `workspace_allowed_paths`), or `all_except_ignored` (anywhere except `workspace_ignored_paths`). |
2459
- | `workspace_allowed_paths` | Extra folders a `workspace_or_allowed` run may use. |
2460
- | `workspace_ignored_paths` | The operator's exclusions; always refused. |
2471
+ | `workspace_allowed_paths` | Additional workspaces a `workspace_or_allowed` run may use. |
2472
+ | `workspace_ignored_paths` | Refused workspaces. A more specific allowed workspace inside one stays reachable (see *Nesting* below). |
2461
2473
  | `workspace_builtin_deny_prefixes` | The host's own protected folders (for example a gateway's data folder and credential folders), as path prefixes. Anything under one is refused. |
2462
2474
  | `workspace_builtin_allow` | Exceptions inside the host's protected folders (for example the run's own folder inside the data folder). The operator's `workspace_ignored_paths` still win over them. |
2475
+ | `workspace_read_only_paths` / `workspace_writable_paths` | Read-only roots and the writable exceptions inside them (`"/"` = a read-only default). The more specific rule wins. |
2463
2476
 
2464
2477
  Lists accept a JSON array, a JSON array pasted as a string, or newline-separated entries.
2465
2478
 
2466
- - When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root, the access mode, the authorized roots and the operator's `workspace_ignored_paths`. The host's built-in deny prefixes and allow entries are enforced but never described to the model, so the system prompt stays identical from turn to turn while the host's folders change, and the prompt cache stays warm. A refused path is reported as `Path is not accessible (protected by the host)` without listing the host's rules.
2467
- - Child runs (subworkflows and agent delegation) inherit all six vars unless they set their own; VisualFlow file and document nodes (`read_file`, `write_file`, `read_pdf`, `write_pdf`, `write_docx`, `write_chart`) apply the same scope.
2468
- - Shell tools are pinned to their starting folder only. A command can still reach other paths (`cd ..`, absolute paths); the workspace scope is a file-tool policy, not a sandbox.
2479
+ - When an `LLM_CALL` offers tools and the run has a workspace scope, the runtime appends a short description of the scope to the system prompt: the root (the run's default working directory); each allowed workspace outside the root with its mode (`(read-only)` or `(read & write)`, from `workspace_read_only_paths` and `workspace_writable_paths`); under `all_except_ignored` the mode of everything else (`Everything else: (read-only)`); the access mode; the authorized roots and the operator's `workspace_ignored_paths`. The host's built-in deny prefixes and allow entries are enforced but never described to the model, so the system prompt stays identical from turn to turn while the host's folders change, and the prompt cache stays warm. A refused path is reported as `Path is not accessible (protected by the host)` without listing the host's rules.
2480
+ - Child runs (subworkflows and agent delegation) inherit the workspace vars unless they set their own; VisualFlow file and document nodes (`read_file`, `write_file`, `read_pdf`, `write_pdf`, `write_docx`, `write_chart`) apply the same scope.
2481
+ - **Nesting (most specific row wins).** For a path P (symlinks resolved), the candidates are `workspace_root` (read & write), `workspace_allowed_paths` (not under `workspace_only`) and `workspace_ignored_paths`. The longest candidate that contains P decides: a refused entry refuses, the root or an allowed entry allows; a tie between a refused entry and an allowed one (or the root) at the same path refuses; no candidate falls back to the access mode (`all_except_ignored` allows, the others refuse). The host's built-in protection is absolute: under a `workspace_builtin_deny_prefixes` entry and not under a `workspace_builtin_allow` entry is refused whatever the rows say. So refusing `/Users/me` and allowing `/Users/me/project` makes the project reachable and the rest of `/Users/me` refused; a refused folder inside an allowed one refuses that subtree. AbstractGateway applies the same rule when it validates and computes a run's workspaces.
2482
+ - **Command sandbox.** `execute_command`, `shell_exec` (the whole persistent session), `local_helper_start` and AbstractAgent's `execute_python` (0.3.18 or newer) start in the workspace and run inside an OS sandbox built from the SAME scope (`sandbox_stamp(scope)`, stamped on every call as the hidden `_sandbox` argument; a model- or payload-supplied value is always replaced). AbstractCore (`abstractcore.tools.sandbox`) applies it: macOS `sandbox-exec`, Linux `bwrap`, or Linux Landlock for "Deny everything, allow listed workspaces". Mapping: `all_except_ignored` → "Allow everything, refuse listed workspaces" (`any_except_denied`), otherwise "Deny everything, allow listed workspaces" (`allowed_only`); a `"/"` read-only root → read-only default; each allowed workspace with its mode; refused paths and the built-in protection as they are. The command string is never parsed — `cd ..`, absolute paths, `$(…)`, symlinks and scripts are stopped by the kernel. With no sandbox on the host, or an AbstractCore without `abstractcore.tools.sandbox`, the command is refused with one sentence and the run continues. The entity exec tool runs inside a sandbox limited to the entity's workspace and its whitelisted mounts. The tool result carries `sandbox: {kind, …}` and a `Sandbox: …` line; the stamp rides the tool call in the run's evidence. Hosts set the host policy (the scrubbed environment commands start from, and whether unsandboxed commands are allowed on a host with no sandbox) once at boot through `abstractruntime.integrations.abstractcore.command_sandbox_host` (`configure_host`, `host_policy`, `host_sandbox_kind`), never by importing AbstractCore.
2469
2483
 
2470
2484
  ## Prompt-cache control plane and durable blocs
2471
2485
 
@@ -3131,6 +3145,37 @@ This is useful when building a `MappingToolExecutor` quickly.
3131
3145
  - `../tools-comms.md` — enabling email/WhatsApp/Telegram tools
3132
3146
  - `../adr/0002_execution_modes_local_remote_hybrid.md` — rationale for local/remote/hybrid
3133
3147
 
3148
+ ## Host-managed serving
3149
+
3150
+ Hosts that expose AbstractCore serving routes use
3151
+ `abstractruntime.integrations.abstractcore.server_facade.serve_core_request(scope, receive, send, *, token, allow_unauthenticated=False)`.
3152
+ The facade lazily loads the Core ASGI application and keeps the host's independent
3153
+ inbound authentication policy scoped to the entire response, including streamed
3154
+ bodies. Concurrent requests retain separate policies; cancellation and exceptions
3155
+ restore the previous policy.
3156
+
3157
+ The host owns route admission, network exposure, origin checks, and token storage.
3158
+ Provide a nonempty token even for open access: absent Authorization is allowed when
3159
+ `allow_unauthenticated=True`, while any supplied Authorization must validate.
3160
+ Anonymous callers cannot use server-held cloud credentials; explicit provider
3161
+ keys use `X-AbstractCore-Provider-API-Key`. This serving facade does not create
3162
+ durable Runtime runs. The AbstractCore server dependencies must be installed.
3163
+
3164
+ ## Structured-output checks for hosts (structured facade)
3165
+
3166
+ A host that accepts an OpenAI `response_format` checks it before any model sees it with
3167
+ `abstractruntime.integrations.abstractcore.structured_facade` (also exported flat from
3168
+ `abstractruntime.integrations.abstractcore`):
3169
+
3170
+ - `parse_response_format(raw)` returns `(kind, schema, name)`, where kind is `"text"`,
3171
+ `"json_object"` or `"json_schema"` and schema is `None` unless kind is `"json_schema"`.
3172
+ - `ResponseFormatError` is AbstractCore's own error class, so `except ResponseFormatError`
3173
+ catches exactly what Core raises; `.param` names the offending field
3174
+ (`"response_format"` or a nested name such as `"response_format.type"`).
3175
+
3176
+ AbstractCore is imported on first use; it needs AbstractCore 2.25.0 or newer. AbstractGateway's
3177
+ `/v1/chat/completions` uses this facade, so the gateway never imports AbstractCore itself.
3178
+
3134
3179
 
3135
3180
  ==============================================================================
3136
3181
  # FILE: docs/proposal.md
@@ -3555,7 +3600,7 @@ sources), `abstractruntime.automation_queries` (listing), `abstractruntime.sessi
3555
3600
  ```mermaid
3556
3601
  flowchart LR
3557
3602
  Trigger["Trigger source<br/>schedule@1 / manual@1"] -->|"due tick or run now"| Controller["Controller run<br/>(automation id)<br/>vars._meta.automation<br/>vars._runtime.automation"]
3558
- Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive"] -->|"decision + wake"| Controller
3603
+ Commands["apply_automation_command<br/>pause / resume / run_now /<br/>revise / stop_current / archive / unarchive"] -->|"decision + wake"| Controller
3559
3604
  Controller -->|"START_SUBWORKFLOW<br/>deterministic run_id"| Occurrence["Occurrence run<br/>role: occurrence<br/>(a session turn)"]
3560
3605
  Occurrence --> Descendants["Descendant runs<br/>role: descendant"]
3561
3606
  Occurrence -->|"output: answer, notify"| Controller
@@ -3813,6 +3858,7 @@ expected_revision=None, now=None)` is the only way to change an automation. It r
3813
3858
  | `automation.revise` | `payload.changes = {title?, target?, trigger?, context?, policy?}` (at least one). `title`, `target`, `trigger` and `context` are replaced whole; `policy` fields are merged, so a field you do not send keeps its value. The next revision applies from the controller's next step. A changed trigger gets a new binding and is re-armed after now, so no past tick fires; an unchanged trigger keeps its binding. | `invalid_state` when archived or finished; the definition's own reason codes for invalid changes |
3814
3859
  | `automation.stop_current` | Cancels the running occurrence tree, or its pending retry. The occurrence completes as `cancelled`, quietly. | `invalid_state` when nothing is running |
3815
3860
  | `automation.archive` | Stops further admissions; the current occurrence finishes and the controller then ends. History is kept and the automation stays listed. Archiving twice is an applied no-op. | — |
3861
+ | `automation.unarchive` | Lifts the archive mark and brings the automation back **paused** (send `automation.resume` to re-arm its trigger). A controller that ended because it was archived restarts at `read_definition` and parks on its wake wait; occurrences, ledger and history are untouched. An exhausted or failed automation only loses the archive mark and keeps its status. Unarchiving an automation that is not archived is an applied no-op. | — |
3816
3862
 
3817
3863
  Every command can also be rejected with:
3818
3864
 
@@ -3826,7 +3872,7 @@ Commands are idempotent per `command_id`. A `command_id` is tied to its whole co
3826
3872
  `expected_revision`). The `automation.command_result` record, keyed
3827
3873
  `automation:command_result:<automation_id>:<command_id>`, is the decision. Sending the same command again returns the
3828
3874
  recorded result with `duplicate: true` and repeats only the follow-ups that are safe to repeat: the observation
3829
- record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`), waking the
3875
+ record (`automation.paused`, `automation.resumed`, `automation.revised`, `automation.archived`, `automation.unarchived`), waking the
3830
3876
  controller, and cancelling the stopped child. A host that fails to carry out a command itself records the failure
3831
3877
  with `record_automation_command_result(...)`, passing the same `payload` and `expected_revision` so a later replay is
3832
3878
  recognized.
@@ -5831,7 +5877,7 @@ In this repo, the AbstractCore wiring lives under `src/abstractruntime/integrati
5831
5877
  - `faq.md` — common questions (recommended)
5832
5878
  - `manual_testing.md` — manual smoke tests and how to run the test suite
5833
5879
  - `artifacts.md` — Runtime artifact identity, descriptors, provenance, catalog search, and access stats
5834
- - `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
5880
+ - `integrations/abstractcore.md` — wiring `LLM_CALL` / `TOOL_CALLS`, the `config_facade` models/engines/host-jobs passthroughs for hosts, the `structured_facade` response_format check for hosts, cached sessions with per-session prompt-cache listing/clearing, host memory snapshots, model-residency listings, locks and model switching, live token streaming, workspace-scoped tools, durable bloc prompt-cache control, media inputs, generated media outputs, video progress events, and tool approval waits via AbstractCore
5835
5881
  - `tools-comms.md` — enabling the optional comms toolset (email/WhatsApp/Telegram)
5836
5882
  - `email.md` — email for each user: run-scoped account binding and the host resolver, sending without asking (self and pre-authorised recipients), the durable event inbox and mail feeder, the `email.received@1` trigger, and the send-email action
5837
5883
  - `tool-approval.md` — tool risk tiers, the run-policy rank ceiling, and per-call refiners (the `send_email` recipient rule: self and pre-authorised recipients)