phronomy 0.27.0 → 0.29.0

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 (517) hide show
  1. checksums.yaml +4 -4
  2. data/.mutant.yml +9 -9
  3. data/CHANGELOG.md +52 -0
  4. data/CONTRIBUTING.md +8 -8
  5. data/README.md +28 -7
  6. data/benchmark/bench_agent_invoke.rb +25 -50
  7. data/benchmark/bench_context_assembler.rb +14 -11
  8. data/benchmark/bench_regression.rb +1 -1
  9. data/benchmark/bench_tool_schema.rb +1 -1
  10. data/docs/application-recipes.md +229 -0
  11. data/docs/architecture/agent-chat-and-state-ownership.md +7 -1
  12. data/docs/architecture/agent-transition-ownership.md +13 -89
  13. data/docs/architecture/backend-groups.md +152 -0
  14. data/docs/architecture/before-llm-input.md +3 -3
  15. data/docs/architecture/context-management.md +1 -1
  16. data/docs/architecture/dx05-agent-scope.md +119 -0
  17. data/docs/architecture/dx05-workflow-task-state.md +134 -0
  18. data/docs/architecture/error-api-review.md +245 -0
  19. data/docs/architecture/execution-abstraction-review.md +88 -0
  20. data/docs/architecture/execution-boundaries.md +28 -0
  21. data/docs/architecture/execution-metadata-and-values.md +6 -0
  22. data/docs/architecture/multi-agent-handoff.md +6 -5
  23. data/docs/architecture/persistence.md +27 -9
  24. data/docs/architecture/r8-unit1.md +104 -0
  25. data/docs/architecture/r8-unit10.md +72 -0
  26. data/docs/architecture/r8-unit11.md +71 -0
  27. data/docs/architecture/r8-unit12.md +67 -0
  28. data/docs/architecture/r8-unit13.md +61 -0
  29. data/docs/architecture/r8-unit14.md +72 -0
  30. data/docs/architecture/r8-unit15.md +65 -0
  31. data/docs/architecture/r8-unit16.md +54 -0
  32. data/docs/architecture/r8-unit17.md +73 -0
  33. data/docs/architecture/r8-unit18.md +92 -0
  34. data/docs/architecture/r8-unit19.md +61 -0
  35. data/docs/architecture/r8-unit2.md +55 -0
  36. data/docs/architecture/r8-unit20.md +51 -0
  37. data/docs/architecture/r8-unit21.md +79 -0
  38. data/docs/architecture/r8-unit22.md +74 -0
  39. data/docs/architecture/r8-unit23.md +81 -0
  40. data/docs/architecture/r8-unit3.md +130 -0
  41. data/docs/architecture/r8-unit4.md +79 -0
  42. data/docs/architecture/r8-unit5.md +115 -0
  43. data/docs/architecture/r8-unit6.md +71 -0
  44. data/docs/architecture/r8-unit7.md +70 -0
  45. data/docs/architecture/r8-unit8.md +78 -0
  46. data/docs/architecture/r8-unit9.md +73 -0
  47. data/docs/architecture/refactoring-closure.md +10 -1
  48. data/docs/architecture/remaining-refactoring-plan.md +16 -0
  49. data/docs/architecture/storage-execution-boundaries.md +54 -0
  50. data/docs/architecture/tool-schema-recording-gap.md +6 -0
  51. data/docs/architecture/tracing.md +1 -1
  52. data/docs/architecture/workflow-terminal-ownership-design.md +2 -2
  53. data/docs/architecture.md +24 -11
  54. data/docs/decisions/015-tool-public-facade-and-rbs-boundary.md +3 -3
  55. data/docs/decisions/027-llm-adapter-provider-boundary.md +2 -0
  56. data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +2 -0
  57. data/docs/decisions/031-durable-multi-agent-coordination.md +2 -0
  58. data/docs/decisions/032-storage-backend-composition.md +5 -0
  59. data/docs/decisions/034-handoff-runner-coordination-ownership.md +2 -0
  60. data/docs/decisions/035-tool-executor-capability-ownership.md +1 -1
  61. data/docs/decisions/038-responsibility-based-source-layout.md +14 -0
  62. data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +8 -0
  63. data/docs/decisions/040-configuration-default-composition.md +12 -1
  64. data/docs/decisions/045-worker-input-restriction-ownership.md +4 -0
  65. data/docs/decisions/051-execution-outcome-worker-ownership.md +2 -0
  66. data/docs/decisions/056-workflow-terminal-policy-ownership.md +1 -1
  67. data/docs/decisions/058-neutral-storage-primitives.md +5 -0
  68. data/docs/decisions/059-backend-contracts-and-async-clients.md +74 -0
  69. data/docs/decisions/060-runtime-settings-and-application-configuration.md +86 -0
  70. data/docs/decisions/061-persistence-failure-contracts.md +89 -0
  71. data/docs/decisions/062-content-store-service.md +52 -0
  72. data/docs/decisions/063-execution-contracts-and-services.md +88 -0
  73. data/docs/decisions/064-agent-execution-and-multi-agent-responsibility.md +36 -0
  74. data/docs/decisions/065-vector-and-embeddings-common-operations.md +38 -0
  75. data/docs/decisions/066-llm-and-tool-operation-contracts.md +20 -0
  76. data/docs/decisions/067-agent-progress-and-engine-connection.md +29 -0
  77. data/docs/decisions/068-agent-tool-child-progress-and-tool-operation.md +36 -0
  78. data/docs/decisions/README.md +18 -1
  79. data/docs/execution-boundaries-preview.md +45 -0
  80. data/docs/failure-reason-codes.md +45 -0
  81. data/docs/features.md +12 -4
  82. data/docs/getting-started.md +52 -48
  83. data/docs/migrations/0.22.md +2 -2
  84. data/docs/migrations/durable-semantic-coordination-v2.md +2 -0
  85. data/docs/migrations/handoff-runner-multi-agent.md +2 -0
  86. data/docs/migrations/persistence-failure-contracts.md +67 -0
  87. data/docs/migrations/r8-unit10.md +36 -0
  88. data/docs/migrations/r8-unit11.md +33 -0
  89. data/docs/migrations/r8-unit12.md +31 -0
  90. data/docs/migrations/r8-unit13.md +36 -0
  91. data/docs/migrations/r8-unit14.md +31 -0
  92. data/docs/migrations/r8-unit15.md +31 -0
  93. data/docs/migrations/r8-unit16.md +26 -0
  94. data/docs/migrations/r8-unit17.md +28 -0
  95. data/docs/migrations/r8-unit18.md +29 -0
  96. data/docs/migrations/r8-unit19.md +28 -0
  97. data/docs/migrations/r8-unit20.md +24 -0
  98. data/docs/migrations/r8-unit21.md +28 -0
  99. data/docs/migrations/r8-unit22.md +29 -0
  100. data/docs/migrations/r8-unit23.md +20 -0
  101. data/docs/migrations/r8-unit4.md +67 -0
  102. data/docs/migrations/r8-unit5.md +75 -0
  103. data/docs/migrations/r8-unit6.md +109 -0
  104. data/docs/migrations/r8-unit7.md +31 -0
  105. data/docs/migrations/r8-unit8.md +33 -0
  106. data/docs/migrations/r8-unit9.md +28 -0
  107. data/docs/migrations/storage-async-client.md +103 -0
  108. data/docs/migrations/vector-async-clients.md +110 -0
  109. data/docs/ordered-event-delivery.md +54 -0
  110. data/docs/persistence-backends.md +38 -21
  111. data/docs/runtime-and-concurrency.md +26 -1
  112. data/docs/workflow-completion.md +92 -0
  113. data/gemfiles/http_minimum.gemfile +5 -0
  114. data/lib/phronomy/agent/admission.rb +78 -0
  115. data/lib/phronomy/agent/{lifecycle_contract/agent_already_exists_error.rb → agent_already_exists_error.rb} +1 -1
  116. data/lib/phronomy/agent/{lifecycle_contract/agent_busy_error.rb → agent_busy_error.rb} +1 -1
  117. data/lib/phronomy/agent/agent_not_found_error.rb +16 -0
  118. data/lib/phronomy/agent/{lifecycle_contract/agent_purged_error.rb → agent_purged_error.rb} +1 -1
  119. data/lib/phronomy/agent/agent_unloaded_error.rb +14 -0
  120. data/lib/phronomy/agent/api/agent.rb +13 -0
  121. data/lib/phronomy/{recovery → agent/api}/execution_rehydration_required_error.rb +1 -1
  122. data/lib/phronomy/agent/async_event_api.rb +132 -103
  123. data/lib/phronomy/agent/base.rb +146 -113
  124. data/lib/phronomy/agent/before_llm_input.rb +70 -0
  125. data/lib/phronomy/agent/composition/run_once.rb +1 -1
  126. data/lib/phronomy/agent/{context_assembly/context_candidate_resolver.rb → context_candidate_resolver.rb} +2 -2
  127. data/lib/phronomy/agent/{context_assembly/context_assembler.rb → context_preparation.rb} +35 -221
  128. data/lib/phronomy/agent/control_request.rb +21 -0
  129. data/lib/phronomy/agent/execution/agent_execution.rb +1 -1
  130. data/lib/phronomy/agent/execution/agent_invocation.rb +27 -53
  131. data/lib/phronomy/agent/execution/approval_resume_commit.rb +1 -1
  132. data/lib/phronomy/agent/execution/dispatch_preparation.rb +17 -127
  133. data/lib/phronomy/agent/execution/exact_execution.rb +55 -32
  134. data/lib/phronomy/agent/execution/execution_cancellation.rb +8 -4
  135. data/lib/phronomy/agent/execution/execution_coordinator.rb +229 -407
  136. data/lib/phronomy/agent/execution/execution_metadata.rb +1 -0
  137. data/lib/phronomy/agent/execution/execution_outcome_committer.rb +71 -127
  138. data/lib/phronomy/agent/execution/execution_registry.rb +6 -2
  139. data/lib/phronomy/agent/execution/execution_session_runner.rb +22 -27
  140. data/lib/phronomy/agent/execution/initial_preparation.rb +19 -120
  141. data/lib/phronomy/agent/execution/{agent_invocation_session_builder.rb → invocation_actions.rb} +54 -194
  142. data/lib/phronomy/agent/execution/invocation_transitions.rb +39 -1
  143. data/lib/phronomy/agent/execution/runtime_record_encoder.rb +8 -11
  144. data/lib/phronomy/agent/execution_change.rb +161 -0
  145. data/lib/phronomy/agent/execution_environment.rb +36 -0
  146. data/lib/phronomy/agent/execution_extension_state.rb +21 -0
  147. data/lib/phronomy/agent/execution_observation.rb +35 -0
  148. data/lib/phronomy/agent/filterable.rb +188 -0
  149. data/lib/phronomy/agent/handoff/{handoff_context.rb → transfer_context.rb} +4 -4
  150. data/lib/phronomy/agent/handoff/{handoff_projection.rb → transfer_projection.rb} +14 -33
  151. data/lib/phronomy/{llm_contract/transport_error.rb → agent/handoff_error.rb} +1 -1
  152. data/lib/phronomy/agent/journal/journal_projection.rb +1 -1
  153. data/lib/phronomy/agent/knowledge_item.rb +13 -0
  154. data/lib/phronomy/agent/lifecycle/agent_root.rb +1 -1
  155. data/lib/phronomy/agent/lifecycle/lifetime_api.rb +76 -0
  156. data/lib/phronomy/agent/lifecycle/operation_lease.rb +33 -0
  157. data/lib/phronomy/agent/lifecycle/operation_result.rb +53 -0
  158. data/lib/phronomy/agent/lifecycle/ownership_registry.rb +117 -31
  159. data/lib/phronomy/agent/lifecycle/scope.rb +198 -0
  160. data/lib/phronomy/agent/lifecycle/scope_cleanup_error.rb +19 -0
  161. data/lib/phronomy/agent/lifecycle/unload_transition.rb +78 -0
  162. data/lib/phronomy/agent/persistence/agent_repository.rb +29 -21
  163. data/lib/phronomy/agent/persistence/cancellation_repository.rb +51 -0
  164. data/lib/phronomy/agent/persistence/codec.rb +1 -21
  165. data/lib/phronomy/agent/persistence/execution_repository.rb +57 -41
  166. data/lib/phronomy/agent/persistence/journal_repository.rb +27 -18
  167. data/lib/phronomy/agent/persistence/records.rb +33 -0
  168. data/lib/phronomy/agent/persistence/retention_repository.rb +70 -0
  169. data/lib/phronomy/agent/persistence/storage_schema.rb +7 -2
  170. data/lib/phronomy/agent/persistence/watermark.rb +13 -11
  171. data/lib/phronomy/agent/recovery/invocation_restorer.rb +13 -21
  172. data/lib/phronomy/agent/recovery/recovery_coordinator/continuation.rb +13 -12
  173. data/lib/phronomy/agent/recovery/recovery_coordinator/installation.rb +34 -34
  174. data/lib/phronomy/agent/recovery/recovery_coordinator/resolution.rb +33 -39
  175. data/lib/phronomy/agent/recovery/recovery_coordinator.rb +28 -25
  176. data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
  177. data/lib/phronomy/agent/recovery/recovery_support.rb +10 -19
  178. data/lib/phronomy/agent/reserved_execution.rb +16 -0
  179. data/lib/phronomy/agent/retention.rb +17 -0
  180. data/lib/phronomy/agent/runtime_binding/engine_environment.rb +60 -0
  181. data/lib/phronomy/agent/runtime_binding/engine_session_builder.rb +34 -0
  182. data/lib/phronomy/agent/runtime_binding/phase_machine_builder.rb +64 -0
  183. data/lib/phronomy/agent/runtime_binding/tool_session_builder.rb +34 -0
  184. data/lib/phronomy/agent/{context_assembly/ruby_llm_materializer.rb → runtime_input.rb} +18 -35
  185. data/lib/phronomy/agent/{context_assembly/saved_context_reader.rb → saved_context_reader.rb} +6 -4
  186. data/lib/phronomy/agent/settings.rb +47 -0
  187. data/lib/phronomy/agent/{context_assembly/state_writer.rb → state_writer.rb} +4 -3
  188. data/lib/phronomy/agent/store.rb +253 -0
  189. data/lib/phronomy/agent/{lifecycle_contract/stream_callback_error.rb → stream_callback_error.rb} +3 -3
  190. data/lib/phronomy/agent/tool_execution/tool_binding.rb +4 -64
  191. data/lib/phronomy/agent/tool_execution/tool_invocation.rb +50 -219
  192. data/lib/phronomy/agent/tool_execution/tool_invocation_actions.rb +107 -0
  193. data/lib/phronomy/agent/tool_execution/tool_invocation_transitions.rb +70 -0
  194. data/lib/phronomy/common/error.rb +65 -1
  195. data/lib/phronomy/configuration/runtime_settings.rb +49 -0
  196. data/lib/phronomy/content_store/base.rb +7 -2
  197. data/lib/phronomy/content_store/storage_schema.rb +1 -0
  198. data/lib/phronomy/content_store/stored_contents.rb +2 -1
  199. data/lib/phronomy/context/assembly.rb +195 -0
  200. data/lib/phronomy/{llm_contract/context_budget_exceeded_error.rb → context/budget_exceeded_error.rb} +3 -1
  201. data/lib/phronomy/context/candidate.rb +51 -0
  202. data/lib/phronomy/context/constraint.rb +47 -0
  203. data/lib/phronomy/{agent/context_contract → context}/context_plan.rb +1 -1
  204. data/lib/phronomy/{agent/context_contract → context}/context_plan_validator.rb +3 -3
  205. data/lib/phronomy/{agent/context_contract → context}/context_policy.rb +1 -1
  206. data/lib/phronomy/{agent/context_contract → context}/context_policy_input.rb +1 -1
  207. data/lib/phronomy/{agent/context_assembly → context}/context_policy_input_builder.rb +1 -1
  208. data/lib/phronomy/context/default_policy.rb +140 -0
  209. data/lib/phronomy/context/final_budget_validator.rb +33 -0
  210. data/lib/phronomy/{agent/context_contract → context}/llm_input_build_context.rb +1 -1
  211. data/lib/phronomy/{agent/context_contract → context}/llm_input_manifest.rb +19 -19
  212. data/lib/phronomy/{agent/context_contract → context}/llm_input_patch.rb +1 -1
  213. data/lib/phronomy/context/manifest_error.rb +10 -0
  214. data/lib/phronomy/context/prompt_template.rb +98 -0
  215. data/lib/phronomy/{vector_store → documents}/loader/base.rb +1 -1
  216. data/lib/phronomy/{vector_store → documents}/loader/csv_loader.rb +2 -2
  217. data/lib/phronomy/{vector_store → documents}/loader/markdown_loader.rb +3 -3
  218. data/lib/phronomy/{vector_store → documents}/loader/plain_text_loader.rb +2 -2
  219. data/lib/phronomy/{vector_store → documents}/splitter/base.rb +1 -1
  220. data/lib/phronomy/{vector_store → documents}/splitter/fixed_size_splitter.rb +2 -2
  221. data/lib/phronomy/{vector_store → documents}/splitter/recursive_splitter.rb +2 -2
  222. data/lib/phronomy/embeddings/async/async_client.rb +44 -0
  223. data/lib/phronomy/embeddings/authentication_error.rb +11 -0
  224. data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +52 -0
  225. data/lib/phronomy/embeddings/base.rb +43 -0
  226. data/lib/phronomy/embeddings/invalid_result_error.rb +11 -0
  227. data/lib/phronomy/embeddings/rate_limit_error.rb +11 -0
  228. data/lib/phronomy/embeddings/transport_error.rb +11 -0
  229. data/lib/phronomy/engine/concurrency/offload_pool.rb +36 -21
  230. data/lib/phronomy/engine/concurrency/pool_registry.rb +47 -12
  231. data/lib/phronomy/engine/diagnostics.rb +1 -1
  232. data/lib/phronomy/engine/event_loop.rb +7 -7
  233. data/lib/phronomy/engine/execution_binding.rb +23 -0
  234. data/lib/phronomy/engine/execution_receiver_binding.rb +43 -0
  235. data/lib/phronomy/engine/fsm_protocol.rb +1 -6
  236. data/lib/phronomy/engine/fsm_session.rb +3 -3
  237. data/lib/phronomy/engine/metrics.rb +16 -14
  238. data/lib/phronomy/engine/runtime/timer_queue.rb +1 -1
  239. data/lib/phronomy/engine/runtime.rb +25 -12
  240. data/lib/phronomy/engine/terminal_decision.rb +7 -0
  241. data/lib/phronomy/execution/async_operation.rb +41 -0
  242. data/lib/phronomy/{engine → execution}/blocking.rb +2 -2
  243. data/lib/phronomy/{engine → execution}/concurrency/cancellation_token.rb +1 -1
  244. data/lib/phronomy/{engine → execution}/concurrency/deadline.rb +0 -17
  245. data/lib/phronomy/{engine → execution}/concurrency/physical_completion_task.rb +1 -1
  246. data/lib/phronomy/{engine → execution}/concurrency/result_collector.rb +1 -1
  247. data/lib/phronomy/{engine → execution}/concurrency/result_composition.rb +33 -12
  248. data/lib/phronomy/{engine/concurrency/subscriptions.rb → execution/concurrency/result_subscriptions.rb} +14 -18
  249. data/lib/phronomy/execution/concurrency/subscriptions.rb +25 -0
  250. data/lib/phronomy/{engine → execution}/execution.rb +61 -27
  251. data/lib/phronomy/{engine → execution}/execution_cancellation_error.rb +2 -2
  252. data/lib/phronomy/execution/execution_receiver.rb +78 -0
  253. data/lib/phronomy/execution/execution_scope_state.rb +35 -0
  254. data/lib/phronomy/{engine → execution}/execution_timeout_error.rb +2 -2
  255. data/lib/phronomy/{engine → execution}/invocation_context.rb +0 -15
  256. data/lib/phronomy/execution/invocation_controls.rb +73 -0
  257. data/lib/phronomy/execution/runnable.rb +24 -0
  258. data/lib/phronomy/{engine → execution}/task_result.rb +9 -4
  259. data/lib/phronomy/execution/wait_policy.rb +24 -0
  260. data/lib/phronomy/filter/{contract/filter_block_error.rb → filter_block_error.rb} +3 -3
  261. data/lib/phronomy/generation/generator_verifier/agent_operation.rb +65 -0
  262. data/lib/phronomy/generation/generator_verifier/default_parser.rb +27 -0
  263. data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +2 -2
  264. data/lib/phronomy/generation/generator_verifier.rb +7 -7
  265. data/lib/phronomy/generation/low_confidence_error.rb +2 -2
  266. data/lib/phronomy/integrations/ordered_event_delivery.rb +208 -0
  267. data/lib/phronomy/llm_adapter/async/async_client.rb +47 -0
  268. data/lib/phronomy/{llm_contract → llm_adapter}/authentication_error.rb +3 -1
  269. data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +183 -0
  270. data/lib/phronomy/llm_adapter/base.rb +49 -68
  271. data/lib/phronomy/{llm_contract → llm_adapter}/context_length_error.rb +3 -1
  272. data/lib/phronomy/llm_adapter/invalid_result_error.rb +10 -0
  273. data/lib/phronomy/llm_adapter/message.rb +62 -0
  274. data/lib/phronomy/{llm_contract → llm_adapter}/rate_limit_error.rb +3 -1
  275. data/lib/phronomy/llm_adapter/request.rb +79 -0
  276. data/lib/phronomy/llm_adapter/response.rb +36 -0
  277. data/lib/phronomy/llm_adapter/stream_chunk.rb +18 -0
  278. data/lib/phronomy/llm_adapter/token_usage.rb +64 -0
  279. data/lib/phronomy/llm_adapter/transport_error.rb +9 -0
  280. data/lib/phronomy/llm_adapter.rb +3 -16
  281. data/lib/phronomy/multi_agent/admission_registry.rb +1 -8
  282. data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +108 -84
  283. data/lib/phronomy/multi_agent/execution_environment.rb +29 -0
  284. data/lib/phronomy/{agent/handoff → multi_agent}/handoff.rb +2 -2
  285. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_capability_factory.rb +21 -2
  286. data/lib/phronomy/multi_agent/handoff_participant.rb +79 -0
  287. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_policy.rb +1 -1
  288. data/lib/phronomy/multi_agent/handoff_runner.rb +77 -100
  289. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_state.rb +1 -1
  290. data/lib/phronomy/multi_agent/orchestrator.rb +61 -75
  291. data/lib/phronomy/multi_agent/persistence/codec.rb +20 -0
  292. data/lib/phronomy/multi_agent/persistence/handoff_state_repository.rb +77 -0
  293. data/lib/phronomy/multi_agent/persistence/records.rb +27 -0
  294. data/lib/phronomy/multi_agent/persistence/storage_schema.rb +21 -0
  295. data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +60 -44
  296. data/lib/phronomy/multi_agent/persistence/team_repository.rb +29 -21
  297. data/lib/phronomy/multi_agent/reserved_child_admission.rb +88 -0
  298. data/lib/phronomy/multi_agent/runtime_binding/engine_environment.rb +35 -0
  299. data/lib/phronomy/multi_agent/shared_state.rb +2 -2
  300. data/lib/phronomy/multi_agent/store.rb +156 -0
  301. data/lib/phronomy/multi_agent/team_busy_error.rb +18 -0
  302. data/lib/phronomy/multi_agent/team_coordinator.rb +99 -77
  303. data/lib/phronomy/multi_agent/team_not_found_error.rb +18 -0
  304. data/lib/phronomy/multi_agent/team_ownership_registry.rb +2 -12
  305. data/lib/phronomy/output_parser/parse_error.rb +7 -0
  306. data/lib/phronomy/persistence/content_repository.rb +26 -0
  307. data/lib/phronomy/persistence/errors.rb +16 -0
  308. data/lib/phronomy/persistence/migration/initial_format_migration.rb +2 -2
  309. data/lib/phronomy/persistence/persistence.rb +23 -0
  310. data/lib/phronomy/persistence/save_outcome.rb +24 -0
  311. data/lib/phronomy/persistence/snapshot_comparison.rb +81 -0
  312. data/lib/phronomy/persistence/storage_boundary.rb +32 -0
  313. data/lib/phronomy/persistence/transaction.rb +86 -0
  314. data/lib/phronomy/persistence_composition/storage_schema.rb +9 -4
  315. data/lib/phronomy/persistence_composition/stores.rb +34 -0
  316. data/lib/phronomy/persistence_composition/unit4_migration.rb +276 -0
  317. data/lib/phronomy/runtime_composition/agent_defaults.rb +5 -1
  318. data/lib/phronomy/runtime_composition/configuration.rb +146 -0
  319. data/lib/phronomy/runtime_composition/evaluation_defaults.rb +7 -0
  320. data/lib/phronomy/runtime_composition/execution_defaults.rb +5 -0
  321. data/lib/phronomy/runtime_composition/generation_defaults.rb +6 -0
  322. data/lib/phronomy/runtime_composition/global_configuration.rb +38 -0
  323. data/lib/phronomy/runtime_composition/multi_agent_defaults.rb +9 -0
  324. data/lib/phronomy/runtime_composition/workflow_defaults.rb +4 -0
  325. data/lib/phronomy/storage/async/async_client.rb +60 -0
  326. data/lib/phronomy/storage/backend.rb +8 -2
  327. data/lib/phronomy/storage/condition_failed_error.rb +2 -2
  328. data/lib/phronomy/storage/unique_constraint_error.rb +2 -2
  329. data/lib/phronomy/testing/eval/metrics.rb +1 -1
  330. data/lib/phronomy/testing/eval/scorer/llm_judge.rb +19 -3
  331. data/lib/phronomy/testing/persistence_contract/a_content_store.rb +2 -2
  332. data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +6 -6
  333. data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +55 -52
  334. data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +3 -3
  335. data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +7 -7
  336. data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +11 -11
  337. data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +57 -51
  338. data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +1 -1
  339. data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +23 -22
  340. data/lib/phronomy/tool/authorization.rb +77 -0
  341. data/lib/phronomy/tool/base.rb +551 -9
  342. data/lib/phronomy/tool/call_request.rb +40 -0
  343. data/lib/phronomy/{agent/tool_execution/tool_definition_set.rb → tool/definition_set.rb} +7 -8
  344. data/lib/phronomy/tool/operation.rb +88 -0
  345. data/lib/phronomy/tool/schema.rb +214 -0
  346. data/lib/phronomy/tool/settings.rb +31 -0
  347. data/lib/phronomy/tool/tool_error.rb +7 -0
  348. data/lib/phronomy/tool/tool_executor.rb +58 -0
  349. data/lib/phronomy/tools/agent.rb +22 -90
  350. data/lib/phronomy/tools/mcp.rb +21 -14
  351. data/lib/phronomy/tools/vector_search.rb +4 -4
  352. data/lib/phronomy/tracing/automatic.rb +11 -6
  353. data/lib/phronomy/tracing/base.rb +36 -7
  354. data/lib/phronomy/tracing/observation.rb +37 -0
  355. data/lib/phronomy/tracing/open_telemetry_tracer.rb +4 -29
  356. data/lib/phronomy/tracing/settings.rb +36 -0
  357. data/lib/phronomy/vector_store/{async_backend.rb → async/async_client.rb} +35 -29
  358. data/lib/phronomy/vector_store/{in_memory.rb → backends/in_memory.rb} +12 -10
  359. data/lib/phronomy/vector_store/{pgvector.rb → backends/pgvector.rb} +44 -16
  360. data/lib/phronomy/vector_store/{redis_search.rb → backends/redis_search.rb} +74 -37
  361. data/lib/phronomy/vector_store/base.rb +118 -49
  362. data/lib/phronomy/vector_store/invalid_result_error.rb +12 -0
  363. data/lib/phronomy/vector_store.rb +2 -17
  364. data/lib/phronomy/version.rb +1 -1
  365. data/lib/phronomy/workflow/completion.rb +11 -0
  366. data/lib/phronomy/workflow/execution/workflow.rb +37 -9
  367. data/lib/phronomy/workflow/execution/workflow_action_rules.rb +67 -0
  368. data/lib/phronomy/workflow/execution/workflow_context.rb +2 -2
  369. data/lib/phronomy/workflow/execution/workflow_execution_environment.rb +28 -0
  370. data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +77 -8
  371. data/lib/phronomy/workflow/execution/workflow_runner.rb +105 -92
  372. data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -0
  373. data/lib/phronomy/workflow/execution/workflow_task_execution.rb +153 -0
  374. data/lib/phronomy/workflow/execution/workflow_task_reception.rb +72 -0
  375. data/lib/phronomy/workflow/execution/workflow_task_resume_error.rb +14 -0
  376. data/lib/phronomy/workflow/persistence/state_repository.rb +28 -22
  377. data/lib/phronomy/workflow/persistence/storage_schema.rb +13 -0
  378. data/lib/phronomy/workflow/runtime_binding/workflow_engine_environment.rb +61 -0
  379. data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +158 -0
  380. data/lib/phronomy/workflow/runtime_binding/workflow_task_session.rb +76 -0
  381. data/lib/phronomy/workflow/{execution → runtime_binding}/workflow_terminal_policy.rb +4 -4
  382. data/lib/phronomy.rb +63 -16
  383. data/scripts/api_snapshot.rb +47 -15
  384. data/scripts/check_readme_ruby.rb +24 -29
  385. data/scripts/check_readme_runnable.rb +92 -81
  386. data/sig/_private/phronomy/agent/settings.rbs +19 -0
  387. data/sig/_private/phronomy/configuration/runtime_settings.rbs +20 -0
  388. data/sig/_private/phronomy/llm_adapter/async/async_client.rbs +10 -0
  389. data/sig/_private/phronomy/multi_agent/store.rbs +8 -0
  390. data/sig/_private/phronomy/persistence/storage_boundary.rbs +7 -0
  391. data/sig/_private/phronomy/tool/settings.rbs +13 -0
  392. data/sig/_private/phronomy/tracing/settings.rbs +15 -0
  393. data/sig/_private/phronomy/workflow/execution/workflow_settings.rbs +13 -0
  394. data/sig/phronomy/agent/admission.rbs +19 -0
  395. data/sig/phronomy/agent/agent_not_found_error.rbs +6 -0
  396. data/sig/phronomy/agent/agent_unloaded_error.rbs +6 -0
  397. data/sig/phronomy/agent/execution_contract.rbs +132 -0
  398. data/sig/phronomy/agent/execution_environment.rbs +20 -0
  399. data/sig/phronomy/agent/store.rbs +73 -0
  400. data/sig/phronomy/agent/stream_callback_error.rbs +8 -0
  401. data/sig/phronomy/agent.rbs +29 -135
  402. data/sig/phronomy/common.rbs +7 -0
  403. data/sig/phronomy/content_store/contracts.rbs +13 -0
  404. data/sig/phronomy/context.rbs +152 -0
  405. data/sig/phronomy/embeddings/async/async_client.rbs +9 -0
  406. data/sig/phronomy/embeddings/base.rbs +23 -0
  407. data/sig/phronomy/engine/concurrency/timer_bindings.rbs +22 -0
  408. data/sig/phronomy/engine/control_bindings.rbs +11 -0
  409. data/sig/phronomy/engine/control_protocols.rbs +23 -0
  410. data/sig/phronomy/engine/execution_binding.rbs +6 -0
  411. data/sig/phronomy/engine/execution_receiver.rbs +15 -0
  412. data/sig/phronomy/engine/observability.rbs +13 -0
  413. data/sig/phronomy/execution/async_operation.rbs +7 -0
  414. data/sig/phronomy/execution/blocking.rbs +5 -0
  415. data/sig/phronomy/execution/concurrency/cancellation_token.rbs +13 -0
  416. data/sig/phronomy/execution/concurrency/deadline.rbs +10 -0
  417. data/sig/phronomy/execution/concurrency/result_composition.rbs +7 -0
  418. data/sig/phronomy/execution/control_protocols.rbs +18 -0
  419. data/sig/phronomy/execution/errors.rbs +7 -0
  420. data/sig/phronomy/execution/execution.rbs +41 -0
  421. data/sig/phronomy/execution/execution_receiver.rbs +40 -0
  422. data/sig/phronomy/execution/execution_scope_state.rbs +9 -0
  423. data/sig/phronomy/execution/invocation_context.rbs +18 -0
  424. data/sig/phronomy/execution/invocation_controls.rbs +13 -0
  425. data/sig/phronomy/execution/task_result.rbs +29 -0
  426. data/sig/phronomy/extensions.rbs +1 -21
  427. data/sig/phronomy/filter/filter_block_error.rbs +6 -0
  428. data/sig/phronomy/generation/low_confidence_error.rbs +6 -0
  429. data/sig/phronomy/handoff.rbs +10 -4
  430. data/sig/phronomy/integrations.rbs +14 -0
  431. data/sig/phronomy/llm_adapter/backends/ruby_llm.rbs +6 -0
  432. data/sig/phronomy/llm_adapter/base.rbs +14 -0
  433. data/sig/phronomy/llm_adapter/usage.rbs +14 -0
  434. data/sig/phronomy/llm_adapter/values.rbs +43 -0
  435. data/sig/phronomy/llm_context_window.rbs +10 -0
  436. data/sig/phronomy/multi_agent/reserved_child_admission.rbs +8 -0
  437. data/sig/phronomy/multi_agent/store.rbs +54 -0
  438. data/sig/phronomy/multi_agent/team_busy_error.rbs +8 -0
  439. data/sig/phronomy/multi_agent/team_not_found_error.rbs +8 -0
  440. data/sig/phronomy/multi_agent.rbs +6 -3
  441. data/sig/phronomy/persistence/errors.rbs +18 -0
  442. data/sig/phronomy/persistence/migration.rbs +13 -0
  443. data/sig/phronomy/persistence/transaction.rbs +19 -0
  444. data/sig/phronomy/persistence.rbs +1 -99
  445. data/sig/phronomy/persistence_composition.rbs +19 -0
  446. data/sig/phronomy/runtime_composition/configuration.rbs +36 -0
  447. data/sig/phronomy/storage/async/async_client.rbs +8 -0
  448. data/sig/phronomy/storage/backends/in_memory.rbs +9 -0
  449. data/sig/phronomy/{storage.rbs → storage/contracts.rbs} +4 -18
  450. data/sig/phronomy/tool.rbs +48 -4
  451. data/sig/phronomy/tracing/observation.rbs +7 -0
  452. data/sig/phronomy/vector_store/async/async_client.rbs +13 -0
  453. data/sig/phronomy/vector_store/base.rbs +23 -0
  454. data/sig/phronomy/workflow/execution/workflow_execution_environment.rbs +15 -0
  455. data/sig/phronomy/workflow/runtime_binding/workflow_terminal_policy.rbs +7 -0
  456. data/sig/phronomy/workflow/store.rbs +8 -0
  457. data/sig/phronomy/workflow.rbs +5 -1
  458. data/sig/phronomy.rbs +4 -49
  459. metadata +365 -117
  460. data/lib/phronomy/agent/concerns/before_llm_input.rb +0 -66
  461. data/lib/phronomy/agent/concerns/error_translation.rb +0 -45
  462. data/lib/phronomy/agent/concerns/filterable.rb +0 -184
  463. data/lib/phronomy/agent/context/capability/base.rb +0 -548
  464. data/lib/phronomy/agent/context/capability/tool_executor.rb +0 -62
  465. data/lib/phronomy/agent/context/instruction/prompt_template.rb +0 -102
  466. data/lib/phronomy/agent/context_assembly/runtime_chat_builder.rb +0 -36
  467. data/lib/phronomy/agent/context_assembly/token_budget_resolver.rb +0 -22
  468. data/lib/phronomy/agent/context_parts/validators/final_budget_validator.rb +0 -37
  469. data/lib/phronomy/agent/context_policies/default.rb +0 -142
  470. data/lib/phronomy/agent/execution/phase_machine_builder.rb +0 -101
  471. data/lib/phronomy/agent/execution/provider_call_outcome.rb +0 -106
  472. data/lib/phronomy/agent/handoff/handoff_execution_coordinator.rb +0 -15
  473. data/lib/phronomy/agent/handoff/handoff_outcome_committer.rb +0 -131
  474. data/lib/phronomy/agent/handoff/handoff_request.rb +0 -45
  475. data/lib/phronomy/agent/lifecycle_contract/handoff_error.rb +0 -7
  476. data/lib/phronomy/agent/persistence/handoff_state_repository.rb +0 -58
  477. data/lib/phronomy/agent/persistence/queries.rb +0 -61
  478. data/lib/phronomy/agent/selection/candidate.rb +0 -53
  479. data/lib/phronomy/agent/selection/constraint.rb +0 -49
  480. data/lib/phronomy/agent/tool_execution/tool_call_intercepted.rb +0 -29
  481. data/lib/phronomy/agent/tool_execution/tool_invocation_session_builder.rb +0 -276
  482. data/lib/phronomy/configuration/configuration.rb +0 -68
  483. data/lib/phronomy/configuration/global_configuration.rb +0 -26
  484. data/lib/phronomy/engine/concurrency/cancellation_scope.rb +0 -124
  485. data/lib/phronomy/engine/concurrency/operation_binding.rb +0 -43
  486. data/lib/phronomy/engine/execution_receiver.rb +0 -65
  487. data/lib/phronomy/engine/runnable.rb +0 -54
  488. data/lib/phronomy/llm_adapter/ruby_llm.rb +0 -47
  489. data/lib/phronomy/llm_contract/token_usage.rb +0 -85
  490. data/lib/phronomy/multi_agent/persistence/queries.rb +0 -30
  491. data/lib/phronomy/multi_agent/storage_contract/team_storage_schema.rb +0 -15
  492. data/lib/phronomy/output_parser/contract/parse_error.rb +0 -7
  493. data/lib/phronomy/persistence/api/persistence.rb +0 -140
  494. data/lib/phronomy/persistence_composition/repositories.rb +0 -77
  495. data/lib/phronomy/recovery/recovery.rb +0 -186
  496. data/lib/phronomy/tool/contract/tool_error.rb +0 -7
  497. data/lib/phronomy/vector_store/embeddings/base.rb +0 -44
  498. data/lib/phronomy/vector_store/embeddings/ruby_llm_embeddings.rb +0 -47
  499. data/lib/phronomy/workflow/phase_machine_builder.rb +0 -205
  500. data/lib/phronomy/workflow/storage_contract/workflow_storage_schema.rb +0 -9
  501. data/sig/phronomy/execution_receiver.rbs +0 -34
  502. data/sig/phronomy/llm_adapter.rbs +0 -11
  503. data/sig/phronomy/runtime.rbs +0 -76
  504. /data/lib/phronomy/agent/{context_assembly/context_importer.rb → context_importer.rb} +0 -0
  505. /data/lib/phronomy/{engine → execution}/backpressure_error.rb +0 -0
  506. /data/lib/phronomy/{engine → execution}/cancellation_error.rb +0 -0
  507. /data/lib/phronomy/{engine → execution}/concurrency/worker_input_restricted.rb +0 -0
  508. /data/lib/phronomy/{engine → execution}/event_loop_reentrancy_error.rb +0 -0
  509. /data/lib/phronomy/{engine → execution}/invalid_async_entry_action_error.rb +0 -0
  510. /data/lib/phronomy/{engine → execution}/invalid_async_transition_action_error.rb +0 -0
  511. /data/lib/phronomy/{engine → execution}/invalid_async_workflow_action_error.rb +0 -0
  512. /data/lib/phronomy/{engine → execution}/pool_shutdown_error.rb +0 -0
  513. /data/lib/phronomy/{engine → execution}/recursion_limit_error.rb +0 -0
  514. /data/lib/phronomy/{engine → execution}/runtime_shutdown_error.rb +0 -0
  515. /data/lib/phronomy/{engine → execution}/runtime_shutdown_reentrancy_error.rb +0 -0
  516. /data/lib/phronomy/{engine → execution}/scheduler_reentrancy_error.rb +0 -0
  517. /data/lib/phronomy/{engine → execution}/timeout_error.rb +0 -0
@@ -9,7 +9,7 @@ Accepted.
9
9
  Phronomy has accumulated two related API-maintenance problems:
10
10
 
11
11
  1. Application-defined Tools are implemented by subclassing the internal-taxonomy
12
- name `Phronomy::Agent::Context::Capability::Base`, even though the product
12
+ name `Phronomy::Tool::Base`, even though the product
13
13
  concept exposed to users is simply a Tool.
14
14
  2. The gem ships almost no RBS signatures, so the distinction between
15
15
  application APIs, extension SPIs, and private implementation objects is not
@@ -42,7 +42,7 @@ Phronomy::Tool::Base
42
42
  The existing implementation class remains:
43
43
 
44
44
  ```ruby
45
- Phronomy::Agent::Context::Capability::Base
45
+ Phronomy::Tool::Base
46
46
  ```
47
47
 
48
48
  `Phronomy::Tool::Base` is an exact constant alias to that same class object. It
@@ -58,7 +58,7 @@ This preserves:
58
58
  name.
59
59
 
60
60
  Consequently, `Phronomy::Tool::Base.name` intentionally remains
61
- `"Phronomy::Agent::Context::Capability::Base"`. If a future public contract
61
+ `"Phronomy::Tool::Base"`. If a future public contract
62
62
  requires the runtime class name itself to become `Phronomy::Tool::Base`, that is
63
63
  a separate migration decision.
64
64
 
@@ -46,6 +46,8 @@ reconciliation must not silently promote its API stability.
46
46
  2. `Phronomy::LLMAdapter::Base#complete` and `#stream` are the public
47
47
  Provider-call extension boundary. Phronomy owns the framework-side
48
48
  asynchronous/offload wrappers around that synchronous adapter contract.
49
+ [ADR-059](059-backend-contracts-and-async-clients.md) locates those wrappers
50
+ in the private `LLMAdapter::AsyncClient`, separate from Base and RubyLLM.
49
51
  3. `Phronomy::LLMAdapter::RubyLLM` remains the default configured LLM adapter
50
52
  and RubyLLM remains Phronomy's default Provider integration.
51
53
  4. A custom LLMAdapter may replace Provider-call behavior, but the LLMAdapter
@@ -1,5 +1,7 @@
1
1
  # ADR-030: Agent Handoff Domain and Durable Responsibility
2
2
 
3
+ > r8 unit 4 supersedes the Agent/Handoff ownership and storage portions below. See [the unit 4 migration](../migrations/r8-unit4.md). Earlier statements describe their original change only.
4
+
3
5
  ## Status
4
6
 
5
7
  Accepted. V2 revision 2, 2026-09-06.
@@ -1,5 +1,7 @@
1
1
  # ADR-031: Durable Multi-Agent Semantic Coordination
2
2
 
3
+ > Agent/MultiAgent ownership is amended by [ADR-064](064-agent-execution-and-multi-agent-responsibility.md).
4
+
3
5
  ## Status
4
6
 
5
7
  Accepted. V2 revision 2, 2026-09-06.
@@ -9,6 +9,11 @@ The raw fixed-repository/error portions are amended by
9
9
  [ADR-058](058-neutral-storage-primitives.md). Domain ownership and applicable
10
10
  transaction/uncertainty decisions below remain in force.
11
11
 
12
+ Domain-facing exception ownership is further amended by
13
+ [061-persistence-failure-contracts](061-persistence-failure-contracts.md).
14
+ Raw backend exceptions remain owned by Storage; domain repository exits now
15
+ translate their known categories to independent Persistence exceptions.
16
+
12
17
  ## Context
13
18
 
14
19
  The previous `Persistence` class combined raw storage contracts with domain
@@ -1,5 +1,7 @@
1
1
  # ADR-034: Handoff Runner Coordination Ownership
2
2
 
3
+ > r8 unit 4 supersedes the Agent/Handoff ownership and storage portions below. See [the unit 4 migration](../migrations/r8-unit4.md). Earlier statements describe their original change only.
4
+
3
5
  ## Status
4
6
 
5
7
  Accepted for the H1 step on `refactor/architecture`, 2026-09-18.
@@ -28,7 +28,7 @@ public compatibility decision.
28
28
  ## Decision
29
29
 
30
30
  1. Move the helper to
31
- `Phronomy::Agent::Context::Capability::ToolExecutor`, in
31
+ `Phronomy::Tool::ToolExecutor`, in
32
32
  `agent/context/capability/tool_executor.rb`. Classify this helper as private
33
33
  API and remove the old internal constant without a compatibility alias.
34
34
  2. Use the new helper from Capability Base and Agent ToolInvocation. Preserve
@@ -1,5 +1,11 @@
1
1
  # ADR-038: Responsibility-Based Source Layout
2
2
 
3
+ > Current boundary: r8 unit 6 supersedes the historical Chat/SDK ownership and
4
+ > adapter extension SPI below. Agent uses LLMAdapter values; the backend owns SDK
5
+ > construction/interception; Tool owns canonical schema validation. See
6
+ > `docs/architecture/r8-unit6.md` and `docs/migrations/r8-unit6.md`.
7
+
8
+
3
9
  ## Status
4
10
 
5
11
  Accepted on the architecture refactoring branch; configuration/runtime lifecycle
@@ -17,6 +23,14 @@ Amends the extraction scope of
17
23
  [037-common-definition-ownership](037-common-definition-ownership.md).
18
24
  Its common-ownership rule and public Error contract remain unchanged.
19
25
 
26
+ ## Amendment: neutral runtime settings
27
+
28
+ [060-runtime-settings-and-application-configuration](060-runtime-settings-and-application-configuration.md)
29
+ amends configuration placement and Engine access: application configuration and
30
+ global accessors belong to `runtime_composition/`, while `configuration/` owns
31
+ only neutral `RuntimeSettings`. Concrete defaults remain composition-owned;
32
+ public configuration and Runtime reset behavior remain unchanged.
33
+
20
34
  ## Context
21
35
 
22
36
  The application loading entry point and the direct `lib/phronomy/` directory
@@ -13,6 +13,14 @@ Amends the configuration ownership in
13
13
  Its loading rules, direct-root allowlist, and compatibility requirements remain
14
14
  in force.
15
15
 
16
+ ## Amendment: neutral runtime settings
17
+
18
+ [060-runtime-settings-and-application-configuration](060-runtime-settings-and-application-configuration.md)
19
+ amends configuration placement and Engine access: application configuration and
20
+ global accessors belong to `runtime_composition/`, while `configuration/` owns
21
+ only neutral `RuntimeSettings`. Concrete defaults remain composition-owned;
22
+ public configuration and Runtime reset behavior remain unchanged.
23
+
16
24
  ## Context
17
25
 
18
26
  `Phronomy.reset_runtime!` shuts down the default Runtime and replaces global
@@ -11,6 +11,14 @@ Their loading, public compatibility, and Runtime reset rules remain in force.
11
11
  The provider-call and framework-owned async boundary in
12
12
  [027-llm-adapter-provider-boundary](027-llm-adapter-provider-boundary.md) is unchanged.
13
13
 
14
+ ## Amendment: neutral runtime settings
15
+
16
+ [060-runtime-settings-and-application-configuration](060-runtime-settings-and-application-configuration.md)
17
+ amends configuration placement and Engine access: application configuration and
18
+ global accessors belong to `runtime_composition/`, while `configuration/` owns
19
+ only neutral `RuntimeSettings`. Concrete defaults remain composition-owned;
20
+ public configuration and Runtime reset behavior remain unchanged.
21
+
14
22
  ## Context
15
23
 
16
24
  `Configuration` holds settings read by Engine and other framework components.
@@ -72,7 +80,10 @@ runtime factory invocation. Construction does not call `Runtime.instance`:
72
80
  the adapter's default pool is acquired later when an async method is called.
73
81
  The previous graph cycle was not infinite constructor recursion.
74
82
 
75
- `LLMAdapter::Base` still owns framework async wrappers and references Runtime.
83
+ At this decision's implementation point, `LLMAdapter::Base` still owned the
84
+ framework async wrappers and referenced Runtime.
85
+ [ADR-059](059-backend-contracts-and-async-clients.md) subsequently moves that
86
+ dependency to the private `LLMAdapter::AsyncClient`.
76
87
  Runtime, pools, tracing, and Agent retain other dependencies and cycles. This
77
88
  step does not claim complete provider independence or an acyclic repository.
78
89
 
@@ -5,6 +5,10 @@
5
5
  **Refines**: [024-event-loop-single-writer-agent-runtime](024-event-loop-single-writer-agent-runtime.md)
6
6
  and [038-responsibility-based-source-layout](038-responsibility-based-source-layout.md)
7
7
 
8
+ Source placement is superseded by [ADR-063](063-execution-contracts-and-services.md):
9
+ the same marker now lives in `execution/concurrency/`. Its namespace,
10
+ 18-type inventory and worker-input behavior remain unchanged.
11
+
8
12
  ## Problem
9
13
 
10
14
  Tool authorization snapshots exclude framework-managed live objects from value
@@ -1,5 +1,7 @@
1
1
  # ADR-051: Execution Outcome Worker Ownership
2
2
 
3
+ > Handoff specialization and commit proof are amended by [ADR-064](064-agent-execution-and-multi-agent-responsibility.md).
4
+
3
5
  **Status**: Accepted on the architecture refactoring branch
4
6
  **Date**: 2026-09-22
5
7
  **Refines**: [024-event-loop-single-writer-agent-runtime](024-event-loop-single-writer-agent-runtime.md),
@@ -30,7 +30,7 @@ The private session protocol is:
30
30
  - `handles?(event)` recognizes a policy event, including an early event that
31
31
  must be discarded by the session before any terminal request.
32
32
  - `decision_for(event)` interprets an accepted event and returns the immutable
33
- `FSMProtocol::TerminalDecision(action:, error:)` value.
33
+ `Phronomy::TerminalDecision(action:, error:)` value.
34
34
 
35
35
  WorkflowTerminalPolicy maps success to `complete`, known failure to `fail` with
36
36
  its original error or the existing fallback error, and outcome unknown to
@@ -6,6 +6,11 @@ Accepted. Applied and verified in Refactor 35 (Storage S2b/S2c), core
6
6
  `ebd99623f94c8b2db2d74355bfa39f01550778a0` and examples
7
7
  `68a0bbd0e354b9e00bbfed728ad2b769b389ed8a`.
8
8
 
9
+ Domain-facing exception ownership is further amended by
10
+ [061-persistence-failure-contracts](061-persistence-failure-contracts.md).
11
+ Raw backend exceptions remain owned by Storage; domain repository exits now
12
+ translate their known categories to independent Persistence exceptions.
13
+
9
14
  ## Context
10
15
 
11
16
  S1 inventoried 37 raw methods across eight required domain slots. Moving their
@@ -0,0 +1,74 @@
1
+ # ADR-059: Backend Contracts, Implementations and Execution Clients
2
+
3
+ ## Status
4
+
5
+ Accepted; P1/P2/P3/P4 (LLM, VectorStore, Embeddings, Storage/ContentStore and
6
+ diagram tooling) implemented. Final P5 review remains pending, as recorded in
7
+ [Backend responsibilities](../architecture/backend-groups.md).
8
+
9
+ ContentStore's classification and directory split are superseded by
10
+ [ADR-062](062-content-store-service.md): content management is a service over
11
+ Storage, outside Backend Contracts and Backend Implementations. The other
12
+ contract/client/backend separations remain in force.
13
+
14
+ ## Context
15
+
16
+ The synchronous LLMAdapter SPI and its RubyLLM implementation shared a directory
17
+ with private async methods that referenced Runtime. Adapter authors were told
18
+ to implement only synchronous methods, but Base still coupled the SPI to Engine.
19
+ Numbered diagram bands also implied an ordering between independent concerns.
20
+
21
+ ## Decision
22
+
23
+ 1. Use independent responsibility groups with stable identifiers. Engine,
24
+ Contracts, Async Clients and Implementations are distinct; coordinates and
25
+ group numbers do not define dependency permissions. For readability, restore
26
+ the earlier B1-B6 horizontal display bands and topical columns; these are
27
+ presentation metadata independent of the responsibility annotations. Place
28
+ separated Contracts in B5, distinct from Engine, and Async Clients in B4.
29
+ Keep Implementations separately grouped in B4; mark unsplit backends there
30
+ as pending instead of presenting their contracts as already separated.
31
+ 2. Keep `LLMAdapter::Base` synchronous. Move internal async wrappers into
32
+ `LLMAdapter::AsyncClient`; Agent supplies its configured adapter to the client.
33
+ The public SPI, configuration setting and RubyLLM constant remain unchanged.
34
+ 3. Separate contract/client/implementation directories, using explicit Zeitwerk
35
+ collapse to retain feature namespaces. Do not make a common Async namespace,
36
+ add a Base-to-client factory, or install an include/prepend compatibility hook.
37
+ 4. Implementations depend on Contracts. Contracts and implementations do not
38
+ reference Engine or clients; clients use Contracts and Engine through normal
39
+ constant references or object injection, without selecting concrete providers.
40
+ 5. Preserve original TaskResult, non-waiting admission failure, token semantics,
41
+ no additional operation timeout, provider-owned retries and EventLoop callback
42
+ delivery. Resolve the default pool at operation time; do not cache it across
43
+ Runtime resets. Explicit pool injection leaves lifecycle ownership to its owner.
44
+ 6. Generate SVG and boundary evidence from each committed source revision.
45
+ Maintain the individual module boxes, IDs, full dependency matrix and source
46
+ evidence. A phase cannot declare completion while legacy dependencies remain.
47
+
48
+ The vector/embedding SPI and namespace clauses are amended by
49
+ [ADR-065](065-vector-and-embeddings-common-operations.md).
50
+
51
+ ## Consequences
52
+
53
+ This supersedes the remaining LLM Base-to-Runtime coupling described in ADR-040.
54
+ ADR-027's synchronous public provider-call boundary and materialization caveat
55
+ still apply: this change does not make RubyLLMMaterializer provider-neutral.
56
+ P2 keeps the LLM client internal. P3 introduces public VectorStore/Embeddings
57
+ AsyncClients and moves async receivers off the synchronous backends. Their
58
+ argument conventions and execution semantics are unchanged; the receiver
59
+ migration is intentional and documented. Storage operations do not change in
60
+ P3. P4 adds public raw `transaction_async` and a private submit path for existing
61
+ Agent/Workflow/coordination units. The latter opens no transaction and leaves
62
+ uncertain-result policy with each owner. P4 originally moved ContentStore's
63
+ implementation into a backend directory; ADR-062 removes that unnecessary split
64
+ and classifies it as a content service. Other repository cycles remain visible.
65
+
66
+ Transparent module/caption panels and hidden incoming arrows to M33/M41/M44 are
67
+ presentation settings only. The full measured graph, matrix and boundary rules
68
+ remain unchanged by that filtering.
69
+
70
+ Boundary tests cover direct and indirect reverse dependencies and keep group
71
+ IDs independent from policy. Runtime tests cover sync-only custom adapters,
72
+ worker/EventLoop separation, rejection, exceptions, cancellation and Runtime
73
+ reset. CI produces artifacts with the actual source SHA rather than committing
74
+ a diagram containing its own commit hash.
@@ -0,0 +1,86 @@
1
+ # ADR-060: Runtime Settings and Application Configuration
2
+
3
+ ## Status
4
+
5
+ The settings membership is amended by
6
+ [r8 unit21](../architecture/r8-unit21.md): Tool owns its result limit and Tracing
7
+ owns tracer/recording settings. RuntimeSettings retains logger and execution
8
+ resource values. The original decision below records the earlier checkpoint;
9
+ lazy composition, public compatibility and the strict dependency rules remain.
10
+
11
+ Accepted for this refactoring. Amends the configuration ownership in
12
+ [038-responsibility-based-source-layout](038-responsibility-based-source-layout.md),
13
+ [039-runtime-configuration-lifecycle-ownership](039-runtime-configuration-lifecycle-ownership.md)
14
+ and [040-configuration-default-composition](040-configuration-default-composition.md).
15
+
16
+ ## Context
17
+
18
+ Engine consumes pool sizes, time thresholds, a logger and an injected tracer.
19
+ Application `Configuration` also exposes an LLM adapter, Agent input hook and
20
+ other domain options. Their correct public RBS types reveal an Engine-to-domain
21
+ path when Engine reads the whole Configuration. A two-reference baseline allowed
22
+ this old type debt through the regression gate. Weakening the types, hiding
23
+ arrows or misassigning RBS owners would not repair the dependency.
24
+
25
+ ## Decision
26
+
27
+ 1. `configuration/` owns private `RuntimeSettings`: neutral runtime values and
28
+ injected logger/tracer objects, with no application-specific type references.
29
+ Engine and automatic tracing read this limited object.
30
+ 2. Application `Configuration` and the global `configuration`, `configure`,
31
+ `reset_configuration!` and `with_configuration` operations belong to
32
+ `runtime_composition/`. Canonical Ruby names, constructor and public RBS types
33
+ remain unchanged. The directory is collapsed by Zeitwerk; no public
34
+ `RuntimeComposition` namespace is introduced.
35
+ 3. Configuration composes RuntimeSettings and explicitly delegates its existing
36
+ runtime-setting accessors. It retains adapter, Agent and application options.
37
+ RBS follows the actual Ruby owner: application declarations live under
38
+ `sig/phronomy/runtime_composition/`, internal settings under `sig/_private/`.
39
+ 4. Composition installs a lazy, typed provider returning only RuntimeSettings.
40
+ Every read resolves the current object so reset/scoped restoration cannot
41
+ leave Engine reading an expired configuration. Binding does not initialize
42
+ global configuration or start Runtime. This provider is private framework
43
+ wiring, not an application extension point or a new execution service.
44
+ 5. Copying Configuration copies its settings container while retaining injected
45
+ component identities. This preserves the previous flat object's shallow-copy
46
+ behavior, including nested scopes, exception restoration and a first scope
47
+ entered before global configuration exists. This change adds no thread-local
48
+ configuration semantics or live pool resizing.
49
+ 6. Remove the two-reference baseline. Require the complete Ruby + RBS union to
50
+ pass all existing responsibility rules. Also reject settings paths reaching
51
+ any non-common responsibility.
52
+
53
+ ## Direct dependencies are evaluated by responsibility
54
+
55
+ LLM error/TokenUsage contracts are already abstract vocabulary, so routing them
56
+ through a concrete adapter would make coupling worse. Backend implementation,
57
+ schema, migration, async bridge and conformance-suite dependencies on Storage
58
+ contracts are intentional. Domain repositories translate records, guards and
59
+ backend errors and legitimately know that SPI.
60
+
61
+ Domain runners that raise StorageConflictError for ownership/revision decisions
62
+ are a separate candidate for a persistence/domain error contract. Existing
63
+ recovery distinguishes known failure from uncertain commit outcomes; introduce
64
+ such a vocabulary only with an explicit compatibility and failure-classification
65
+ design. Do not substitute a forwarding wrapper or broadly catch StandardError.
66
+
67
+ Engine's TaskResult, Runnable and FSM contracts are the execution abstractions
68
+ used by runners and async clients. A higher-level Agent facade is not a
69
+ replacement for the mechanism that implements Agent itself. Ordinary synchronous
70
+ evaluation work can use `Blocking.call_async`: LlmJudge now does so instead of
71
+ accessing Runtime's pool. Dedicated-pool cleanup, concurrency-limited orchestration
72
+ and tracing with nonwaiting admission handling retain their specialized owners.
73
+
74
+ ## Verification and graph interpretation
75
+
76
+ Preserve public signature declarations, settings defaults/accessor semantics,
77
+ subclass construction, cold loading, reset/scoped restoration and runtime pool
78
+ configuration. Check scorer provider/admission failures, the full regression
79
+ suite, RBS validation and strict dependency rules. No network provider is needed
80
+ for these behavior checks.
81
+
82
+ SVG topology must show the actual declaration owners and keep all evidence,
83
+ even for display-hidden arrows. Application configuration shares the composition
84
+ directory with lifecycle/default wiring; its directory SCC may grow because
85
+ unrelated members aggregate. Report directory SCCs and Ruby file SCCs separately;
86
+ do not claim that all cycles have disappeared or that fewer arrows is the goal.
@@ -0,0 +1,89 @@
1
+ # ADR-061: Domain Persistence failure contracts
2
+
3
+ - Status: Accepted
4
+ - Date: 2026-09-26
5
+ - Amends: [032-storage-backend-composition](032-storage-backend-composition.md) and [058-neutral-storage-primitives](058-neutral-storage-primitives.md), only for the exception surface exposed above raw Storage.
6
+
7
+ ## Context
8
+
9
+ Agent execution, ownership, Handoff, Recovery, Team coordination and Workflow
10
+ interpret durable failures, but previously referenced raw Storage exception
11
+ classes even when they did not perform raw storage operations. A domain state
12
+ contradiction and a physical compare-and-swap rejection had the same owner.
13
+ Moving or aliasing those classes would keep backend and domain contracts coupled.
14
+
15
+ ## Decision
16
+
17
+ Define independent public errors in `persistence/contract/`, under the existing
18
+ `Phronomy::Persistence` namespace: Error, ConflictError, StateConflictError,
19
+ NotFoundError, SerializationError and UnsupportedBackendError. Error inherits
20
+ Phronomy::Error. StateConflictError inherits Persistence::ConflictError; the other
21
+ four categories inherit Persistence::Error. No class inherits a Storage error,
22
+ and no compatibility alias is introduced. The contract depends only on Common.
23
+
24
+ The selected upper domain consumers raise StateConflictError for their own
25
+ ownership/revision/state contradictions. Backend CAS conflicts, including
26
+ repository precondition conflicts, expose Persistence::ConflictError. Existing
27
+ conflict retry/catch sites also accept StateConflictError by inheritance.
28
+
29
+ An internal `Persistence::StorageBoundary` maps exactly four Storage categories
30
+ (ConflictError, NotFoundError, SerializationError, UnsupportedBackendError) to
31
+ the corresponding Persistence category. It preserves message and backtrace and
32
+ sets the original exception as `cause`. Mapping happens at domain repository
33
+ exits and Persistence construction/transaction exits. Existing repository-local
34
+ constraint interpretation runs first: only the matching active-owner unique
35
+ constraint or exact NoRows condition becomes AgentBusyError. Other raw conflict
36
+ subclasses map to Persistence::ConflictError with their metadata in `cause`.
37
+
38
+ Domain repositories continue to own codecs and record validation. Decode checks
39
+ remain inside the physical atomic block, so a malformed write response still
40
+ rolls back before translation. The translator creates no transaction or task.
41
+ The same boundary covers root and transaction repository views, watermark checks,
42
+ and persisted manifest reading. A private ContentRepository adapts the existing
43
+ StoredContents primitive methods for the upper failure contract; the independent
44
+ ContentStore backend retains its content identity and integrity semantics.
45
+
46
+ Unknown exceptions, Storage::TransactionError, ContentStore::IntegrityError,
47
+ AgentBusyError and already translated Persistence errors pass through unchanged.
48
+ Persistence::Error is a base type, not a blanket known-not-committed classifier.
49
+ Each existing caller retains its exact category set, including intentional
50
+ three-category/four-category differences and ArgumentError/ConfigurationError.
51
+ A lost commit acknowledgement must not become a known rejection or trigger a
52
+ new retry. F0/F1/F4 recovery and X0 limitations are unchanged.
53
+
54
+ ## Loading and ownership
55
+
56
+ Contracts can be loaded without Storage, Engine, Agent or a driver. Ordinary
57
+ framework loading explicitly installs the canonical Persistence service before
58
+ Zeitwerk setup, so an earlier contract load cannot suppress service methods or
59
+ change class identity. This does not construct a backend or start a Runtime.
60
+ The API class is still defined in `persistence/api/persistence.rb`. Namespace
61
+ reopenings in helpers are not its declaration owner for dependency analysis.
62
+
63
+ ## Public migration and preservation
64
+
65
+ Calls through Persistence now expose Persistence errors rather than Storage
66
+ errors. This is an intentional public exception contract change; applications
67
+ must migrate relevant rescue clauses. Raw backend/driver code keeps Storage
68
+ errors. See the [migration guide](../migrations/persistence-failure-contracts.md).
69
+
70
+ Existing public method/RBS declarations remain; six error classes are added.
71
+ SPI 2, tables, record envelopes, revisions, content IDs and all eight repository
72
+ transaction semantics remain unchanged. Stored error class names are diagnostic
73
+ data: new failures may name Persistence errors, while old saved names remain
74
+ readable without rewriting or constantizing them.
75
+
76
+ ## Verification and diagram
77
+
78
+ Tests inject real backend failures through all eight repository accessors and
79
+ check cause/trace, no double translation, unknown-error identity, commit-response
80
+ loss, nested savepoints, post-write validation rollback and AgentBusyError.
81
+ Existing domain recovery, admission, conformance and integration suites remain
82
+ required. Raw Storage isolation tests continue to reject domain/Engine loading.
83
+
84
+ Ruby + RBS boundary validation rejects raw Storage references from the eight
85
+ reviewed upper directories and rejects non-Common reachability from Persistence
86
+ Contracts. It does not whitelist the new dependencies. G55 shows the translation
87
+ boundary and G56 the independent domain failure contracts in the existing banded
88
+ layout. All measured edges remain in evidence and the matrix; presentation-only
89
+ incoming-arrow filters do not change boundary results.
@@ -0,0 +1,52 @@
1
+ # ADR-062: ContentStore is a content service over Storage
2
+
3
+ - Status: Accepted
4
+ - Date: 2026-09-28
5
+ - Amends: ADR-059's ContentStore classification and source subdivision only.
6
+
7
+ ## Context
8
+
9
+ ContentStore was grouped with synchronous backend contracts, and StoredContents
10
+ with physical backend implementations. InMemory and SQL instead implement
11
+ Storage::Backend. Composition always constructs StoredContents over that
12
+ backend's view. ContentStore adds content-derived IDs, canonical text/JSON and
13
+ digest verification; it is not another physical-storage selection point.
14
+
15
+ ## Decision
16
+
17
+ Treat `content_store/` as a content management service. Move StoredContents from
18
+ `content_store/backends/` into this directory, next to Base and StorageSchema.
19
+ Delete the empty backend subdivision and its Zeitwerk collapse, without a
20
+ forwarding file, alias or alternative implementation-selection API.
21
+
22
+ Keep Base: both StoredContents and Persistence::ContentRepository use its shared
23
+ text/JSON operations. Keep ContentRepository: it translates known Storage
24
+ failures at the Persistence boundary. These classes are used responsibilities,
25
+ not obsolete backend scaffolding. StorageSchema is owned by the content service.
26
+
27
+ Retain the dependency from the service to neutral Storage. Storage owns physical
28
+ I/O, immutable blobs and transactions. The content service must not select a
29
+ physical backend or depend on Engine, Async Clients or domain orchestration;
30
+ Storage contracts and implementations must not depend on the content service.
31
+
32
+ ## Compatibility and presentation
33
+
34
+ Public constants and RBS, private constant identities, content IDs, resource IDs,
35
+ database schema, exception behavior and root/transaction composition stay the
36
+ same. In particular, StoredContents' missing-content errors are still raw Storage
37
+ errors, translated by the Persistence facade. This change does not introduce an
38
+ independent ContentStore exception contract or alter commit uncertainty policy.
39
+
40
+ M10 moves to G57 Content Service, displayed in B3's persistence column. M73 is
41
+ retired and never reused. G47/G48 contain no ContentStore modules. Keep the
42
+ existing banded layout, group colors, module outlines, transparent text panels
43
+ and presentation-only common-arrow filters. Preserve every measured Ruby/RBS
44
+ edge, including the service-to-Storage edge; compare counts knowing that two
45
+ source directories have become one. Historical baseline evidence is immutable.
46
+
47
+ ## Verification
48
+
49
+ Existing loading, content, Persistence conformance and transaction tests cover
50
+ the source move. The full Ruby + RBS boundary gate allows the intended Storage
51
+ dependency and rejects direct/indirect reverse or concrete-backend coupling.
52
+ The independent architecture regression also injects RBS-only violations.
@@ -0,0 +1,88 @@
1
+ # ADR-063: Execution Contracts, Services and Engine Internals
2
+
3
+ > Historical decision. Superseded by [r8 unit 1](../architecture/r8-unit1.md): Execution contracts and services are now united, with mechanism binding in Engine.
4
+
5
+ **Status**: Accepted for implementation
6
+ **Date**: 2026-09-28
7
+ **Refines**: [038-source-layout](038-responsibility-based-source-layout.md),
8
+ [045-worker-input](045-worker-input-restriction-ownership.md) and
9
+ [059-backend-groups](059-backend-contracts-and-async-clients.md)
10
+
11
+ ## Problem
12
+
13
+ Engine grouped public result/call APIs, shared value/error/marker contracts and
14
+ private schedulers together. A WorkerInputRestricted include or an RBS token
15
+ reference consequently appeared to be a dependency on worker machinery.
16
+ ToolBinding also implemented its own result transformation. It forwarded the
17
+ source's physical-completion signal before the result filter had finished;
18
+ Agent execution quiescence could therefore observe an incomplete transformation
19
+ as physically complete.
20
+
21
+ ## Decision
22
+
23
+ Keep public constants and split source ownership into three responsibility groups:
24
+
25
+ | Group | Directory | Owns |
26
+ |---|---|---|
27
+ | G58 Execution Contracts | `execution_contract/`, `execution_contract/concurrency/` | Runnable, InvocationContext, Event, FSMProtocol, shared failures, CancellationToken and WorkerInputRestricted |
28
+ | G59 Execution Services | `execution_services/` | TaskResult, Execution, Blocking, and outcome-bearing execution errors |
29
+ | G14 Engine Internals | `engine/`, `engine/concurrency/`, `engine/runtime/` | Runtime, EventLoop, FSMSession, receivers, pools, queues and control/result-composition machinery |
30
+
31
+ Zeitwerk collapses the two new root directories. Existing `Phronomy::*` and
32
+ `Phronomy::Concurrency::*` constants keep their identity, signatures and
33
+ behavior. No new public namespace or forwarding file is introduced. Public RBS
34
+ declarations remain in `sig/` but follow their actual source owners.
35
+
36
+ Contracts may depend only on Execution Contracts and Common responsibilities,
37
+ including neutral RuntimeSettings. This is a boundary contract, not a claim
38
+ that every class is methodless: CancellationToken retains its existing state
39
+ and callbacks, and Runnable retains its default tracing switch. InvocationContext
40
+ can carry opaque execution bindings without constructing a scheduler.
41
+
42
+ Execution Services contain real implementation. TaskResult uses Engine's result
43
+ composition and wait guards; Engine pools create TaskResults. This mutual
44
+ dependency remains explicit. The split does not assert an acyclic layer
45
+ hierarchy. Backend Contracts and implementations may not reach either services
46
+ or Engine, including through RBS references.
47
+
48
+ ToolBinding delegates callback-based transformation to a private TaskResult
49
+ entry point backed by ResultComposition. Physical completion now requires both
50
+ source physical completion and transformation completion. The callback-only
51
+ path preserves custom result handles, failure identity, name, no inherited
52
+ execution scope, and the existing behavior that cancelling the filtered result
53
+ does not cancel its source or suppress the later filter. Public map/flat_map
54
+ scope and parent semantics are unchanged.
55
+
56
+ Tracing finish and approval notification use Blocking.call_async for generic
57
+ default-pool work. Both observe the returned failure because Blocking converts
58
+ admission errors into failed results. Approval callbacks that fail after dispatch
59
+ are now also logged. Checks that only ask whether code runs on EventLoop use
60
+ Runtime.in_event_loop_context?, avoiding construction of a Runtime merely to
61
+ answer that question.
62
+
63
+ ## Retained direct dependencies
64
+
65
+ AsyncClients are execution bridges and retain Runtime/pool access, specialized
66
+ pools, tokens and result types. Agent/Workflow runners and registries still own
67
+ FSM sessions, control delivery, single-writer state and lifecycle coordination.
68
+ Replacing these with a generic wrapper would conceal required ownership rather
69
+ than remove it. Registry receiver lookup is not redesigned in this change.
70
+ See the [usage inventory](../architecture/execution-boundaries.md).
71
+
72
+ ## Compatibility and verification
73
+
74
+ `require "phronomy"` remains the public loading contract. Old implementation
75
+ file paths move without compatibility shims. Public signatures and API snapshot,
76
+ transactions, pool admission policy and timeout/cancellation ownership are
77
+ unchanged. No backend author must implement another async method.
78
+
79
+ Test blocked success/failure filters against a real pool, cancellation and custom
80
+ completion handles; rejected tracing/approval dispatch and asynchronous callback
81
+ failure; standalone marker loading and eager loading without Runtime creation;
82
+ the public signatures and full Ruby/RBS boundary graph. Existing unit,
83
+ integration, coverage, style, benchmark and SQLite contracts remain required.
84
+
85
+ The measured SVG retains B1-B6 display bands, pastel group backgrounds, module
86
+ boxes and transparent text. G59 is in B4 and G58 in B5; these positions grant
87
+ no dependency permission. Incoming M33/M41/M44 arrows remain visually hidden
88
+ while every dependency stays in the matrix, audit and boundary checks.
@@ -0,0 +1,36 @@
1
+ # ADR-064: Agent execution and MultiAgent responsibility
2
+
3
+ Status: accepted for the r8 unit 4 implementation. This amends the Handoff and
4
+ coordination ownership portions of ADR-030, ADR-031, ADR-034 and ADR-051.
5
+ Acceptance records the authorized design; database validation is reported separately.
6
+
7
+ Agent owns execution identity, durable admission, semantic observations, finalized
8
+ input projection, dispatch prerequisites, terminal changes, retention and
9
+ cancellation intent. MultiAgent owns subagent slot reservations/import progress
10
+ and Handoff policy, routing, target reservations and history lifecycle.
11
+
12
+ A versioned, synchronous participant joins Agent's `ExecutionChange` in one outer
13
+ Persistence scope. It receives semantic inputs, acquires ordered guards, captures
14
+ the pre-state through `prepare_in`, writes its own records and invokes `commit_in`
15
+ once. Agent owns validation, record writes and publication after commit. Complete
16
+ before/after evidence reconciles ambiguous responses; revision equality alone
17
+ does not prove success. No generic raw-record update hook or compatibility alias
18
+ is introduced.
19
+
20
+ Current application wiring is supplied on resume/load and is never serialized.
21
+ A saved extension records only binding key, version and content reference.
22
+ MultiAgent calls exact execution APIs rather than Agent repositories or private
23
+ recovery machinery. Persisted holds prevent purge until the referencing domain
24
+ atomically removes its history and releases its own holds.
25
+
26
+ AgentExecution format 0.2 replaces old coordination metadata. An explicit,
27
+ quiescent export/convert/import/verify process preserves IDs, revisions, content
28
+ and unresolved outcomes in a separate destination. Runtime does not interpret
29
+ old formats. The shared SQL drivers provide runnable migration and rejection of
30
+ populated destinations. The complete migration path must be tested on each
31
+ production backend before cutover.
32
+
33
+ Runtime shutdown/AdmissionRegistry and other Engine dependencies remain later r8
34
+ work. The measured source graph continues to expose them. See
35
+ [implementation responsibilities](../architecture/r8-unit4.md) and
36
+ [API/data migration](../migrations/r8-unit4.md).