phronomy 0.26.0 → 0.28.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 (557) hide show
  1. checksums.yaml +4 -4
  2. data/.mutant.yml +9 -9
  3. data/CHANGELOG.md +92 -0
  4. data/CONTRIBUTING.md +8 -8
  5. data/README.md +13 -3
  6. data/VERIFY.sh +27 -27
  7. data/benchmark/bench_agent_invoke.rb +26 -47
  8. data/benchmark/bench_context_assembler.rb +17 -15
  9. data/benchmark/bench_regression.rb +1 -1
  10. data/benchmark/bench_tool_schema.rb +1 -1
  11. data/docs/architecture/agent-chat-and-state-ownership.md +153 -0
  12. data/docs/architecture/agent-configuration-and-tool-binding.md +139 -0
  13. data/docs/architecture/agent-context.md +4 -2
  14. data/docs/architecture/agent-transition-ownership.md +13 -0
  15. data/docs/architecture/backend-groups.md +152 -0
  16. data/docs/architecture/before-llm-input.md +9 -3
  17. data/docs/architecture/context-management.md +31 -1
  18. data/docs/architecture/context-preparation-steps.md +90 -0
  19. data/docs/architecture/entry-action-and-team-wording.md +72 -0
  20. data/docs/architecture/execution-abstraction-review.md +88 -0
  21. data/docs/architecture/execution-boundaries.md +28 -0
  22. data/docs/architecture/execution-metadata-and-values.md +86 -0
  23. data/docs/architecture/generator-verifier-ownership.md +111 -0
  24. data/docs/architecture/multi-agent-handoff.md +11 -4
  25. data/docs/architecture/persistence-refactoring-plan.md +50 -0
  26. data/docs/architecture/persistence.md +45 -4
  27. data/docs/architecture/r8-unit1.md +104 -0
  28. data/docs/architecture/r8-unit10.md +72 -0
  29. data/docs/architecture/r8-unit11.md +71 -0
  30. data/docs/architecture/r8-unit12.md +67 -0
  31. data/docs/architecture/r8-unit13.md +61 -0
  32. data/docs/architecture/r8-unit14.md +72 -0
  33. data/docs/architecture/r8-unit15.md +65 -0
  34. data/docs/architecture/r8-unit16.md +54 -0
  35. data/docs/architecture/r8-unit17.md +73 -0
  36. data/docs/architecture/r8-unit18.md +92 -0
  37. data/docs/architecture/r8-unit19.md +61 -0
  38. data/docs/architecture/r8-unit2.md +55 -0
  39. data/docs/architecture/r8-unit20.md +51 -0
  40. data/docs/architecture/r8-unit21.md +79 -0
  41. data/docs/architecture/r8-unit22.md +74 -0
  42. data/docs/architecture/r8-unit23.md +81 -0
  43. data/docs/architecture/r8-unit3.md +130 -0
  44. data/docs/architecture/r8-unit4.md +79 -0
  45. data/docs/architecture/r8-unit5.md +115 -0
  46. data/docs/architecture/r8-unit6.md +71 -0
  47. data/docs/architecture/r8-unit7.md +70 -0
  48. data/docs/architecture/r8-unit8.md +78 -0
  49. data/docs/architecture/r8-unit9.md +73 -0
  50. data/docs/architecture/refactoring-closure.md +343 -0
  51. data/docs/architecture/remaining-refactoring-plan.md +390 -0
  52. data/docs/architecture/rubyllm-2-token-ownership.md +82 -0
  53. data/docs/architecture/storage-execution-boundaries.md +54 -0
  54. data/docs/architecture/tool-schema-recording-gap.md +56 -0
  55. data/docs/architecture/tracing.md +2 -2
  56. data/docs/architecture/workflow-terminal-ownership-design.md +104 -0
  57. data/docs/architecture.md +222 -0
  58. data/docs/decisions/014-unified-persistence-durable-state.md +11 -0
  59. data/docs/decisions/015-tool-public-facade-and-rbs-boundary.md +3 -3
  60. data/docs/decisions/024-event-loop-single-writer-agent-runtime.md +5 -1
  61. data/docs/decisions/025-process-local-agent-ownership-and-runtime-admission.md +13 -3
  62. data/docs/decisions/026-workflow-runtime-admission-and-durable-terminal-barrier.md +5 -1
  63. data/docs/decisions/027-llm-adapter-provider-boundary.md +2 -0
  64. data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +7 -0
  65. data/docs/decisions/031-durable-multi-agent-coordination.md +7 -0
  66. data/docs/decisions/032-storage-backend-composition.md +85 -0
  67. data/docs/decisions/033-domain-persistence-ownership.md +79 -0
  68. data/docs/decisions/034-handoff-runner-coordination-ownership.md +78 -0
  69. data/docs/decisions/035-tool-executor-capability-ownership.md +68 -0
  70. data/docs/decisions/036-context-contract-ownership.md +86 -0
  71. data/docs/decisions/037-common-definition-ownership.md +62 -0
  72. data/docs/decisions/038-responsibility-based-source-layout.md +145 -0
  73. data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +82 -0
  74. data/docs/decisions/040-configuration-default-composition.md +105 -0
  75. data/docs/decisions/041-feature-owned-identity-registries.md +100 -0
  76. data/docs/decisions/042-feature-owned-execution-state.md +106 -0
  77. data/docs/decisions/043-storage-execution-constraint-notifications.md +75 -0
  78. data/docs/decisions/044-agent-default-and-one-shot-composition.md +106 -0
  79. data/docs/decisions/045-worker-input-restriction-ownership.md +104 -0
  80. data/docs/decisions/046-agent-responsibility-layout-and-shared-records.md +110 -0
  81. data/docs/decisions/047-recovered-execution-continuation-contract.md +116 -0
  82. data/docs/decisions/048-dispatch-preparation-worker-ownership.md +120 -0
  83. data/docs/decisions/049-initial-preparation-worker-ownership.md +111 -0
  84. data/docs/decisions/050-approval-resume-snapshot-and-commit-ownership.md +98 -0
  85. data/docs/decisions/051-execution-outcome-worker-ownership.md +153 -0
  86. data/docs/decisions/052-tool-invocation-restoration-ownership.md +92 -0
  87. data/docs/decisions/053-shared-state-coordination-ownership.md +71 -0
  88. data/docs/decisions/054-workflow-terminal-save-single-owner.md +76 -0
  89. data/docs/decisions/055-terminal-observer-failure-settlement.md +60 -0
  90. data/docs/decisions/056-workflow-terminal-policy-ownership.md +87 -0
  91. data/docs/decisions/057-storage-transaction-boundaries.md +73 -0
  92. data/docs/decisions/058-neutral-storage-primitives.md +83 -0
  93. data/docs/decisions/059-backend-contracts-and-async-clients.md +74 -0
  94. data/docs/decisions/060-runtime-settings-and-application-configuration.md +86 -0
  95. data/docs/decisions/061-persistence-failure-contracts.md +89 -0
  96. data/docs/decisions/062-content-store-service.md +52 -0
  97. data/docs/decisions/063-execution-contracts-and-services.md +88 -0
  98. data/docs/decisions/064-agent-execution-and-multi-agent-responsibility.md +36 -0
  99. data/docs/decisions/065-vector-and-embeddings-common-operations.md +38 -0
  100. data/docs/decisions/066-llm-and-tool-operation-contracts.md +20 -0
  101. data/docs/decisions/067-agent-progress-and-engine-connection.md +29 -0
  102. data/docs/decisions/068-agent-tool-child-progress-and-tool-operation.md +36 -0
  103. data/docs/decisions/README.md +52 -6
  104. data/docs/design/durable-semantic-coordination/IMPLEMENTATION_DESIGN_V2.md +6 -0
  105. data/docs/design/durable-semantic-coordination/IMPLEMENTATION_REPORT.md +6 -0
  106. data/docs/execution-boundaries-preview.md +45 -0
  107. data/docs/features.md +16 -5
  108. data/docs/getting-started.md +11 -8
  109. data/docs/migrations/0.15.md +5 -0
  110. data/docs/migrations/0.22.md +2 -2
  111. data/docs/migrations/durable-semantic-coordination-v2.md +8 -0
  112. data/docs/migrations/handoff-runner-multi-agent.md +37 -0
  113. data/docs/migrations/neutral-storage-spi.md +43 -0
  114. data/docs/migrations/parallel-tool-chat-removal.md +49 -0
  115. data/docs/migrations/persistence-failure-contracts.md +67 -0
  116. data/docs/migrations/r8-unit10.md +36 -0
  117. data/docs/migrations/r8-unit11.md +33 -0
  118. data/docs/migrations/r8-unit12.md +31 -0
  119. data/docs/migrations/r8-unit13.md +36 -0
  120. data/docs/migrations/r8-unit14.md +31 -0
  121. data/docs/migrations/r8-unit15.md +31 -0
  122. data/docs/migrations/r8-unit16.md +26 -0
  123. data/docs/migrations/r8-unit17.md +28 -0
  124. data/docs/migrations/r8-unit18.md +29 -0
  125. data/docs/migrations/r8-unit19.md +28 -0
  126. data/docs/migrations/r8-unit20.md +24 -0
  127. data/docs/migrations/r8-unit21.md +28 -0
  128. data/docs/migrations/r8-unit22.md +29 -0
  129. data/docs/migrations/r8-unit23.md +20 -0
  130. data/docs/migrations/r8-unit4.md +67 -0
  131. data/docs/migrations/r8-unit5.md +75 -0
  132. data/docs/migrations/r8-unit6.md +109 -0
  133. data/docs/migrations/r8-unit7.md +31 -0
  134. data/docs/migrations/r8-unit8.md +33 -0
  135. data/docs/migrations/r8-unit9.md +28 -0
  136. data/docs/migrations/shared-state-multi-agent.md +44 -0
  137. data/docs/migrations/storage-async-client.md +103 -0
  138. data/docs/migrations/storage-backend-composition.md +117 -0
  139. data/docs/migrations/storage-transaction-boundaries.md +74 -0
  140. data/docs/migrations/vector-async-clients.md +110 -0
  141. data/docs/persistence-backends.md +190 -215
  142. data/docs/runtime-and-concurrency.md +142 -32
  143. data/lib/phronomy/agent/admission.rb +78 -0
  144. data/lib/phronomy/{agent_already_exists_error.rb → agent/agent_already_exists_error.rb} +2 -0
  145. data/lib/phronomy/{agent_busy_error.rb → agent/agent_busy_error.rb} +2 -0
  146. data/lib/phronomy/{agent_purged_error.rb → agent/agent_purged_error.rb} +2 -0
  147. data/lib/phronomy/agent/api/agent.rb +17 -0
  148. data/lib/phronomy/{execution_rehydration_required_error.rb → agent/api/execution_rehydration_required_error.rb} +2 -0
  149. data/lib/phronomy/agent/async_event_api.rb +38 -33
  150. data/lib/phronomy/agent/base.rb +106 -294
  151. data/lib/phronomy/agent/before_llm_input.rb +64 -0
  152. data/lib/phronomy/{agent.rb → agent/composition/run_once.rb} +4 -13
  153. data/lib/phronomy/agent/context_candidate_resolver.rb +2 -2
  154. data/lib/phronomy/agent/context_importer.rb +2 -2
  155. data/lib/phronomy/agent/{context_assembler.rb → context_preparation.rb} +157 -288
  156. data/lib/phronomy/agent/control_request.rb +21 -0
  157. data/lib/phronomy/agent/{agent_execution.rb → execution/agent_execution.rb} +8 -4
  158. data/lib/phronomy/agent/{agent_invocation.rb → execution/agent_invocation.rb} +32 -63
  159. data/lib/phronomy/agent/execution/approval_resume_commit.rb +108 -0
  160. data/lib/phronomy/agent/execution/dispatch_preparation.rb +195 -0
  161. data/lib/phronomy/agent/{exact_execution.rb → execution/exact_execution.rb} +43 -23
  162. data/lib/phronomy/agent/{execution_cancellation.rb → execution/execution_cancellation.rb} +8 -5
  163. data/lib/phronomy/agent/execution/execution_coordinator.rb +1744 -0
  164. data/lib/phronomy/agent/execution/execution_failure.rb +30 -0
  165. data/lib/phronomy/agent/execution/execution_metadata.rb +54 -0
  166. data/lib/phronomy/agent/execution/execution_outcome_committer.rb +288 -0
  167. data/lib/phronomy/agent/execution/execution_registry.rb +463 -0
  168. data/lib/phronomy/agent/execution/execution_session_runner.rb +113 -0
  169. data/lib/phronomy/agent/execution/initial_preparation.rb +323 -0
  170. data/lib/phronomy/agent/execution/invocation_actions.rb +368 -0
  171. data/lib/phronomy/agent/execution/invocation_transitions.rb +124 -0
  172. data/lib/phronomy/agent/execution/runtime_record_encoder.rb +210 -0
  173. data/lib/phronomy/agent/execution_change.rb +161 -0
  174. data/lib/phronomy/agent/execution_environment.rb +36 -0
  175. data/lib/phronomy/agent/execution_extension_state.rb +21 -0
  176. data/lib/phronomy/agent/execution_observation.rb +35 -0
  177. data/lib/phronomy/agent/filterable.rb +182 -0
  178. data/lib/phronomy/agent/{handoff_context.rb → handoff/transfer_context.rb} +6 -6
  179. data/lib/phronomy/agent/{handoff_projection.rb → handoff/transfer_projection.rb} +14 -33
  180. data/lib/phronomy/agent/handoff_error.rb +7 -0
  181. data/lib/phronomy/agent/{journal_projection.rb → journal/journal_projection.rb} +4 -0
  182. data/lib/phronomy/agent/{journal_record.rb → journal/journal_record.rb} +3 -3
  183. data/lib/phronomy/agent/{llm_call_record.rb → journal/llm_call_record.rb} +2 -2
  184. data/lib/phronomy/agent/knowledge_item.rb +13 -0
  185. data/lib/phronomy/agent/{agent_root.rb → lifecycle/agent_root.rb} +6 -2
  186. data/lib/phronomy/agent/lifecycle/default_persistence.rb +29 -0
  187. data/lib/phronomy/{engine/runtime/agent_ownership_registry.rb → agent/lifecycle/ownership_registry.rb} +24 -15
  188. data/lib/phronomy/agent/persistence/agent_repository.rb +69 -0
  189. data/lib/phronomy/agent/persistence/cancellation_repository.rb +51 -0
  190. data/lib/phronomy/agent/persistence/codec.rb +338 -0
  191. data/lib/phronomy/agent/persistence/execution_repository.rb +124 -0
  192. data/lib/phronomy/agent/persistence/journal_repository.rb +63 -0
  193. data/lib/phronomy/agent/persistence/records.rb +33 -0
  194. data/lib/phronomy/agent/persistence/retention_repository.rb +70 -0
  195. data/lib/phronomy/agent/persistence/storage_schema.rb +29 -0
  196. data/lib/phronomy/agent/persistence/watermark.rb +29 -0
  197. data/lib/phronomy/agent/recovery/invocation_restorer.rb +124 -0
  198. data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/continuation.rb +28 -51
  199. data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/installation.rb +50 -55
  200. data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/resolution.rb +38 -43
  201. data/lib/phronomy/agent/{recovery_coordinator.rb → recovery/recovery_coordinator.rb} +26 -23
  202. data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
  203. data/lib/phronomy/agent/recovery/recovery_support.rb +224 -0
  204. data/lib/phronomy/agent/reserved_execution.rb +16 -0
  205. data/lib/phronomy/agent/retention.rb +17 -0
  206. data/lib/phronomy/agent/runtime_binding/engine_environment.rb +60 -0
  207. data/lib/phronomy/agent/runtime_binding/engine_session_builder.rb +34 -0
  208. data/lib/phronomy/agent/runtime_binding/phase_machine_builder.rb +64 -0
  209. data/lib/phronomy/agent/runtime_binding/tool_session_builder.rb +34 -0
  210. data/lib/phronomy/agent/{ruby_llm_materializer.rb → runtime_input.rb} +19 -39
  211. data/lib/phronomy/agent/saved_context_reader.rb +55 -0
  212. data/lib/phronomy/agent/settings.rb +47 -0
  213. data/lib/phronomy/agent/state_writer.rb +166 -0
  214. data/lib/phronomy/agent/store.rb +253 -0
  215. data/lib/phronomy/{stream_callback_error.rb → agent/stream_callback_error.rb} +2 -0
  216. data/lib/phronomy/agent/{approval_evaluation_request.rb → tool_execution/approval_evaluation_request.rb} +1 -12
  217. data/lib/phronomy/agent/{tool_approval_request.rb → tool_execution/tool_approval_request.rb} +1 -10
  218. data/lib/phronomy/agent/tool_execution/tool_binding.rb +30 -0
  219. data/lib/phronomy/agent/{tool_invocation.rb → tool_execution/tool_invocation.rb} +114 -248
  220. data/lib/phronomy/agent/tool_execution/tool_invocation_actions.rb +107 -0
  221. data/lib/phronomy/agent/tool_execution/tool_invocation_transitions.rb +70 -0
  222. data/lib/phronomy/common/configuration_error.rb +7 -0
  223. data/lib/phronomy/common/error.rb +5 -0
  224. data/lib/phronomy/{agent → common/values}/immutable.rb +9 -1
  225. data/lib/phronomy/common/values/serializable.rb +32 -0
  226. data/lib/phronomy/configuration/runtime_settings.rb +49 -0
  227. data/lib/phronomy/content_store/storage_schema.rb +12 -0
  228. data/lib/phronomy/content_store/stored_contents.rb +44 -0
  229. data/lib/phronomy/context/assembly.rb +202 -0
  230. data/lib/phronomy/{context_budget_exceeded_error.rb → context/budget_exceeded_error.rb} +5 -1
  231. data/lib/phronomy/context/candidate.rb +51 -0
  232. data/lib/phronomy/context/constraint.rb +47 -0
  233. data/lib/phronomy/{agent → context}/context_plan.rb +2 -2
  234. data/lib/phronomy/{agent → context}/context_plan_validator.rb +3 -3
  235. data/lib/phronomy/{agent → context}/context_policy.rb +1 -1
  236. data/lib/phronomy/{agent → context}/context_policy_input.rb +7 -7
  237. data/lib/phronomy/{agent → context}/context_policy_input_builder.rb +1 -1
  238. data/lib/phronomy/context/default_policy.rb +140 -0
  239. data/lib/phronomy/context/final_budget_validator.rb +33 -0
  240. data/lib/phronomy/{agent → context}/llm_input_build_context.rb +2 -2
  241. data/lib/phronomy/{agent → context}/llm_input_manifest.rb +21 -21
  242. data/lib/phronomy/{agent → context}/llm_input_patch.rb +3 -3
  243. data/lib/phronomy/context/manifest_error.rb +10 -0
  244. data/lib/phronomy/context/prompt_template.rb +98 -0
  245. data/lib/phronomy/{vector_store → documents}/loader/base.rb +1 -1
  246. data/lib/phronomy/{vector_store → documents}/loader/csv_loader.rb +2 -2
  247. data/lib/phronomy/{vector_store → documents}/loader/markdown_loader.rb +3 -3
  248. data/lib/phronomy/{vector_store → documents}/loader/plain_text_loader.rb +2 -2
  249. data/lib/phronomy/{vector_store → documents}/splitter/base.rb +1 -1
  250. data/lib/phronomy/{vector_store → documents}/splitter/fixed_size_splitter.rb +2 -2
  251. data/lib/phronomy/{vector_store → documents}/splitter/recursive_splitter.rb +2 -2
  252. data/lib/phronomy/embeddings/async/async_client.rb +44 -0
  253. data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +48 -0
  254. data/lib/phronomy/embeddings/base.rb +43 -0
  255. data/lib/phronomy/embeddings/invalid_result_error.rb +11 -0
  256. data/lib/phronomy/embeddings/transport_error.rb +11 -0
  257. data/lib/phronomy/engine/concurrency/offload_pool.rb +39 -20
  258. data/lib/phronomy/engine/concurrency/pool_registry.rb +47 -12
  259. data/lib/phronomy/{diagnostics.rb → engine/diagnostics.rb} +1 -1
  260. data/lib/phronomy/engine/event_loop.rb +164 -630
  261. data/lib/phronomy/engine/execution_binding.rb +23 -0
  262. data/lib/phronomy/engine/execution_receiver_binding.rb +43 -0
  263. data/lib/phronomy/engine/fsm_protocol.rb +9 -0
  264. data/lib/phronomy/engine/fsm_session.rb +37 -30
  265. data/lib/phronomy/engine/metrics.rb +28 -0
  266. data/lib/phronomy/engine/runtime/timer_queue.rb +1 -1
  267. data/lib/phronomy/engine/runtime.rb +104 -95
  268. data/lib/phronomy/engine/terminal_decision.rb +7 -0
  269. data/lib/phronomy/execution/async_operation.rb +41 -0
  270. data/lib/phronomy/execution/backpressure_error.rb +7 -0
  271. data/lib/phronomy/{blocking.rb → execution/blocking.rb} +2 -2
  272. data/lib/phronomy/execution/cancellation_error.rb +7 -0
  273. data/lib/phronomy/{engine → execution}/concurrency/cancellation_token.rb +5 -1
  274. data/lib/phronomy/{engine → execution}/concurrency/deadline.rb +0 -17
  275. data/lib/phronomy/{engine → execution}/concurrency/physical_completion_task.rb +1 -1
  276. data/lib/phronomy/{engine → execution}/concurrency/result_collector.rb +1 -1
  277. data/lib/phronomy/{engine → execution}/concurrency/result_composition.rb +33 -12
  278. data/lib/phronomy/{engine/concurrency/subscriptions.rb → execution/concurrency/result_subscriptions.rb} +14 -18
  279. data/lib/phronomy/execution/concurrency/subscriptions.rb +25 -0
  280. data/lib/phronomy/execution/concurrency/worker_input_restricted.rb +14 -0
  281. data/lib/phronomy/execution/event_loop_reentrancy_error.rb +8 -0
  282. data/lib/phronomy/{execution.rb → execution/execution.rb} +57 -30
  283. data/lib/phronomy/{execution_cancellation_error.rb → execution/execution_cancellation_error.rb} +2 -0
  284. data/lib/phronomy/execution/execution_receiver.rb +78 -0
  285. data/lib/phronomy/execution/execution_scope_state.rb +35 -0
  286. data/lib/phronomy/{execution_timeout_error.rb → execution/execution_timeout_error.rb} +2 -0
  287. data/lib/phronomy/{invalid_async_entry_action_error.rb → execution/invalid_async_entry_action_error.rb} +2 -0
  288. data/lib/phronomy/{invalid_async_transition_action_error.rb → execution/invalid_async_transition_action_error.rb} +2 -0
  289. data/lib/phronomy/{invalid_async_workflow_action_error.rb → execution/invalid_async_workflow_action_error.rb} +2 -0
  290. data/lib/phronomy/{invocation_context.rb → execution/invocation_context.rb} +0 -15
  291. data/lib/phronomy/execution/invocation_controls.rb +73 -0
  292. data/lib/phronomy/execution/pool_shutdown_error.rb +7 -0
  293. data/lib/phronomy/execution/recursion_limit_error.rb +7 -0
  294. data/lib/phronomy/execution/runnable.rb +24 -0
  295. data/lib/phronomy/execution/runtime_shutdown_error.rb +7 -0
  296. data/lib/phronomy/execution/runtime_shutdown_reentrancy_error.rb +7 -0
  297. data/lib/phronomy/execution/scheduler_reentrancy_error.rb +9 -0
  298. data/lib/phronomy/{engine → execution}/task_result.rb +7 -3
  299. data/lib/phronomy/execution/timeout_error.rb +7 -0
  300. data/lib/phronomy/execution/wait_policy.rb +24 -0
  301. data/lib/phronomy/filter/filter_block_error.rb +14 -0
  302. data/lib/phronomy/generation/generator_verifier/agent_operation.rb +65 -0
  303. data/lib/phronomy/generation/generator_verifier/agent_result_receiver.rb +89 -0
  304. data/lib/phronomy/generation/generator_verifier/default_parser.rb +27 -0
  305. data/lib/phronomy/generation/generator_verifier/pipeline_state.rb +57 -0
  306. data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +112 -0
  307. data/lib/phronomy/generation/generator_verifier.rb +118 -0
  308. data/lib/phronomy/generation/low_confidence_error.rb +14 -0
  309. data/lib/phronomy/llm_adapter/async/async_client.rb +47 -0
  310. data/lib/phronomy/llm_adapter/authentication_error.rb +9 -0
  311. data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +183 -0
  312. data/lib/phronomy/llm_adapter/base.rb +49 -68
  313. data/lib/phronomy/llm_adapter/context_length_error.rb +9 -0
  314. data/lib/phronomy/llm_adapter/invalid_result_error.rb +10 -0
  315. data/lib/phronomy/llm_adapter/message.rb +62 -0
  316. data/lib/phronomy/llm_adapter/rate_limit_error.rb +9 -0
  317. data/lib/phronomy/llm_adapter/request.rb +79 -0
  318. data/lib/phronomy/llm_adapter/response.rb +36 -0
  319. data/lib/phronomy/llm_adapter/stream_chunk.rb +18 -0
  320. data/lib/phronomy/llm_adapter/token_usage.rb +64 -0
  321. data/lib/phronomy/llm_adapter/transport_error.rb +9 -0
  322. data/lib/phronomy/llm_adapter.rb +3 -16
  323. data/lib/phronomy/llm_context_window/token_budget.rb +6 -7
  324. data/lib/phronomy/multi_agent/admission_registry.rb +15 -2
  325. data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +108 -84
  326. data/lib/phronomy/multi_agent/execution_environment.rb +29 -0
  327. data/lib/phronomy/{agent → multi_agent}/handoff.rb +2 -2
  328. data/lib/phronomy/{agent → multi_agent}/handoff_capability_factory.rb +21 -2
  329. data/lib/phronomy/multi_agent/handoff_participant.rb +79 -0
  330. data/lib/phronomy/{agent → multi_agent}/handoff_policy.rb +1 -1
  331. data/lib/phronomy/multi_agent/handoff_runner.rb +156 -0
  332. data/lib/phronomy/{agent → multi_agent}/handoff_state.rb +2 -2
  333. data/lib/phronomy/multi_agent/orchestrator.rb +61 -75
  334. data/lib/phronomy/multi_agent/persistence/codec.rb +75 -0
  335. data/lib/phronomy/multi_agent/persistence/handoff_state_repository.rb +77 -0
  336. data/lib/phronomy/multi_agent/persistence/records.rb +27 -0
  337. data/lib/phronomy/multi_agent/persistence/storage_schema.rb +21 -0
  338. data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +124 -0
  339. data/lib/phronomy/multi_agent/persistence/team_repository.rb +69 -0
  340. data/lib/phronomy/multi_agent/reserved_child_admission.rb +88 -0
  341. data/lib/phronomy/multi_agent/runtime_binding/engine_environment.rb +35 -0
  342. data/lib/phronomy/{agent → multi_agent}/shared_state.rb +56 -39
  343. data/lib/phronomy/multi_agent/store.rb +156 -0
  344. data/lib/phronomy/multi_agent/team_coordinator.rb +87 -75
  345. data/lib/phronomy/multi_agent/team_execution.rb +1 -1
  346. data/lib/phronomy/{engine/runtime → multi_agent}/team_ownership_registry.rb +5 -5
  347. data/lib/phronomy/multi_agent/team_root.rb +1 -1
  348. data/lib/phronomy/output_parser/parse_error.rb +7 -0
  349. data/lib/phronomy/persistence/content_repository.rb +26 -0
  350. data/lib/phronomy/persistence/errors.rb +16 -0
  351. data/lib/phronomy/persistence/migration/initial_format_migration.rb +21 -21
  352. data/lib/phronomy/persistence/persistence.rb +23 -0
  353. data/lib/phronomy/persistence/save_outcome.rb +24 -0
  354. data/lib/phronomy/persistence/snapshot_comparison.rb +81 -0
  355. data/lib/phronomy/persistence/storage_boundary.rb +32 -0
  356. data/lib/phronomy/persistence/transaction.rb +86 -0
  357. data/lib/phronomy/persistence_composition/storage_schema.rb +29 -0
  358. data/lib/phronomy/persistence_composition/stores.rb +34 -0
  359. data/lib/phronomy/persistence_composition/unit4_migration.rb +276 -0
  360. data/lib/phronomy/runtime_composition/agent_defaults.rb +11 -0
  361. data/lib/phronomy/runtime_composition/configuration.rb +146 -0
  362. data/lib/phronomy/runtime_composition/configuration_defaults.rb +9 -0
  363. data/lib/phronomy/runtime_composition/evaluation_defaults.rb +7 -0
  364. data/lib/phronomy/runtime_composition/execution_defaults.rb +5 -0
  365. data/lib/phronomy/runtime_composition/generation_defaults.rb +6 -0
  366. data/lib/phronomy/runtime_composition/global_configuration.rb +38 -0
  367. data/lib/phronomy/runtime_composition/global_runtime.rb +19 -0
  368. data/lib/phronomy/runtime_composition/multi_agent_defaults.rb +9 -0
  369. data/lib/phronomy/runtime_composition/workflow_defaults.rb +4 -0
  370. data/lib/phronomy/storage/async/async_client.rb +60 -0
  371. data/lib/phronomy/storage/backend.rb +107 -0
  372. data/lib/phronomy/storage/backends/in_memory.rb +157 -0
  373. data/lib/phronomy/storage/blob_conflict_error.rb +10 -0
  374. data/lib/phronomy/storage/blobs.rb +31 -0
  375. data/lib/phronomy/storage/condition.rb +25 -0
  376. data/lib/phronomy/storage/condition_failed_error.rb +16 -0
  377. data/lib/phronomy/storage/conflict_error.rb +9 -0
  378. data/lib/phronomy/{persistence → storage}/durable_record.rb +12 -12
  379. data/lib/phronomy/storage/entry.rb +33 -0
  380. data/lib/phronomy/storage/guard_ref.rb +13 -0
  381. data/lib/phronomy/storage/not_found_error.rb +9 -0
  382. data/lib/phronomy/storage/record_codec.rb +177 -0
  383. data/lib/phronomy/storage/records.rb +61 -0
  384. data/lib/phronomy/storage/resource.rb +126 -0
  385. data/lib/phronomy/storage/scope.rb +25 -0
  386. data/lib/phronomy/storage/serialization_error.rb +9 -0
  387. data/lib/phronomy/storage/streams.rb +44 -0
  388. data/lib/phronomy/storage/transaction_error.rb +10 -0
  389. data/lib/phronomy/storage/unique_constraint_error.rb +17 -0
  390. data/lib/phronomy/storage/unsupported_backend_error.rb +9 -0
  391. data/lib/phronomy/storage/validation.rb +53 -0
  392. data/lib/phronomy/storage/view.rb +131 -0
  393. data/lib/phronomy/testing/eval/metrics.rb +1 -1
  394. data/lib/phronomy/testing/eval/scorer/llm_judge.rb +19 -3
  395. data/lib/phronomy/testing/persistence_contract/a_content_store.rb +1 -1
  396. data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +2 -2
  397. data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +54 -48
  398. data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +1 -1
  399. data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +1 -1
  400. data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +5 -5
  401. data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +52 -46
  402. data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +263 -0
  403. data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +124 -0
  404. data/lib/phronomy/testing/persistence_contract.rb +4 -0
  405. data/lib/phronomy/tool/authorization.rb +77 -0
  406. data/lib/phronomy/tool/base.rb +549 -9
  407. data/lib/phronomy/tool/call_request.rb +40 -0
  408. data/lib/phronomy/{agent/tool_definition_set.rb → tool/definition_set.rb} +16 -12
  409. data/lib/phronomy/tool/operation.rb +88 -0
  410. data/lib/phronomy/tool/schema.rb +214 -0
  411. data/lib/phronomy/tool/settings.rb +31 -0
  412. data/lib/phronomy/tool/tool_error.rb +7 -0
  413. data/lib/phronomy/{agent → tool}/tool_executor.rb +10 -7
  414. data/lib/phronomy/tools/agent.rb +22 -90
  415. data/lib/phronomy/tools/mcp.rb +21 -14
  416. data/lib/phronomy/tools/vector_search.rb +4 -4
  417. data/lib/phronomy/tracing/automatic.rb +11 -6
  418. data/lib/phronomy/tracing/base.rb +1 -1
  419. data/lib/phronomy/tracing/observation.rb +37 -0
  420. data/lib/phronomy/tracing/settings.rb +36 -0
  421. data/lib/phronomy/vector_store/{async_backend.rb → async/async_client.rb} +35 -29
  422. data/lib/phronomy/vector_store/{in_memory.rb → backends/in_memory.rb} +12 -10
  423. data/lib/phronomy/vector_store/{pgvector.rb → backends/pgvector.rb} +44 -16
  424. data/lib/phronomy/vector_store/{redis_search.rb → backends/redis_search.rb} +74 -37
  425. data/lib/phronomy/vector_store/base.rb +118 -49
  426. data/lib/phronomy/vector_store/invalid_result_error.rb +12 -0
  427. data/lib/phronomy/vector_store.rb +2 -17
  428. data/lib/phronomy/version.rb +1 -1
  429. data/lib/phronomy/workflow/completion.rb +11 -0
  430. data/lib/phronomy/{workflow.rb → workflow/execution/workflow.rb} +10 -8
  431. data/lib/phronomy/workflow/execution/workflow_action_rules.rb +67 -0
  432. data/lib/phronomy/{workflow_context.rb → workflow/execution/workflow_context.rb} +5 -1
  433. data/lib/phronomy/workflow/execution/workflow_context_ownership_error.rb +7 -0
  434. data/lib/phronomy/workflow/execution/workflow_execution_environment.rb +27 -0
  435. data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +186 -0
  436. data/lib/phronomy/{workflow_runner.rb → workflow/execution/workflow_runner.rb} +145 -115
  437. data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -0
  438. data/lib/phronomy/workflow/persistence/codec.rb +153 -0
  439. data/lib/phronomy/workflow/persistence/state_repository.rb +63 -0
  440. data/lib/phronomy/workflow/persistence/storage_schema.rb +13 -0
  441. data/lib/phronomy/workflow/runtime_binding/workflow_engine_environment.rb +38 -0
  442. data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +156 -0
  443. data/lib/phronomy/workflow/runtime_binding/workflow_terminal_policy.rb +40 -0
  444. data/lib/phronomy.rb +97 -98
  445. data/scripts/api_snapshot.rb +36 -16
  446. data/scripts/storage_spi_snapshot.rb +36 -0
  447. data/sig/_private/phronomy/agent/settings.rbs +19 -0
  448. data/sig/_private/phronomy/configuration/runtime_settings.rbs +20 -0
  449. data/sig/_private/phronomy/llm_adapter/async/async_client.rbs +10 -0
  450. data/sig/_private/phronomy/multi_agent/store.rbs +8 -0
  451. data/sig/_private/phronomy/persistence/storage_boundary.rbs +7 -0
  452. data/sig/_private/phronomy/tool/settings.rbs +13 -0
  453. data/sig/_private/phronomy/tracing/settings.rbs +15 -0
  454. data/sig/_private/phronomy/workflow/execution/workflow_settings.rbs +13 -0
  455. data/sig/phronomy/agent/admission.rbs +19 -0
  456. data/sig/phronomy/agent/execution_contract.rbs +132 -0
  457. data/sig/phronomy/agent/execution_environment.rbs +20 -0
  458. data/sig/phronomy/agent/store.rbs +73 -0
  459. data/sig/phronomy/agent.rbs +14 -139
  460. data/sig/phronomy/common.rbs +7 -0
  461. data/sig/phronomy/content_store/contracts.rbs +13 -0
  462. data/sig/phronomy/context.rbs +152 -0
  463. data/sig/phronomy/embeddings/async/async_client.rbs +9 -0
  464. data/sig/phronomy/embeddings/base.rbs +17 -0
  465. data/sig/phronomy/engine/concurrency/timer_bindings.rbs +22 -0
  466. data/sig/phronomy/engine/control_bindings.rbs +11 -0
  467. data/sig/phronomy/engine/control_protocols.rbs +23 -0
  468. data/sig/phronomy/engine/execution_binding.rbs +6 -0
  469. data/sig/phronomy/engine/execution_receiver.rbs +15 -0
  470. data/sig/phronomy/engine/observability.rbs +13 -0
  471. data/sig/phronomy/execution/async_operation.rbs +7 -0
  472. data/sig/phronomy/execution/blocking.rbs +5 -0
  473. data/sig/phronomy/execution/concurrency/cancellation_token.rbs +13 -0
  474. data/sig/phronomy/execution/concurrency/deadline.rbs +10 -0
  475. data/sig/phronomy/execution/concurrency/result_composition.rbs +7 -0
  476. data/sig/phronomy/execution/control_protocols.rbs +18 -0
  477. data/sig/phronomy/execution/errors.rbs +7 -0
  478. data/sig/phronomy/execution/execution.rbs +41 -0
  479. data/sig/phronomy/execution/execution_receiver.rbs +40 -0
  480. data/sig/phronomy/execution/execution_scope_state.rbs +9 -0
  481. data/sig/phronomy/execution/invocation_context.rbs +18 -0
  482. data/sig/phronomy/execution/invocation_controls.rbs +13 -0
  483. data/sig/phronomy/execution/task_result.rbs +29 -0
  484. data/sig/phronomy/extensions.rbs +0 -21
  485. data/sig/phronomy/handoff.rbs +12 -4
  486. data/sig/phronomy/llm_adapter/backends/ruby_llm.rbs +6 -0
  487. data/sig/phronomy/llm_adapter/base.rbs +14 -0
  488. data/sig/phronomy/llm_adapter/usage.rbs +14 -0
  489. data/sig/phronomy/llm_adapter/values.rbs +43 -0
  490. data/sig/phronomy/llm_context_window.rbs +10 -0
  491. data/sig/phronomy/multi_agent/reserved_child_admission.rbs +8 -0
  492. data/sig/phronomy/multi_agent/store.rbs +54 -0
  493. data/sig/phronomy/multi_agent.rbs +24 -3
  494. data/sig/phronomy/persistence/errors.rbs +18 -0
  495. data/sig/phronomy/persistence/migration.rbs +13 -0
  496. data/sig/phronomy/persistence/transaction.rbs +19 -0
  497. data/sig/phronomy/persistence.rbs +3 -185
  498. data/sig/phronomy/persistence_composition.rbs +19 -0
  499. data/sig/phronomy/runtime_composition/configuration.rbs +36 -0
  500. data/sig/phronomy/storage/async/async_client.rbs +8 -0
  501. data/sig/phronomy/storage/backends/in_memory.rbs +9 -0
  502. data/sig/phronomy/storage/contracts.rbs +160 -0
  503. data/sig/phronomy/tool.rbs +58 -5
  504. data/sig/phronomy/tracing/observation.rbs +7 -0
  505. data/sig/phronomy/vector_store/async/async_client.rbs +13 -0
  506. data/sig/phronomy/vector_store/base.rbs +23 -0
  507. data/sig/phronomy/workflow/execution/workflow_execution_environment.rbs +14 -0
  508. data/sig/phronomy/workflow/runtime_binding/workflow_terminal_policy.rbs +7 -0
  509. data/sig/phronomy/workflow/store.rbs +8 -0
  510. data/sig/phronomy/workflow.rbs +1 -1
  511. data/sig/phronomy.rbs +0 -49
  512. metadata +462 -130
  513. data/lib/phronomy/agent/agent_invocation_session_builder.rb +0 -584
  514. data/lib/phronomy/agent/concerns/before_llm_input.rb +0 -66
  515. data/lib/phronomy/agent/concerns/error_translation.rb +0 -45
  516. data/lib/phronomy/agent/concerns/filterable.rb +0 -184
  517. data/lib/phronomy/agent/context/capability/base.rb +0 -507
  518. data/lib/phronomy/agent/context/instruction/prompt_template.rb +0 -102
  519. data/lib/phronomy/agent/context_parts/validators/final_budget_validator.rb +0 -37
  520. data/lib/phronomy/agent/context_policies/default.rb +0 -142
  521. data/lib/phronomy/agent/execution_coordinator.rb +0 -3151
  522. data/lib/phronomy/agent/handoff_execution_coordinator.rb +0 -143
  523. data/lib/phronomy/agent/handoff_request.rb +0 -45
  524. data/lib/phronomy/agent/handoff_runner.rb +0 -178
  525. data/lib/phronomy/agent/phase_machine_builder.rb +0 -152
  526. data/lib/phronomy/agent/provider_call_outcome.rb +0 -106
  527. data/lib/phronomy/agent/recovery_support.rb +0 -504
  528. data/lib/phronomy/agent/selection/candidate.rb +0 -53
  529. data/lib/phronomy/agent/selection/constraint.rb +0 -49
  530. data/lib/phronomy/agent/token_budget_resolver.rb +0 -70
  531. data/lib/phronomy/agent/tool_call_intercepted.rb +0 -29
  532. data/lib/phronomy/agent/tool_invocation_session_builder.rb +0 -276
  533. data/lib/phronomy/configuration.rb +0 -59
  534. data/lib/phronomy/engine/concurrency/cancellation_scope.rb +0 -124
  535. data/lib/phronomy/engine/concurrency/operation_binding.rb +0 -43
  536. data/lib/phronomy/generator_verifier.rb +0 -369
  537. data/lib/phronomy/invalid_context_budget_configuration_error.rb +0 -8
  538. data/lib/phronomy/llm_adapter/ruby_llm.rb +0 -47
  539. data/lib/phronomy/metrics.rb +0 -26
  540. data/lib/phronomy/multi_agent/parallel_tool_chat.rb +0 -116
  541. data/lib/phronomy/persistence/durable_codec.rb +0 -706
  542. data/lib/phronomy/persistence/in_memory.rb +0 -690
  543. data/lib/phronomy/persistence/repository_facades.rb +0 -535
  544. data/lib/phronomy/persistence.rb +0 -276
  545. data/lib/phronomy/recovery.rb +0 -186
  546. data/lib/phronomy/ruby_llm_patches.rb +0 -24
  547. data/lib/phronomy/runnable.rb +0 -54
  548. data/lib/phronomy/token_usage.rb +0 -85
  549. data/lib/phronomy/vector_store/embeddings/base.rb +0 -44
  550. data/lib/phronomy/vector_store/embeddings/ruby_llm_embeddings.rb +0 -47
  551. data/lib/phronomy/workflow/phase_machine_builder.rb +0 -205
  552. data/lib/phronomy/workflow_recovery.rb +0 -123
  553. data/sig/phronomy/llm_adapter.rbs +0 -11
  554. data/sig/phronomy/runtime.rbs +0 -76
  555. /data/lib/phronomy/agent/{llm_operation_result.rb → execution/llm_operation_result.rb} +0 -0
  556. /data/lib/phronomy/{canonical_json.rb → common/canonical_json.rb} +0 -0
  557. /data/lib/phronomy/{event.rb → engine/event.rb} +0 -0
@@ -62,7 +62,7 @@ resolved explicitly.
62
62
  | [`011-delegate-transport-policy-to-adapters`](011-delegate-transport-policy-to-adapters.md) | Accepted | Yes | Legacy duplicate numeric prefix; use the full canonical key. |
63
63
  | [`012-canonical-execution-log-and-context-policy`](012-canonical-execution-log-and-context-policy.md) | Accepted | Yes | Current Journal / Manifest / Context authority. |
64
64
  | [`013-journal-backed-knowledge-as-context-candidates`](013-journal-backed-knowledge-as-context-candidates.md) | Accepted | Yes | Current persistent Knowledge authority. |
65
- | [`014-unified-persistence-durable-state`](014-unified-persistence-durable-state.md) | Accepted | Yes | Durable-backend and live-owner/no-reload intent remains current; live Agent execution mutation is refined by ADR-024, same-process Agent identity/admission ownership by ADR-025, and same-process Workflow admission/terminal-barrier ordering by ADR-026. Workflow identity terminology is superseded by ADR-020, generic `InvocationContext` / Agent correlation semantics by ADR-021, and concrete FSMSession/Agent-Tool routing identity by ADR-023. |
65
+ | [`014-unified-persistence-durable-state`](014-unified-persistence-durable-state.md) | Accepted | Yes | Durable-backend and live-owner/no-reload intent remains current; [032-storage-backend-composition](032-storage-backend-composition.md) refines storage contract ownership and replaces the backend inheritance SPI; live Agent execution mutation is refined by ADR-024, same-process Agent identity/admission ownership by ADR-025, and same-process Workflow admission/terminal-barrier ordering by ADR-026. Workflow identity terminology is superseded by ADR-020, generic `InvocationContext` / Agent correlation semantics by ADR-021, and concrete FSMSession/Agent-Tool routing identity by ADR-023. |
66
66
  | [`015-tool-public-facade-and-rbs-boundary`](015-tool-public-facade-and-rbs-boundary.md) | Accepted | Yes | Current Tool façade / extension-SPI / RBS boundary. |
67
67
  | [`016-semantic-multi-agent-handoff`](016-semantic-multi-agent-handoff.md) | Superseded | No | Superseded by [ADR-030](030-agent-handoff-domain-and-durable-responsibility.md), including Agent-domain ownership and exact Target recovery. |
68
68
  | [`017-design-authority-and-adr-governance`](017-design-authority-and-adr-governance.md) | Accepted | Yes | Repository-wide architecture authority and ADR governance. |
@@ -72,14 +72,52 @@ resolved explicitly.
72
72
  | [`021-generic-agent-invocation-identity-removal`](021-generic-agent-invocation-identity-removal.md) | Accepted | Yes | Removes generic Agent/InvocationContext identity and canonical Journal `correlation_id`; CG-02 is closed, with targeted legacy durable-key read compatibility and no eager rewrite. |
73
73
  | [`022-agent-execution-parent-identity-and-runtime-routing-boundary`](022-agent-execution-parent-identity-and-runtime-routing-boundary.md) | Accepted | Yes | Canonicalizes Agent-owned Tool/approval logical parent as `execution_id`; CG-03a is reconciled, ADR-023 supplies incarnation routing, and ADR-024 supplies EventLoop result/live-state authority. |
74
74
  | [`023-fsm-session-incarnation-identity-and-routing`](023-fsm-session-incarnation-identity-and-routing.md) | Accepted | Yes | FSMSession-owned incarnation identity, session-local Agent/Tool/Multi-Agent routing, and stale-target drop remain current. Its transitional Workflow identity-reservation/admission bridge is superseded by ADR-026; Agent result authority is completed by ADR-024. |
75
- | [`024-event-loop-single-writer-agent-runtime`](024-event-loop-single-writer-agent-runtime.md) | Accepted | Yes | EventLoop is the single writer of Phronomy-managed live Agent execution state; removes Activation/ActivationRegistry and defines operation-specific Offload result application with current FSM + semantic-ID authority. |
76
- | [`025-process-local-agent-ownership-and-runtime-admission`](025-process-local-agent-ownership-and-runtime-admission.md) | Accepted | Yes | One mutable live Agent owner per `agent_id` per Runtime; EventLoop is the primary same-process top-level admission authority while Persistence admission remains durable defense. |
77
- | [`026-workflow-runtime-admission-and-durable-terminal-barrier`](026-workflow-runtime-admission-and-durable-terminal-barrier.md) | Accepted | Yes | EventLoop-owned opaque Workflow admission owner, admission-before-hydration ordering, and FSMSession-integrated durable terminal save barrier with fail-closed uncertain outcomes. |
75
+ | [`024-event-loop-single-writer-agent-runtime`](024-event-loop-single-writer-agent-runtime.md) | Amended | Yes | EventLoop is the single writer of Phronomy-managed live Agent execution state; removes Activation/ActivationRegistry and defines operation-specific Offload result application with current FSM + semantic-ID authority. Implementation ownership/delivery amended by [042-feature-owned-execution-state](042-feature-owned-execution-state.md). |
76
+ | [`025-process-local-agent-ownership-and-runtime-admission`](025-process-local-agent-ownership-and-runtime-admission.md) | Amended | Yes | One mutable live Agent owner per `agent_id` per Runtime; EventLoop is the primary same-process top-level admission authority while Persistence admission remains durable defense. ADR-041 moves registry implementation to Agent while retaining Runtime-scoped lifetime. Implementation ownership/delivery amended by [042-feature-owned-execution-state](042-feature-owned-execution-state.md). |
77
+ | [`026-workflow-runtime-admission-and-durable-terminal-barrier`](026-workflow-runtime-admission-and-durable-terminal-barrier.md) | Amended | Yes | EventLoop-owned opaque Workflow admission owner, admission-before-hydration ordering, and FSMSession-integrated durable terminal save barrier with fail-closed uncertain outcomes. Implementation ownership/delivery amended by [042-feature-owned-execution-state](042-feature-owned-execution-state.md). |
78
78
  | [`027-llm-adapter-provider-boundary`](027-llm-adapter-provider-boundary.md) | Accepted | Yes | Phronomy-owned Provider-call extension boundary; RubyLLM is the default adapter/integration while current input materialization remains RubyLLM-specific. |
79
79
  | [`028-preparing-recovery-replay-contract`](028-preparing-recovery-replay-contract.md) | Accepted | Yes | Adds replay-safe same-`execution_id` recovery for durably admitted Agent `:preparing` executions when replayability is durably established; unsupported Runtime-only dependencies fail closed. |
80
80
  | [`029-semantic-completion-and-application-effect-boundary`](029-semantic-completion-and-application-effect-boundary.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. |
81
- | [`030-agent-handoff-domain-and-durable-responsibility`](030-agent-handoff-domain-and-durable-responsibility.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. |
82
- | [`031-durable-multi-agent-coordination`](031-durable-multi-agent-coordination.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. |
81
+ | [`030-agent-handoff-domain-and-durable-responsibility`](030-agent-handoff-domain-and-durable-responsibility.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. Runner ownership amended by [034-handoff-runner-coordination-ownership](034-handoff-runner-coordination-ownership.md); other V2 semantics remain. |
82
+ | [`031-durable-multi-agent-coordination`](031-durable-multi-agent-coordination.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. Runner ownership amended by [034-handoff-runner-coordination-ownership](034-handoff-runner-coordination-ownership.md); other V2 semantics remain. |
83
+ | [`032-storage-backend-composition`](032-storage-backend-composition.md) | Accepted | Yes | Separates raw Storage contracts/backends from domain Persistence by composition; replaces the Persistence subclass SPI and its facade-building helper. ADR-014 single transaction domain and ownership guarantees remain; [033-domain-persistence-ownership](033-domain-persistence-ownership.md) refines codec/repository ownership. |
84
+ | [`033-domain-persistence-ownership`](033-domain-persistence-ownership.md) | Amended | Yes | Domain-owned codecs, repositories, and result queries over the unchanged Storage SPI; explicit composition preserves one transaction domain. Error boundary refined by [043-storage-execution-constraint-notifications](043-storage-execution-constraint-notifications.md). |
85
+ | [`034-handoff-runner-coordination-ownership`](034-handoff-runner-coordination-ownership.md) | Accepted | Yes | H1 moves the public HandoffRunner to MultiAgent; Agent execution, Handoff records, and Runtime shutdown semantics are preserved. Further Handoff separation is deferred. |
86
+ | [`035-tool-executor-capability-ownership`](035-tool-executor-capability-ownership.md) | Accepted | Yes | T1 places the private default Tool executor beside Capability Base; public Tool identity, execution modes, Runtime injection, and Agent authorization/result ownership are preserved. |
87
+ | [`036-context-contract-ownership`](036-context-contract-ownership.md) | Accepted | Yes | C1 groups Context Policy/hook contracts, values, Manifest representation, and Plan validation in a collapsed directory; public Agent constants, extension protocols, and stored formats are preserved. |
88
+ | [`037-common-definition-ownership`](037-common-definition-ownership.md) | Amended | Yes | Defines the common responsibility group and initially extracts the shared base exception; [038-responsibility-based-source-layout](038-responsibility-based-source-layout.md) extends the extraction scope while preserving ownership rules and exception contracts. |
89
+ | [`038-responsibility-based-source-layout`](038-responsibility-based-source-layout.md) | Amended | Yes | Reserves the direct root for version/namespace loading, groups common definitions and feature implementation/contracts, and preserves canonical constants and lifecycle loading through explicit Zeitwerk roots. ADR-039 separates cross-owner Runtime lifecycle coordination. |
90
+ | [`039-runtime-configuration-lifecycle-ownership`](039-runtime-configuration-lifecycle-ownership.md) | Amended | Yes | Separates application Runtime reset and configuration replacement into runtime_composition; configuration access and Engine mechanics retain their own ownership and existing API behavior. ADR-040 separates concrete-default selection without changing Runtime reset. |
91
+ | [`040-configuration-default-composition`](040-configuration-default-composition.md) | Amended | Yes | Settings consume internal fresh-instance factories; runtime_composition selects and binds the concrete adapter/tracer defaults. Preserves Configuration.new and the adapter SPI. |
92
+ | [`041-feature-owned-identity-registries`](041-feature-owned-identity-registries.md) | Accepted | Yes | Agent and MultiAgent own identity registries; Runtime retains them through generic lookup, drain/wait, and optional finalization. Preserves product APIs and single-owner lifetime; Execution state is separately assigned by ADR-042. |
93
+
94
+ | [`042-feature-owned-execution-state`](042-feature-owned-execution-state.md) | Accepted | Yes | Agent/Workflow own execution state; Engine retains generic receiver delivery, synchronization and shutdown boundaries. Single-writer and durable barriers remain. |
95
+ | [`043-storage-execution-constraint-notifications`](043-storage-execution-constraint-notifications.md) | Accepted | Yes | Raw backends report Storage-owned active-execution conflicts; feature repositories preserve public busy errors within the same transaction. Beta raw error SPI migration. |
96
+ | [`044-agent-default-and-one-shot-composition`](044-agent-default-and-one-shot-composition.md) | Accepted | Yes | Agent consumes an owner-defined fresh-Persistence factory; application composition selects the default and owns the unchanged one-shot API. |
97
+ | [`045-worker-input-restriction-ownership`](045-worker-input-restriction-ownership.md) | Accepted | Yes | Each restricted type declares an execution-boundary marker; authorization input validation preserves the existing rejection and opaque application-value contracts without enumerating feature types. |
98
+ | [`046-agent-responsibility-layout-and-shared-records`](046-agent-responsibility-layout-and-shared-records.md) | Amended | Yes | Agent responsibility directories preserve constants; shared record encoding, saved context reads and live restoration have separate owners. Continuation control refined by [047-recovered-execution-continuation-contract](047-recovered-execution-continuation-contract.md); deferred SharedState ownership resolved by [053-shared-state-coordination-ownership](053-shared-state-coordination-ownership.md). |
99
+ | [`047-recovered-execution-continuation-contract`](047-recovered-execution-continuation-contract.md) | Accepted | Yes | Recovery hands semantic commands to the execution owner; EventLoop identity/revision checks and shared session registration replace private control calls. |
100
+ | [`048-dispatch-preparation-worker-ownership`](048-dispatch-preparation-worker-ownership.md) | Accepted | Yes | Dispatch worker owns prerequisite persistence and readback; the execution owner retains EventLoop validation, apply and dispatch. Operation-specific boundaries and purpose-level method bodies are preserved. |
101
+ | [`049-initial-preparation-worker-ownership`](049-initial-preparation-worker-ownership.md) | Accepted | Yes | Initial preparation and preparing recovery share a persistence worker; admission outcomes, commit certainty and EventLoop ownership stay distinct. Pure failure classification is shared without sharing transaction control. |
102
+ | [`050-approval-resume-snapshot-and-commit-ownership`](050-approval-resume-snapshot-and-commit-ownership.md) | Accepted | Yes | Validated approval commands own immutable recovery snapshots. A worker commits decision, Execution and Root; the execution owner retains admission, live state and session resumption. |
103
+ | [`051-execution-outcome-worker-ownership`](051-execution-outcome-worker-ownership.md) | Accepted | Yes | Ordinary and Handoff outcome workers own atomic persistence and operation-specific readback; EventLoop retains result authority and delivery. |
104
+ | [`052-tool-invocation-restoration-ownership`](052-tool-invocation-restoration-ownership.md) | Accepted | Yes | ToolInvocation owns saved state application; Recovery retains snapshot decoding and identity matching. Existing restoration and replay rules are preserved. |
105
+ | [`053-shared-state-coordination-ownership`](053-shared-state-coordination-ownership.md) | Accepted | Yes | Moves Experimental SharedState and its invocation-local store to MultiAgent without an old-name alias; preserves coordination behavior and generated definition identity. Resolves the deferred SharedState ownership in ADR-046. |
106
+ | [`054-workflow-terminal-save-single-owner`](054-workflow-terminal-save-single-owner.md) | Accepted | Yes | Consolidates the active F1-aware terminal save in WorkflowRunner and removes its private prepend override. Amends ADR-038 loading; preserves the durable barrier and leaves FSMSession policy ownership as separate work. |
107
+ | [`055-terminal-observer-failure-settlement`](055-terminal-observer-failure-settlement.md) | Accepted | Yes | Keeps the error path open until terminal stable notification returns. Observer failure settles the caller and releases admission without retrying or undoing an already confirmed save. Clarifies ADR-026; W2b ownership extraction remains separate. |
108
+ | [`056-workflow-terminal-policy-ownership`](056-workflow-terminal-policy-ownership.md) | Accepted | Yes | Workflow owns persistence-result interpretation through a private policy; Engine retains generic session gating and complete/fail/retire actions. Preserves ADR-026/055 ordering and uncertainty without a public plugin API. |
109
+ | [`057-storage-transaction-boundaries`](057-storage-transaction-boundaries.md) | Accepted | Yes | Enforces active-owner exclusion on InMemory updates, validates SQL Journal batches before writes and defines explicit nested savepoints with propagated failures. Preserves the existing SPI and record formats; the neutral SPI remains separate work. |
110
+
111
+ | [`058-neutral-storage-primitives`](058-neutral-storage-primitives.md) | Accepted | Yes | Neutral Records/Streams/Blobs SPI 2 and scoped transaction lifecycle; amends 032, 033, 043 and 057. |
112
+
113
+ | [`059-backend-contracts-and-async-clients`](059-backend-contracts-and-async-clients.md) | Accepted | Yes | P1/P2 separates synchronous LLM contracts, implementations and internal clients; independent responsibility groups replace numbered layers. VectorStore/Storage migration remains pending. |
114
+ | [`060-runtime-settings-and-application-configuration`](060-runtime-settings-and-application-configuration.md) | Accepted | Yes | Separates neutral Engine settings from typed application Configuration; preserves public settings/lifecycle semantics and requires the complete Ruby + RBS boundary gate without exceptions. |
115
+
116
+ | [`061-persistence-failure-contracts`](061-persistence-failure-contracts.md) | Accepted | Yes | Independent domain failure contracts and explicit raw Storage translation; public rescue-clause migration, preserved transaction/admission/uncertainty semantics. |
117
+ | [`062-content-store-service`](062-content-store-service.md) | Accepted | Yes | Content management over neutral Storage; removes the unnecessary backend subdivision and preserves content/Persistence behavior. |
118
+
119
+ | [`063-execution-contracts-and-services`](063-execution-contracts-and-services.md) | Accepted | Yes | Shared execution contracts and result/call services separated from Engine internals; preserves public APIs and fixes filtered physical completion. |
120
+ | [`068-agent-tool-child-progress-and-tool-operation`](068-agent-tool-child-progress-and-tool-operation.md) | Accepted | Yes | C04 Tool child progress and original environment; C06 operation dispatch/result adaptation; child FSM in runtime_binding. |
83
121
 
84
122
  ## Legacy duplicate `011`
85
123
 
@@ -174,3 +212,11 @@ Current explanatory architecture starts at
174
212
  segregated under `docs/archive/design/` and are non-normative. Explanatory
175
213
  architecture documents describe the reconciled current system but do not
176
214
  supersede ADRs merely by being newer.
215
+
216
+ - [`064-agent-execution-and-multi-agent-responsibility`](064-agent-execution-and-multi-agent-responsibility.md)
217
+
218
+ - [`065-vector-and-embeddings-common-operations`](065-vector-and-embeddings-common-operations.md) — accepted for r8 unit 5; amends the vector/embedding SPI and namespace provisions of ADR-059.
219
+
220
+ - [`066-llm-and-tool-operation-contracts`](066-llm-and-tool-operation-contracts.md)
221
+
222
+ - [`067-agent-progress-and-engine-connection`](067-agent-progress-and-engine-connection.md) — Agent progress rules and Engine connection ownership.
@@ -1,5 +1,11 @@
1
1
  # Phronomy Durable Semantic Coordination — Implementation Design V2
2
2
 
3
+ > Runner namespace update (2026-09-18): this document preserves the V2
4
+ > implementation/migration record. The current Runner is
5
+ > `Phronomy::MultiAgent::HandoffRunner` under
6
+ > [ADR-034](../../decisions/034-handoff-runner-coordination-ownership.md).
7
+ > Handoff and HandoffPolicy remain in Agent at this stage.
8
+
3
9
  ## 0. Status and authority
4
10
 
5
11
  **Accepted implementation design — V2 revision 2 (2026-09-06).**
@@ -1,5 +1,11 @@
1
1
  # Durable Semantic Coordination V2 revision 2 — Implementation report
2
2
 
3
+ > Runner namespace update (2026-09-18): this document preserves the V2
4
+ > implementation/migration record. The current Runner is
5
+ > `Phronomy::MultiAgent::HandoffRunner` under
6
+ > [ADR-034](../../decisions/034-handoff-runner-coordination-ownership.md).
7
+ > Handoff and HandoffPolicy remain in Agent at this stage.
8
+
3
9
  作成日: 2026-09-07。設計承認日: 2026-09-06。
4
10
  対象baseline: `5472116cd99a63ec27875024c955ea82be612d6b`。
5
11
  承認済みADR-029/030/031とRC-01〜05に対する新規実装です。
@@ -0,0 +1,45 @@
1
+ # Execution boundary candidate (unapplied)
2
+
3
+ Base: main 653e255a34fe4062d4beca47530e084fdd3a6ba9.
4
+ This is an unpublished prototype for source-derived architecture review.
5
+
6
+ TaskResult, Outcome, result composition, physical completion and ScopeState
7
+ belong to Execution Results. They depend on Contracts and Common, without
8
+ acquiring Runtime or calling Execution Services. Engine and Services share
9
+ these neutral results. OffloadPool uses an injected timer protocol; its wait
10
+ guard uses WaitPolicy. Services owns operation binding, timer subscriptions,
11
+ worker submission and invocation-control adaptation.
12
+
13
+ Workflow::Completion owns the public DSL finish value `:__finish__`.
14
+ WorkflowPhaseMachineBuilder, beside WorkflowRunner, translates it to the FSM
15
+ terminal state. FSMSession retains terminal detection and persistence gating.
16
+ TerminalDecision is an execution contract, independent of Workflow and FSM
17
+ state vocabulary.
18
+
19
+ ## Intentional compatibility changes
20
+
21
+ * InvocationContext#effective_timeout_token and #effective_cancellation_token
22
+ are removed. Although annotated private, both occurred in the Stable API
23
+ snapshot. This candidate updates those two entries explicitly. Applications
24
+ pass cancellation_token/deadline into InvocationContext; the invoking
25
+ service applies them. Code needing a standalone token constructs
26
+ Concurrency::CancellationToken directly.
27
+ * Deadline#attach_to is removed. Deadline is a time value, not a timer owner.
28
+ Internal Workflow control adaptation moves to InvocationControls.
29
+ * Unused private CancellationScope is removed. Private
30
+ Workflow::PhaseMachineBuilder becomes WorkflowPhaseMachineBuilder in the
31
+ Runner source directory. FSMProtocol::TerminalDecision becomes
32
+ Phronomy::TerminalDecision. Direct requires of moved internal files change.
33
+ * An already expired Workflow deadline now cancels immediately. An explicitly
34
+ supplied token still takes precedence over that deadline, as before.
35
+
36
+ TaskResult/map/flat_map/all_settled and AsyncClient public operations remain.
37
+ WorkerSubmission preserves injected-pool ownership, original result identity,
38
+ operation-time Runtime resolution and synchronous admission errors. Blocking
39
+ continues converting admission errors to failed results. MCP keeps its named
40
+ cleanup pool. Engine connections remain with registries/coordinators/runners.
41
+
42
+ RBS declares scope, timer, receiver and terminal-policy protocols in sig/.
43
+ Validation checks signature consistency, not whole-program type correctness.
44
+ The static diagram includes Ruby and RBS evidence; injected implementations
45
+ and callback behavior also require runtime tests.
data/docs/features.md CHANGED
@@ -20,7 +20,7 @@ for production deployments.
20
20
  | **Workflow** — Stateful, branching workflows with `wait_state` and explicit events | Stable |
21
21
  | **Agent** — Stateful ReAct-style agents with stable `agent_id`, one mutable live owner per Runtime, persistence-backed execution state, canonical history, and conversation context | Stable |
22
22
  | **Tool authoring façade** — `Phronomy::Tool::Base` is the public authoring name for the existing Capability base class; the legacy namespace remains compatible | Beta |
23
- | **Unified Persistence** — One durable backend abstraction for Agent state and Workflow `workflow_states`; live Agent/Workflow state remains owned by Runtime/session authority between durable commits; custom backends implement the documented Backend SPI and repository/transaction semantics | Beta |
23
+ | **Unified Persistence** — One transaction domain for Agent, Team, and Workflow state; a domain-facing `Persistence` composes a record-oriented `Storage::Backend`; live Agent/Workflow state remains owned by Runtime/session authority between durable commits; custom backends implement the documented Backend SPI, including Storage-owned active-execution constraint notifications translated by domain repositories, and repository/transaction semantics | Beta |
24
24
  | **LLMAdapter SPI** — `Phronomy::LLMAdapter::Base#complete` / `#stream` define the Beta call-adapter extension boundary; Phronomy owns async/offload wrapping | Beta |
25
25
  | **Before-Large-Language-Model (LLM) Input Hook** — Three-tier per-call LLM input customization via `before_llm_input` and `LLMInputPatch` | Stable |
26
26
  | **Context Management** — Journal + Context Policy + per-LLM-call Manifest with token-budget-aware selection and protocol-safe Tool Call / Tool message dependencies | Stable |
@@ -46,12 +46,17 @@ rather than implicitly inheriting the parent revision. The Stable
46
46
  |---|---|
47
47
  | **Knowledge** — Journal-backed persistent Agent context registered with `knowledge:` / `add_knowledge`, selected per LLM call by Context Policy | Beta |
48
48
  | **`VectorStore#size`** — Document count for InMemory, RedisSearch, and Pgvector backends | Beta |
49
- | **VectorStore async convenience** — `add_async` / `search_async` / `remove_async` / `clear_async` offload the synchronous Backend SPI through Phronomy and return `TaskResult`; native async override is not part of the current Backend SPI | Beta |
50
- | **Embedding async convenience** — `embed_async` offloads synchronous `embed` through Phronomy and returns `TaskResult` | Beta |
49
+ | **Storage::AsyncClient** — `transaction_async` runs a raw backend transaction on one worker and returns TaskResult; [usage and lifetime rules](migrations/storage-async-client.md) | Beta |
50
+ | **VectorStore::AsyncClient** — `add_async` / `search_async` / `remove_async` / `clear_async` offload the synchronous Backend SPI through Phronomy and return `TaskResult`; native async override is not part of the current Backend SPI | Beta |
51
+ | **VectorStore::Embeddings::AsyncClient** — `embed_async` offloads synchronous `embed` through Phronomy and returns `TaskResult` | Beta |
51
52
  | **Model Context Protocol (MCP) Tool** — `Phronomy::Tools::Mcp` integration through the official `mcp` gem | Beta |
52
53
  | **Agent Tool** — `Phronomy::Tools::Agent.from_agent` exposes a child Agent as a Tool without occupying a worker while waiting | Beta |
53
54
  | **Vector Search Tool** — `Phronomy::Tools::VectorSearch` wraps VectorStore and Embeddings adapters | Beta |
54
55
 
56
+ Applications previously calling async methods on backend objects must
57
+ [move those calls to explicit clients](migrations/vector-async-clients.md).
58
+ Backend authors continue to implement the synchronous SPI only.
59
+
55
60
  ## Execution and reliability
56
61
 
57
62
  | Feature | Stability |
@@ -79,14 +84,20 @@ rather than implicitly inheriting the parent revision. The Stable
79
84
 
80
85
  ## Agent and workflow patterns
81
86
 
87
+ Agent Tool batches use a single ordinary RubyLLM chat path. Agent owns Tool
88
+ authorization, dispatch and the barrier before the next Provider request;
89
+ concurrency remains governed by Tool execution modes and Runtime capacity.
90
+ The obsolete `parallel_tool_execution` configuration accessor has been removed.
91
+ See the [migration guide](migrations/parallel-tool-chat-removal.md).
92
+
82
93
  | Feature | Stability |
83
94
  |---|---|
84
95
  | **Workflow asynchronous pattern** — Start async work, return immediately, and continue through `Workflow#signal` | Beta |
85
- | **Durable Agent Handoff** — `Agent::Handoff` and `Agent::HandoffRunner` persist responsibility, immutable Context and exact Target reservation in one Persistence domain; current graph wiring is required for continuation | Beta |
96
+ | **Durable Handoff** — `MultiAgent::Handoff` and `MultiAgent::HandoffRunner` persist responsibility, immutable Context and exact Target reservation in one Persistence domain; current graph wiring is required for continuation | Beta |
86
97
  | **GeneratorVerifier** — Generator-Verifier loop with injectable prompts/parsers | Beta |
87
98
  | **`Phronomy::MultiAgent::Orchestrator`** — Parallel subagent dispatch, fan-out, and `subagent` DSL | Beta |
88
99
  | **`Phronomy::MultiAgent::TeamCoordinator`** — LLM coordinator with stateful worker Agents | Beta |
89
- | **SharedState** — Peer-agent shared-state coordination | Experimental |
100
+ | **`Phronomy::MultiAgent::SharedState`** — Sequential peer-agent coordination through an invocation-local findings store; see the [namespace migration](migrations/shared-state-multi-agent.md) | Experimental |
90
101
  | **Human-in-the-loop approval** — durable suspension publishes `:approval_required` through the Agent listener; `approve` / `approve_async` resumes the same logical `execution_id` with a fresh FSMSession incarnation | Beta |
91
102
  | **`tool_approval_policy`** — Application-defined allow/approve/reject policy using a value-only `ApprovalEvaluationRequest` without live Agent/Tool references | Beta |
92
103
 
@@ -50,7 +50,7 @@ Install only the backend gems required by your application:
50
50
  ## Define a Tool and Agent
51
51
 
52
52
  Use `Phronomy::Tool::Base` as the application-facing authoring API. It is an
53
- exact alias of the existing `Phronomy::Agent::Context::Capability::Base`, so
53
+ exact alias of the existing `Phronomy::Tool::Base`, so
54
54
  existing Tool definitions using the longer namespace remain compatible.
55
55
 
56
56
  ```ruby
@@ -85,7 +85,7 @@ application does not need to pass the previous `messages` array back into every
85
85
  invocation.
86
86
 
87
87
  ```ruby
88
- persistence = Phronomy::Persistence::InMemory.new
88
+ persistence = Phronomy::PersistenceComposition.agent
89
89
 
90
90
  agent = ResearchAgent.create(
91
91
  agent_id: "research-session-42",
@@ -115,7 +115,7 @@ A Runtime has at most one mutable live Agent object for an `agent_id`. If the
115
115
  Agent is already live, repeated `load` returns that exact Ruby object and does
116
116
  not reload Persistence. If it is not live, `load` hydrates the durable Agent
117
117
  once. Loading an ID that does not exist durably raises
118
- `Persistence::NotFoundError`.
118
+ `Storage::NotFoundError`.
119
119
 
120
120
  Use `get` when only a process-local lookup is wanted:
121
121
 
@@ -131,7 +131,7 @@ While the Agent is live, it owns its current AgentRoot/Journal view and
131
131
  Runtime/EventLoop owns process-local identity/admission/execution authority.
132
132
  Phronomy persists snapshots at defined durability boundaries but does not reload
133
133
  mutable Agent/Execution/Journal state before every LLM or Tool step. A conflicting
134
- external durable write is surfaced as `Persistence::ConflictError` rather than
134
+ external durable write is surfaced as `Storage::ConflictError` rather than
135
135
  silently merged into the live instance.
136
136
 
137
137
  The active transcript and Knowledge views can be advanced independently without
@@ -250,7 +250,7 @@ end
250
250
  write_draft = ->(state) { state.merge(draft: "Draft content") }
251
251
  review_draft = ->(state) { state.merge(feedback: "Feedback on: #{state.draft}") }
252
252
 
253
- persistence = Phronomy::Persistence::InMemory.new
253
+ persistence = Phronomy::PersistenceComposition.in_memory.workflow
254
254
 
255
255
  workflow = Phronomy::Workflow.define(
256
256
  ReviewContext,
@@ -274,7 +274,7 @@ final = workflow.send_event(state: state, event: :approve)
274
274
  puts final.approved
275
275
  ```
276
276
 
277
- `Persistence#workflow_states` is the durable Workflow repository. `workflow_instance_id`
277
+ The injected Workflow checkpoint repository supplies `load`, `save`, and `delete`. `workflow_instance_id`
278
278
  identifies the durable Workflow state and remains stable across resume. Each
279
279
  concrete Runtime execution receives a separate internal `fsm_session_id`; the
280
280
  application-level `session_id` remains ordinary caller/tracing metadata. Phronomy
@@ -286,12 +286,15 @@ A global Persistence backend can be configured when Agents and Workflows should
286
286
  share one durable backend:
287
287
 
288
288
  ```ruby
289
+ stores = Phronomy::PersistenceComposition.in_memory
289
290
  Phronomy.configure do |config|
290
- config.persistence = persistence
291
+ config.agent_store = stores.agent
292
+ config.multi_agent_store = stores.multi_agent
293
+ config.workflow_store = stores.workflow
291
294
  end
292
295
  ```
293
296
 
294
- Agent `new`/`create` and Workflow definitions use the global backend when they do
297
+ Agent `new`/`create`, Team construction, and Workflow definitions use their configured store when they do
295
298
  not inject an explicit `persistence:`. Workflow durability is fixed at the
296
299
  application/Workflow-definition boundary; there is no per-invocation backend
297
300
  switch.
@@ -16,6 +16,11 @@ follow the current contracts documented in
16
16
  | `InvocationContext#provider_limits` | Configure the provider client directly |
17
17
  | `stream_queue_max_size` | No replacement; the shared EventLoop queue is unbounded by design. Monitor `Metrics.snapshot[:event_loop_queue_depth]` instead |
18
18
 
19
+ The historical `parallel_tool_execution` switch mentioned above was subsequently
20
+ removed by the architecture refactor. Current code should follow the
21
+ [Chat migration guide](parallel-tool-chat-removal.md); it is not an on/off
22
+ control for Agent Tool concurrency.
23
+
19
24
  ## Timeout ownership
20
25
 
21
26
  Phronomy owns logical lifecycle deadlines and cooperative cancellation. Provider,
@@ -178,8 +178,8 @@ and no ordinary Handoff Tool result is generated.
178
178
 
179
179
  ACS-04 replaces the intermediate Context selection composition API with the
180
180
  final four-category Context Policy SPI. Application-defined policies receive an
181
- immutable `Phronomy::Agent::ContextPolicyInput` and return an immutable
182
- `Phronomy::Agent::ContextPlan`, each organized as `instruction`, `knowledge`,
181
+ immutable `Phronomy::Context::ContextPolicyInput` and return an immutable
182
+ `Phronomy::Context::ContextPlan`, each organized as `instruction`, `knowledge`,
183
183
  `tools`, and grouped `conversation`.
184
184
 
185
185
  Agent classes bind one Application-constructed Policy instance:
@@ -1,5 +1,13 @@
1
1
  # Durable semantic coordination V2 migration
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
+
5
+ > Runner namespace update (2026-09-18): this document preserves the V2
6
+ > implementation/migration record. The current Runner is
7
+ > `Phronomy::MultiAgent::HandoffRunner` under
8
+ > [ADR-034](../decisions/034-handoff-runner-coordination-ownership.md).
9
+ > Handoff and HandoffPolicy remain in Agent at this stage.
10
+
3
11
  This Beta clean break applies to baseline `5472116cd99a63ec27875024c955ea82be612d6b`.
4
12
 
5
13
  | Previous surface | Current surface |
@@ -0,0 +1,37 @@
1
+ # HandoffRunner moves to MultiAgent
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
+
5
+ This change applies to H1 on `refactor/architecture` after core commit
6
+ `fe2ad7cea6945a240858b18645dc4ae285e8ce64`. The released 0.26.0 gem does not
7
+ yet provide this new Runner name.
8
+
9
+ | Previous API | API on this refactoring branch |
10
+ |---|---|
11
+ | `Phronomy::Agent::HandoffRunner` | `Phronomy::MultiAgent::HandoffRunner` |
12
+ | `Phronomy::Agent::Handoff` | Unchanged |
13
+ | `Phronomy::Agent::HandoffPolicy` | Unchanged |
14
+
15
+ The previous Runner name is removed without an alias. Update direct `require`
16
+ paths from `phronomy/agent/handoff_runner` to `phronomy/multi_agent/handoff_runner`
17
+ if used; ordinary `require "phronomy"` continues to use Zeitwerk.
18
+
19
+ Runner initialization still accepts `main_agent:` and `handoffs:`. Its `invoke`,
20
+ `cancel` and `result` methods, `main_agent`/`handoffs` readers and `MAX_HANDOFFS`
21
+ constant retain their behavior. Existing Handoff edges and Policy objects remain
22
+ in the Agent namespace during this first step.
23
+
24
+ Update the core and examples together. When using examples from the corresponding
25
+ refactoring branch, set `PHRONOMY_PATH` to the matching local core checkout before
26
+ resolving bundles or running verification. The examples API preflight rejects an
27
+ older core and checks exact removed constants without mistaking
28
+ `MultiAgent::HandoffRunner` for `MultiAgent::Handoff`.
29
+
30
+ No persisted-record migration or SQL schema change is required. Existing
31
+ HandoffState, Context and execution records are read using the same format,
32
+ identity and revision rules. Recovery still requires compatible current Agent
33
+ definitions and Handoff graph wiring; changing the Runner namespace does not
34
+ relax that requirement.
35
+
36
+ The ownership rationale and remaining work are recorded in
37
+ [ADR-034](../decisions/034-handoff-runner-coordination-ownership.md).
@@ -0,0 +1,43 @@
1
+ # Migrating to neutral Storage SPI 2 (Refactor 35)
2
+
3
+ Apply matching core and examples changes together. Existing SQL databases need
4
+ no schema or payload migration. Applications continue using Persistence domain
5
+ repositories. Direct Backend implementations and callers must migrate.
6
+
7
+ | Previous extension point | SPI 2 |
8
+ |---|---|
9
+ | Eight repository keywords to Backend | `resources: [Resource, ...]` |
10
+ | `backend.agents`, `backend.executions`, etc. | `backend.view.records(resource)`; domain names stay on Persistence |
11
+ | Journal raw repository | `view.streams(resource)` with `Entry::Append` inputs |
12
+ | Raw ContentStore repository | `view.blobs(resource)`; `ContentStore::StoredContents` owns digest behavior |
13
+ | `Storage::Repositories` transaction view | `Storage::View` bound to a transaction scope |
14
+ | `assert_agent_watermark!` on raw Backend | Agent-owned Watermark composes GuardRef, RevisionIs and StreamHeadIs |
15
+ | ActiveExecutionConflictError | UniqueConstraintError with exact resource/constraint; NoRows condition for idle |
16
+ | Three domain-named raw capabilities | spi_version 2 and six neutral capabilities |
17
+
18
+ A driver implements the protected physical operations used by Records, Streams,
19
+ Blobs and guards, plus `storage_transaction`. Reuse the common scope lifecycle;
20
+ do not override `transaction` with a view that bypasses it. Return independent
21
+ Entry values and never decode domain payload to reconstruct index metadata.
22
+ A non-subclass backend must provide the same public protocol and semantics.
23
+ The SQL reference driver receives immutable physical mappings independently of
24
+ resource declarations; no resource-ID case switch selects domain SQL behavior.
25
+
26
+ Repository wrappers obtained inside a transaction expire with that transaction.
27
+ Do not retain them in application objects. Cache root repositories/handles when
28
+ needed: they route to the current transaction on the same thread. Recover from
29
+ an operation failure only outside an explicit inner savepoint. Catching a failure
30
+ inside its failed scope prevents further work and commit. Complete transaction
31
+ blocks normally; return/break/throw raises TransactionError after rollback.
32
+
33
+ Initial Workflow/Handoff saves still use expected_revision nil and return the
34
+ existing domain result. Storage Records itself requires explicit insert versus
35
+ replace. Missing required parent records now consistently raise NotFoundError;
36
+ this closes prior InMemory/SQLite/PG differences for orphan raw writes. Nonempty
37
+ keys and text attributes must be valid UTF-8 without NUL. Nullable unique keys
38
+ are distinct. Domain Journal limit zero remains an empty result.
39
+
40
+ Run the shipped domain and neutral conformance suites, the dedicated SPI 2/RBS
41
+ checks and each physical driver's concurrency/failure tests. For PostgreSQL run
42
+ the real server gate with the matching candidate core, then verify fresh-pool
43
+ reload. Existing S2a CI is historical evidence, not validation of this SPI.
@@ -0,0 +1,49 @@
1
+ # Removal of the internal parallel Chat path
2
+
3
+ This change belongs to the incremental architecture refactor following 0.26.0.
4
+ It does not publish a new gem version.
5
+
6
+ ## Application changes
7
+
8
+ Remove assignments to `Phronomy.configuration.parallel_tool_execution`, including
9
+ assignments inside `Phronomy.configure`. Both the reader and writer are removed;
10
+ there is no compatibility accessor or replacement switch. The former setting
11
+ selected a Chat subclass but did not gate concurrency in the Agent-owned Tool
12
+ execution path. A previous value of `false` did not guarantee serial execution.
13
+
14
+ `Phronomy::MultiAgent::ParallelToolChat` and its file are removed. Do not require
15
+ the old file or instantiate that private class. No `Agent::ParallelToolChat`
16
+ replacement or alias is introduced. Applications that need Agent-owned Tool
17
+ approval, cancellation and execution tracking should enter through the Agent
18
+ invoke/stream APIs. Direct RubyLLM chat use is outside that Agent lifecycle.
19
+
20
+ ## Retained behavior
21
+
22
+ Both complete and streaming calls use ordinary `RubyLLM::Chat`. Before the first
23
+ Tool body runs, the existing RubyLLM callback lets Agent capture every Tool call
24
+ in the complete assistant message. Agent manages Tool authorization, approval,
25
+ dispatch, cancellation and result collection under ADR-010 and ADR-024.
26
+
27
+ On success, every result is associated with its original call ID and recorded
28
+ in request order. All results are included in the next Provider request, after
29
+ the batch completes. Runtime capacity and each Tool's execution mode still
30
+ determine how work can overlap. This change does not introduce a serial Tool
31
+ mode or a partial-result Provider continuation.
32
+
33
+ The old direct-Chat fallback and its RubyLLM-specific callback/Halt behavior are
34
+ removed with the private class. They are not a second supported Agent execution
35
+ API. Agent-level event callbacks keep their existing contract.
36
+
37
+ ## Existing stored records
38
+
39
+ New standard model-config records omit `parallel_tool_execution`. Existing
40
+ ContentStore records and manifest hashes are not rewritten. An existing record
41
+ may still contain that field; materialization preserves its bytes and Agent's
42
+ Chat builder ignores it, just as it ignores other unused model-config fields.
43
+ There is no manifest version change or compatibility branch that reinstates the
44
+ removed Chat class.
45
+
46
+ The regression suite checks materialization and Chat construction for stored
47
+ records containing both historical boolean values. Existing recovery tests
48
+ continue to cover the supported recovery contracts; this change does not add
49
+ execution-resumption or external-effect guarantees.
@@ -0,0 +1,67 @@
1
+ # Migrate the domain Persistence failure contract
2
+
3
+ This change intentionally changes the exception classes exposed by domain
4
+ Persistence operations. Apply it together with application rescue-clause updates;
5
+ there is no compatibility alias. Public method arguments, return values and
6
+ backend SPI 2 do not change.
7
+
8
+ ## Application and domain repository callers
9
+
10
+ For calls through `Persistence`, its eight repositories, Agent, Team and Workflow,
11
+ use the upper contract:
12
+
13
+ | Previous category | New category |
14
+ |---|---|
15
+ | `Phronomy::Storage::ConflictError` | `Phronomy::Persistence::ConflictError` |
16
+ | `Phronomy::Storage::NotFoundError` | `Phronomy::Persistence::NotFoundError` |
17
+ | `Phronomy::Storage::SerializationError` | `Phronomy::Persistence::SerializationError` |
18
+ | `Phronomy::Storage::UnsupportedBackendError` | `Phronomy::Persistence::UnsupportedBackendError` |
19
+
20
+ For example:
21
+
22
+ ```ruby
23
+ begin
24
+ root = persistence.agents.load(agent_id)
25
+ rescue Phronomy::Persistence::NotFoundError => error
26
+ # Handle the missing domain object here.
27
+ logger.info(error.message)
28
+ end
29
+ ```
30
+
31
+ `Persistence::StateConflictError < Persistence::ConflictError` identifies state,
32
+ ownership or revision contradictions raised by upper domain operations. Catch
33
+ ConflictError when the application handles both state and backend conflicts.
34
+ This subtype is not an instruction to retry: retain operation-specific retry and
35
+ recovery policies. Repository CAS/precondition rejections expose ConflictError.
36
+
37
+ Translated backend failures retain their original message/backtrace and expose
38
+ the original exception through `error.cause`. Backend constraint/resource details
39
+ remain there. `AgentBusyError` keeps its existing meaning and original cause;
40
+ only the owning active constraint/condition qualifies for that mapping.
41
+
42
+ ## Backend implementations and raw callers
43
+
44
+ Do **not** globally replace Storage exception names in driver implementations or
45
+ raw `Storage::Backend`/View/Records/Streams/Blobs callers. Those interfaces still
46
+ raise Storage errors. The raw `persistence.backend` accessor exposes that same
47
+ backend. Direct `ContentStore::StoredContents` use also retains its raw failure
48
+ surface; `persistence.contents` applies the upper translation boundary.
49
+
50
+ Core domain repository conformance examples now expect Persistence errors. Raw
51
+ Storage conformance examples continue to expect Storage errors. Tests which
52
+ inject failures at the physical backend should still inject Storage exceptions;
53
+ tests mocking an already translated repository should inject Persistence errors.
54
+
55
+ ## Commit uncertainty and saved data
56
+
57
+ Only the four listed categories are translated. Unknown driver/transport errors,
58
+ including IOError, and Storage::TransactionError pass through as the same object.
59
+ ContentStore::IntegrityError and existing domain errors also retain identity.
60
+ Do not classify every Persistence::Error as a known rollback, and do not add a
61
+ retry for a lost commit acknowledgement. Existing admission, transaction scope,
62
+ rollback, nested savepoint and recovery rules continue to apply.
63
+
64
+ No database migration is required. Saved records and content bytes use the same
65
+ formats. Error class names in newly saved diagnostic payloads can use the new
66
+ Persistence names. Old saved class strings remain diagnostic data; they are not
67
+ resolved as live exception constants or rewritten.
@@ -0,0 +1,36 @@
1
+ # Migrating to r8 unit 10
2
+
3
+ Apply after core d961fc742f6c4ea4d06dc89f20eedfeb49d04099 (unit 9).
4
+ This package changes core only. The unit 6 examples at
5
+ ed455c52018338f7c5a4c2948ae0d7db131aa090 require no source changes.
6
+
7
+ Public TeamCoordinator and HandoffRunner arguments and results are unchanged.
8
+ No database migration or application Registry registration is needed.
9
+ The existing registries remain MultiAgent-owned and preserve their rules.
10
+
11
+ | Internal use | Replacement |
12
+ | --- | --- |
13
+ | AdmissionRegistry.for(runtime) | The owning MultiAgent ExecutionEnvironment.admissions |
14
+ | TeamOwnershipRegistry.for(runtime) | The owning environment.ownership |
15
+ | TeamOwnershipRegistry.existing_for(runtime) | The selected environment.existing_ownership for lookup only |
16
+ | Team/Handoff Runtime.instance checks | The captured environment.current? |
17
+ | Team cancellation Execution.submit(runtime: ...) | The captured environment.submit(...) |
18
+ | Team persistence factory in runtime_composition/agent_defaults.rb | runtime_composition/multi_agent_defaults.rb |
19
+
20
+ Registry construction remains side-effect free. Tests of domain rules can use
21
+ Registry.new; tests of Runtime registration use MultiAgent::EngineEnvironment.
22
+ Removed private class methods have no aliases. Internal callers are updated
23
+ together. New connection classes are private APIs; public RBS signatures stay
24
+ unchanged. Ordinary require "phronomy" installs defaults lazily, without creating
25
+ global configuration, stores or a Runtime during loading.
26
+
27
+ The ZIP includes complete changed files, a strict-base applier, expected-tree
28
+ verification, a review patch, test evidence and rollback instructions. Run
29
+ --check, --apply and --verify in a new worktree, then --verify again after commit.
30
+ Use the existing stop/drain procedure when replacing running processes. This
31
+ change does not add in-flight cross-version compatibility or rollback of
32
+ external effects.
33
+
34
+ For examples verification, unset BUNDLE_GEMFILE before entering the examples
35
+ checkout and set PHRONOMY_PATH to the candidate core. Inspect and restore only
36
+ verification-generated lockfile/vendor changes; no examples commit is needed.
@@ -0,0 +1,33 @@
1
+ # Migrating to r8 unit 11
2
+
3
+ Apply after core eaff581cb8806c707d47649bb561b70690fa9e57 (unit 10).
4
+ This package changes core only. The unit 6 examples at
5
+ ed455c52018338f7c5a4c2948ae0d7db131aa090 require no source changes.
6
+
7
+ No application API changes or database migrations are required. Continue to
8
+ load the library with require "phronomy" and use the existing context_policy
9
+ DSL for explicit policies. The boot composition installs DefaultPolicy through
10
+ that same DSL. Reading an unconfigured internal Base now fails explicitly
11
+ instead of selecting a concrete Policy inside Agent.
12
+
13
+ | Private implementation use | Replacement |
14
+ | --- | --- |
15
+ | Agent::Base concrete Policy fallback | runtime_composition/agent_defaults.rb installs the default |
16
+ | InvocationActions constructs LLMAdapter::AsyncClient | Its captured environment.build_llm_client(adapter: ...) |
17
+ | Agent LLM submission resolves the current global Runtime | EngineEnvironment binds the client to its retained Runtime |
18
+ | AsyncClient constructor | Optional submitter: using existing _ExecutionSubmitter; existing arguments still work |
19
+
20
+ Internal custom ExecutionEnvironment implementations must supply the new client
21
+ capability. It is not a supported application extension API. Clients created
22
+ without an injected submitter preserve their default Runtime behavior; explicit
23
+ pool arguments preserve precedence. Changing the global default Runtime does
24
+ not migrate an existing Agent's resources. Follow the existing stop/drain and
25
+ recreate procedure when replacing running processes.
26
+
27
+ The ZIP contains complete changed files, strict-base application and expected-tree
28
+ verification, a review patch, test evidence and recovery instructions. Run
29
+ --check, --apply and --verify in a new worktree, then --verify after commit.
30
+
31
+ For examples verification, unset BUNDLE_GEMFILE before entering the examples
32
+ checkout and set PHRONOMY_PATH to this core. Inspect and restore only generated
33
+ lockfile/vendor changes; no examples commit is needed.