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
@@ -0,0 +1,79 @@
1
+ # 033: Own persistence rules within each domain
2
+
3
+ - Status: Amended
4
+ - Date: 2026-09-18
5
+ - Error boundary refined by: [043-storage-execution-constraint-notifications](043-storage-execution-constraint-notifications.md)
6
+ - Refines: [032-storage-backend-composition](032-storage-backend-composition.md)
7
+
8
+ The raw fixed-repository/error portions are amended by
9
+ [ADR-058](058-neutral-storage-primitives.md). Domain ownership and applicable
10
+ transaction/uncertainty decisions below remain in force.
11
+
12
+ ## Context
13
+
14
+ ADR-032 separated raw storage from domain persistence, but the common-looking
15
+ `persistence/` directory still collected Agent, Team, and Workflow schemas and
16
+ repository facades. Moving that directory to an upper band in a dependency
17
+ diagram described its contents; it did not establish suitable domain ownership.
18
+ The public Persistence entry point also contained domain-specific result queries.
19
+
20
+ ## Decision
21
+
22
+ 1. `agent/persistence/` owns AgentRoot, Journal, AgentExecution, and Handoff
23
+ codecs/repositories and Agent/Handoff result queries.
24
+ 2. `multi_agent/persistence/` owns TeamRoot and TeamExecution codecs/repositories
25
+ and Team result queries. Team persistence can be used over a raw backend
26
+ without loading Agent implementation or the combined Persistence service.
27
+ 3. `workflow/persistence/` owns the Workflow record schema, normalization rules,
28
+ and state repository. Workflow symbol normalization remains specific to that
29
+ domain; other codecs do not adopt it implicitly.
30
+ 4. `Storage::RecordCodec` contains shared record-envelope and scalar validation.
31
+ Domain codecs extend it; it neither selects nor imports a domain codec.
32
+ These helpers and domain components are private implementation, not new SPI.
33
+ 5. `PersistenceComposition::Repositories` explicitly assembles the seven domain
34
+ repository wrappers and the existing ContentStore from one raw storage view.
35
+ The public `Phronomy::Persistence` service remains the compatible entry point.
36
+ It delegates queries and retains the Runtime observation-thread guard.
37
+ Each view creates and caches domain wrappers on first use, under one lock,
38
+ so Agent-only use does not load Team or Workflow implementations.
39
+ 6. Conversion remains inside `backend.transaction`. Root and transaction paths
40
+ use the same builder. Reusing the root view when the backend yields itself
41
+ retains the existing repository identity and fault-injection behavior.
42
+ 7. Delete the private combined `Persistence::DurableCodec` and
43
+ `Persistence::RepositoryFacades`; do not preserve a second owner through
44
+ compatibility aliases. Explicit historical migration keeps its public API
45
+ and calls the new domain codecs.
46
+
47
+ InMemory, SQLite, and PostgreSQL are all concrete implementations of the common
48
+ Backend contract. Domain repository wrappers are consumers of that contract;
49
+ they do not introduce a second physical transaction boundary.
50
+
51
+ ## Preserved contracts and limits
52
+
53
+ Public Persistence methods, Backend SPI, eight repository accessors, IDs,
54
+ revisions/positions, active constraints, physical SQL schemas, record types,
55
+ format versions, and payload schemas are unchanged. Existing SQL backends need
56
+ no source migration for this ownership change. The public result-reader dispatch
57
+ and observation guard remain in the public entry point.
58
+
59
+ Atomic durable-state transitions and rollback remain CONDITIONAL on a conforming
60
+ backend for F0. Commit-outcome certainty under F1 is not added. F4 restart
61
+ readability depends on retained confirmed data; InMemory is not disk retention.
62
+ X0 effects remain outside storage transactions.
63
+
64
+ The raw `Storage::Repositories` still names eight Phronomy record repositories and
65
+ an Agent watermark operation. This is an explicit intermediate state, not a claim
66
+ that the framework contract is domain-neutral. Contract generalization and naming
67
+ of the final common persistence framework are deferred to the staged plan below.
68
+
69
+ ## Validation
70
+
71
+ Existing record-schema, backend conformance, optimistic conflict, recovery,
72
+ Handoff, Team, Workflow, and public compatibility tests remain required. A
73
+ separate-process boundary test uses Team persistence without Agent, Workflow,
74
+ Runtime, or combined-Persistence loading. Another process uses the public Agent
75
+ repositories without loading Team or Workflow implementations. A failure-injection test rejects the
76
+ Team response after writes and verifies rollback across Agent, Team, and content.
77
+ Dependency analysis must not introduce a new nontrivial file cycle.
78
+
79
+ See [the staged implementation plan](../architecture/persistence-refactoring-plan.md).
@@ -0,0 +1,78 @@
1
+ # ADR-034: Handoff Runner Coordination Ownership
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
+ ## Status
6
+
7
+ Accepted for the H1 step on `refactor/architecture`, 2026-09-18.
8
+ The subsequent Handoff contract and persistence separation is deferred.
9
+
10
+ ## Scope of supersession
11
+
12
+ This amends the Runner placement/public namespace in
13
+ [030-agent-handoff-domain-and-durable-responsibility](030-agent-handoff-domain-and-durable-responsibility.md)
14
+ and the domain map in
15
+ [031-durable-multi-agent-coordination](031-durable-multi-agent-coordination.md).
16
+ All other durable Handoff semantics remain in force.
17
+
18
+ ## Context
19
+
20
+ HandoffRunner validates a graph of concrete Agents, selects the active Agent,
21
+ invokes or resumes exact executions, follows multiple transfers, and scopes
22
+ cancellation/result lookup to a specified chain. Those responsibilities span
23
+ Agents. They differ from an individual Agent's execution, Journal and Context.
24
+
25
+ Calling Handoff from an Agent does not make that whole coordination lifetime an
26
+ Agent implementation detail. Updating the Source and routing state in one
27
+ transaction also does not require them to occupy one module.
28
+
29
+ The Runner and TeamCoordinator share the Runtime-local AdmissionRegistry. Keeping
30
+ the Runner inside Agent creates an Agent-to-MultiAgent concrete dependency.
31
+ Moving only the Runner aligns ownership without generalizing the registry or
32
+ changing the existing shutdown participant contract.
33
+
34
+ ## Decision
35
+
36
+ 1. Move the public Runner implementation from `agent/handoff_runner.rb` to
37
+ `multi_agent/handoff_runner.rb` and expose
38
+ `Phronomy::MultiAgent::HandoffRunner`.
39
+ 2. Remove `Phronomy::Agent::HandoffRunner` without a compatibility alias on the
40
+ refactoring branch. Migrate API documentation, RBS, snapshot and consumers
41
+ together. See the [migration guide](../migrations/handoff-runner-multi-agent.md).
42
+ 3. Retain `Agent::Handoff`, `HandoffPolicy`, Context/Request/State and Agent
43
+ terminal/persistence integration during H1. Qualify the Runner's dependencies
44
+ explicitly. This mixed placement is an intermediate state.
45
+ 4. Keep AdmissionRegistry in MultiAgent. The admission key, exception classes,
46
+ successful-call release and Runtime shutdown participation are unchanged.
47
+ 5. Preserve method parameters/results, record formats, main-Agent anchor,
48
+ deterministic Target IDs, transaction boundaries, exact recovery and scoped
49
+ cancellation. H1 introduces no new execution or shutdown manager.
50
+
51
+ ## Consequences and limits
52
+
53
+ Agent no longer directly names a MultiAgent implementation in production source.
54
+ The Runner's existing Tracing dependency now belongs to the MultiAgent directory.
55
+ Module-edge totals and large strongly connected components need not decrease:
56
+ this step changes responsibility placement, not the underlying algorithm.
57
+
58
+ Agent still interprets Handoff/Team coordination metadata. This logical coupling
59
+ is not removed merely because a directory edge disappears.
60
+
61
+ Later work must separate Request construction, Coordinator selection, Context
62
+ conversion, transaction participation and purge/recovery constraints before
63
+ moving the remaining Handoff-specific types and persistence rules. That work must
64
+ preserve one transaction for Source termination plus responsibility transfer and
65
+ for Target termination plus routing stabilization. It must not promote transferred
66
+ Context into permanent Target Journal/Knowledge or depend on post-commit callbacks
67
+ for coordination correctness.
68
+
69
+ ## Verification obligations
70
+
71
+ The new public constant must load with Zeitwerk and match its RBS/API snapshot;
72
+ the old constant must not remain as an alias. Existing Handoff, multi-hop,
73
+ cancellation/recovery, shutdown and SQLite reconstruction scenarios must pass.
74
+ API guards must distinguish `MultiAgent::HandoffRunner` from the removed exact
75
+ constant `MultiAgent::Handoff`.
76
+
77
+ The implementation delivery records test results separately; this ADR does not
78
+ assert that unexecuted live-LLM or database-server tests passed.
@@ -0,0 +1,68 @@
1
+ # ADR-035: Default Tool Executor Ownership
2
+
3
+ ## Status
4
+
5
+ Accepted on the architecture refactoring branch as T1.
6
+
7
+ This decision assigns the default Tool execution helper to the existing
8
+ Capability implementation. The public Tool facade defined by ADR-015 remains
9
+ the same Class object with the same canonical implementation name.
10
+
11
+ ## Context
12
+
13
+ `Agent::Context::Capability::Base#call_async` delegates default asynchronous
14
+ dispatch to `Agent::ToolExecutor`. The helper selects inline cooperative work
15
+ or OffloadPool submission and returns a TaskResult. It has no responsibility
16
+ for Agent state, approval, persistence, recovery, or multi-Agent coordination.
17
+
18
+ Placing this helper directly under Agent makes the Capability directory depend
19
+ on Agent execution while Agent execution also depends on Capability. The
20
+ underlying helper is part of the Tool calling contract and its standard
21
+ implementation, so its ownership should reflect that role.
22
+
23
+ Moving only the helper to `tool/` would introduce another directory cycle:
24
+ `tool/base.rb` currently aliases `Agent::Context::Capability::Base`. Moving the
25
+ canonical Tool class and changing its runtime name would require a separate
26
+ public compatibility decision.
27
+
28
+ ## Decision
29
+
30
+ 1. Move the helper to
31
+ `Phronomy::Tool::ToolExecutor`, in
32
+ `agent/context/capability/tool_executor.rb`. Classify this helper as private
33
+ API and remove the old internal constant without a compatibility alias.
34
+ 2. Use the new helper from Capability Base and Agent ToolInvocation. Preserve
35
+ the existing dispatch implementation and error messages.
36
+ 3. Keep `Tool::Base` and `Agent::Context::Capability::Base` as the same Class
37
+ object. Preserve their canonical name, DSL state, method-owner checks, and
38
+ the public `call_async(args, cancellation_token:, config:)` protocol.
39
+ 4. Keep Runtime selection, authorization and logical result ownership in Agent
40
+ ToolInvocation. Its standard path passes Runtime and `on_full: :raise` to
41
+ the private helper; custom Tool implementations receive the public protocol.
42
+ Agent-as-Tool continues through its own asynchronous Agent lifecycle.
43
+ 5. Keep the existing TaskResult and OffloadPool mechanisms in Engine. This
44
+ step adds no execution manager or application registration requirement.
45
+
46
+ ## Consequences and limits
47
+
48
+ The Capability directory now directly names its existing Engine dependencies
49
+ instead of an Agent-owned wrapper. The code-level algorithm and file-level
50
+ dependency graph are preserved when the moved file is matched to its source.
51
+ Directory placement changes do not imply that all larger dependency cycles
52
+ have been resolved.
53
+
54
+ Applications should use the public Tool authoring and invocation contracts.
55
+ Code or tests that directly reference the removed private Agent::ToolExecutor
56
+ constant need to follow its new internal name. The public Tool API and durable
57
+ formats require no migration, and the Context contract regrouping remains a
58
+ separate change.
59
+
60
+ ## Verification obligations
61
+
62
+ Verify cooperative execution, OffloadPool dispatch, cancellation propagation,
63
+ Runtime injection, custom `call_async`, and Agent-as-Tool. Keep the existing
64
+ offload-boundary observations aligned with the moved source path. The public
65
+ API snapshot, RBS and Tool class identity must remain unchanged; Zeitwerk must
66
+ load the new helper and leave the old internal constant absent.
67
+
68
+ The implementation delivery records its actual test results separately.
@@ -0,0 +1,86 @@
1
+ # ADR-036: Context Contract Ownership
2
+
3
+ ## Status
4
+
5
+ Accepted on the architecture refactoring branch as C1.
6
+
7
+ This decision clarifies the ownership of existing Context contracts. The
8
+ Journal/Manifest authority model in ADR-012 and the Knowledge model in ADR-013
9
+ remain in force. It does not change either model or introduce a new public API.
10
+
11
+ ## Context
12
+
13
+ `ContextPolicies::Default` depends on `ContextPolicy` and `ContextPolicyInput`.
14
+ Agent execution also consumes these contracts and selects a concrete policy.
15
+ Keeping the contracts beside execution classes directly under `agent/` makes
16
+ the policy directory appear to depend back on Agent execution.
17
+
18
+ The shared vocabulary is broader than a policy base class. Policy inputs refer
19
+ to the previous `LLMInputManifest`; plans and generated items have common
20
+ validation rules; `before_llm_input` hooks exchange typed input and result
21
+ values. Moving only a base class would leave those shared contracts split
22
+ across responsibility groups.
23
+
24
+ The Manifest constructs, validates, and converts record values. It does not
25
+ open transactions or write records to a backend. Its representation therefore
26
+ belongs with the Context contracts used by both producers and consumers.
27
+
28
+ ## Decision
29
+
30
+ 1. Move these seven unchanged files into `lib/phronomy/agent/context_contract/`:
31
+ - `context_policy.rb`
32
+ - `context_policy_input.rb`
33
+ - `context_plan.rb`
34
+ - `context_plan_validator.rb`
35
+ - `llm_input_manifest.rb`
36
+ - `llm_input_build_context.rb`
37
+ - `llm_input_patch.rb`
38
+ 2. Collapse the directory with Zeitwerk, following the existing Engine layout
39
+ mechanism. Keep the existing `Phronomy::Agent::*` definitions and canonical
40
+ names, including nested input and Manifest value types. Add no aliases or
41
+ `Phronomy::Agent::ContextContract` namespace.
42
+ 3. Keep `ContextPolicies::Default` with the concrete policy implementations.
43
+ Keep Context assembly, input building, candidate resolution, Runtime
44
+ integration, hook invocation, and persistence transactions with their
45
+ existing execution-side owners.
46
+ 4. Preserve policy instance binding, the `call(input)` protocol, hook input and
47
+ result types, and the Manifest version and encoded representation. Add no
48
+ descriptor, registry, application registration step, or data migration.
49
+ 5. Treat the contracts and concrete policies as separate responsibility groups.
50
+ They may share a horizontal band in a dependency view. Directory nesting and
51
+ Ruby namespace nesting do not determine architectural dependency direction.
52
+
53
+ ## Consequences and limits
54
+
55
+ Policies and hooks reference the contract definitions in their shared group,
56
+ while Agent execution composes and consumes them. The contract files have no
57
+ static dependency on Agent execution or MultiAgent implementation classes.
58
+ Their dependencies on immutable values, token estimation, canonical JSON,
59
+ shared errors, and Storage serialization errors remain unchanged.
60
+
61
+ The source bodies and mapped file-level dependency graph are preserved. A new
62
+ directory group exposes edges previously internal to `agent/`, so aggregate
63
+ directory edge counts and strongly connected component sizes can increase.
64
+ This is not evidence that the existing file-level cycles were resolved.
65
+
66
+ The contracts still contain Handoff-related categories and metadata vocabulary.
67
+ That semantic coupling belongs to the subsequent Handoff responsibility review.
68
+ The mixed root directory and execution cycles also require separate work.
69
+
70
+ Applications continue to `require "phronomy"` and use the same documented
71
+ constants. Individual implementation paths that previously lived directly
72
+ under `agent/` have moved; no forwarding files are retained at those paths.
73
+
74
+ ## Verification obligations
75
+
76
+ Verify ordinary lazy loading and eager loading, canonical constant names,
77
+ independently accessing each contract, custom Policy binding, Plan validation,
78
+ hook input/result handling, Manifest serialization and restoration, Context
79
+ assembly, and existing migration/persistence integration.
80
+
81
+ Keep the public API snapshot and RBS unchanged. Match each moved file to its
82
+ source when comparing dependencies. Record the removal of direct policy/hook
83
+ references to the execution directory without presenting aggregate graph
84
+ changes as the elimination of all cycles.
85
+
86
+ The implementation delivery records its test results separately.
@@ -0,0 +1,62 @@
1
+ # ADR-037: Common Definition Ownership
2
+
3
+ ## Status
4
+
5
+ Accepted on the architecture refactoring branch.
6
+
7
+ The initial extraction scope is amended by
8
+ [038-responsibility-based-source-layout](038-responsibility-based-source-layout.md),
9
+ which adds reviewed general definitions and relocates feature-owned definitions.
10
+ The common-ownership rule and public Error contract below remain in force.
11
+
12
+ ## Context
13
+
14
+ `lib/phronomy.rb` combines the application loading entry point with shared
15
+ exception definitions and global configuration. Internal consumers of the
16
+ base `Phronomy::Error` therefore refer back to the entry point even though
17
+ they do not explicitly require it.
18
+
19
+ The shared base exception has no dependency on feature implementations. It
20
+ belongs to a common definition group. An `errors/` group would not convey the
21
+ distinction between general definitions and feature-owned exception contracts.
22
+ The same distinction applies to definitions other than exceptions.
23
+
24
+ ## Decision
25
+
26
+ 1. Use `lib/phronomy/common/` for general definitions shared across the
27
+ framework that do not belong to a particular feature. These definitions
28
+ must not depend on concrete Agent, Workflow, Runtime, or other feature
29
+ implementations. Multiple consumers alone do not establish common ownership.
30
+ 2. Move only the base `Phronomy::Error < StandardError` definition from the
31
+ entry point to `common/error.rb`. Name files after their responsibility;
32
+ do not introduce an unbounded `common/common.rb` collection.
33
+ 3. Collapse `common/` with Zeitwerk to retain `Phronomy::Error` as its canonical
34
+ name. Do not introduce a second class, alias, or `Phronomy::Common` namespace.
35
+ Ordinary application loading remains `require "phronomy"`.
36
+ 4. Keep existing subclass definitions, inheritance, constructors, and rescue
37
+ behavior unchanged. Inheriting from `Phronomy::Error` does not require a
38
+ feature-owned exception to live in `common/`.
39
+ 5. Keep the common base independent of entry-point loading. Reading its
40
+ implementation file in isolation must not initialize the full framework.
41
+ This is an internal architecture check, not a new public partial-loading API.
42
+
43
+ ## Consequences and limits
44
+
45
+ Internal references to the shared base resolve to its common definition rather
46
+ than to the loading entry point. The application-facing constant and signatures
47
+ remain unchanged. No new explicit require of the application entry point is
48
+ introduced.
49
+
50
+ Other exceptions still defined in the entry point, global configuration, and
51
+ the mixed root implementation group need separate ownership reviews. This
52
+ single extraction does not establish that all file or directory cycles have
53
+ been eliminated.
54
+
55
+ ## Verification obligations
56
+
57
+ Verify isolated base-definition loading, ordinary application loading, and eager
58
+ loading. Check ordinary and preloaded-base initialization orders, canonical
59
+ constant identity, representative subclass hierarchies, and catching a domain
60
+ exception with `rescue Phronomy::Error`. Preserve the public API snapshot and
61
+ RBS signatures. Compare dependency targets against the applied baseline and
62
+ report remaining entry-point references separately.
@@ -0,0 +1,145 @@
1
+ # ADR-038: Responsibility-Based Source Layout
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
+
9
+ ## Status
10
+
11
+ Accepted on the architecture refactoring branch; configuration/runtime lifecycle
12
+ ownership amended by
13
+ [039-runtime-configuration-lifecycle-ownership](039-runtime-configuration-lifecycle-ownership.md).
14
+ Concrete-default ownership is subsequently amended by
15
+ [040-configuration-default-composition](040-configuration-default-composition.md).
16
+ Agent default selection and one-shot placement are subsequently refined by
17
+ [044-agent-default-and-one-shot-composition](044-agent-default-and-one-shot-composition.md).
18
+ The Workflow recovery prepend requirement is subsequently replaced by direct
19
+ Runner ownership in
20
+ [054-workflow-terminal-save-single-owner](054-workflow-terminal-save-single-owner.md).
21
+
22
+ Amends the extraction scope of
23
+ [037-common-definition-ownership](037-common-definition-ownership.md).
24
+ Its common-ownership rule and public Error contract remain unchanged.
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
+
34
+ ## Context
35
+
36
+ The application loading entry point and the direct `lib/phronomy/` directory
37
+ were distinct sources of mixed ownership. After the base Error extraction,
38
+ the entry point still defined twenty feature/shared exceptions and global
39
+ configuration operations. Thirty-nine direct Ruby files still included
40
+ Workflow implementation, execution contracts, recovery, configuration, and
41
+ general values alongside namespace declarations.
42
+
43
+ A directory's location must describe its responsibility. A public constant
44
+ under `Phronomy` does not require its implementation file to remain directly
45
+ under `lib/phronomy/`. Conversely, a shared consumer list does not make a
46
+ feature contract a general common definition.
47
+
48
+ ## Decision
49
+
50
+ 1. Reserve `lib/phronomy.rb` for application loading and explicit initialization
51
+ wiring. Production implementation files under `lib/phronomy/` must not require that entry
52
+ point. Use Zeitwerk for canonical constant loading and precise requires for
53
+ dependencies and initialization side effects.
54
+ The existing `testing/persistence_contract.rb` is a separately documented
55
+ public entry point for external backend authors. It remains allowed to load
56
+ Phronomy and RSpec, and remains excluded from production automatic loading.
57
+ This single named exception does not exempt other files under `testing/`.
58
+ 2. Allow only these direct Ruby files under `lib/phronomy/`:
59
+
60
+ | File | Reason |
61
+ |---|---|
62
+ | `version.rb` | Bundler/gem metadata convention and Zeitwerk GemInflector's version-file convention |
63
+ | `llm_adapter.rb` | Explicit namespace and extension-SPI documentation |
64
+ | `tool.rb` | Explicit public Tool authoring namespace and documentation |
65
+ | `vector_store.rb` | Explicit namespace and backend-SPI documentation |
66
+ | `output_parser.rb` | Explicit parser namespace declaration |
67
+ | `testing.rb` | Explicit test-support namespace declaration |
68
+ | `filter.rb` | Existing Filter convenience loading entry, without feature implementation |
69
+ | `tracing.rb` | Existing Tracing convenience loading entry, without feature implementation |
70
+
71
+ Namespace files must not accumulate method bodies or concrete classes.
72
+ RubyGems does not mandate this entire allowlist. Keeping these small files
73
+ is an explicit Phronomy design/compatibility choice. New exceptions to the
74
+ allowlist require an ownership reason and an amendment to this decision.
75
+ 3. Extend `common/` with `CanonicalJSON`, `ConfigurationError`, and
76
+ `Values::Immutable`. Preserve their canonical names, JSON representation,
77
+ copy/freeze behavior, and exception hierarchy. The three equivalent private
78
+ Agent copy helpers delegate to `Values::Immutable.copy`; domain-specific
79
+ command copying and Workflow copying keep their different contracts.
80
+ 4. Move the remaining implementation and exception definitions to their owners:
81
+
82
+ | Directory | Responsibility |
83
+ |---|---|
84
+ | `engine/` | EventLoop/FSM communication, synchronous callback constraints, execution composition, cancellation/deadlines, runtime diagnostics, invocation and runnable execution contracts |
85
+ | `recovery/` | Shared recovery vocabulary and execution rehydration requirement; no concrete Agent/Workflow orchestration |
86
+ | `workflow/execution/` | Workflow DSL, context ownership, runner, and terminal persistence recovery |
87
+ | `agent/api/` | Agent namespace/event loading and lifecycle extension installation |
88
+ | `agent/composition/` | One-shot Agent/Persistence composition; method definition loaded by the application entry (ADR-044) |
89
+ | `agent/lifecycle_contract/` | Agent ownership, handoff, and application stream-delivery exceptions |
90
+ | `configuration/` | Global configuration values, defaults, accessors, replacement, and scoped overrides |
91
+ | `runtime_composition/` | Application Runtime/configuration lifecycle coordination and concrete default bindings (ADR-039/040/044) |
92
+ | `llm_contract/` | Token usage, context-budget failures, and LLM call-boundary failures |
93
+ | `llm_adapter/ruby_llm_patches.rb` | RubyLLM version-guarded compatibility patch |
94
+ | `persistence/api/` | Public Persistence facade and repository composition |
95
+ | `generation/` | GeneratorVerifier pipeline and its confidence failure |
96
+ | `tool/contract/`, `filter/contract/`, `output_parser/contract/` | Feature-owned shared exceptions |
97
+
98
+ 5. Preserve all existing Ruby constant names, class/module kinds, inheritance,
99
+ constructors, method visibility, public signatures, and persisted formats.
100
+ Do not add constant aliases or compatibility files at retired implementation
101
+ paths. Ordinary application loading remains `require "phronomy"`; arbitrary
102
+ internal file paths are not a new public partial-loading API.
103
+ 6. Use existing Zeitwerk `collapse` and `push_dir(namespace: Phronomy)` facilities.
104
+ The named nested roots are independent of their enclosing namespace. This
105
+ retains top-level `Phronomy::WorkflowContext` beside existing nested
106
+ `Phronomy::Workflow::Persistence` without collapsing the entire Workflow
107
+ namespace. Load `version.rb` first to establish the non-reloadable Phronomy
108
+ root namespace. Do not depend on facilities introduced after Zeitwerk 2.6.
109
+ 7. Preserve explicit lifecycle initialization. Workflow recovery must be
110
+ prepended during ordinary application loading. Agent event/recovery
111
+ extensions must be installed when Agent is loaded. Keep external patching
112
+ and global namespace reopening files outside automatic name inference.
113
+ Production eager loading must continue to exclude RSpec conformance support.
114
+
115
+ ## Dependency interpretation and limits
116
+
117
+ `Event` is an Engine communication contract, not a general-purpose common
118
+ value. The `InvalidAsync*` family belongs to synchronous FSM callback rules:
119
+ Engine and Agent use the entry-action failure as well as Workflow. Moving that
120
+ contract into Workflow implementation would introduce the wrong dependency.
121
+
122
+ `ExecutionRehydrationRequiredError` belongs to recovery even though its name
123
+ starts with Execution. It is not the timeout/cancellation outcome of fan-out
124
+ composition. `ConfigurationError` is common; `Configuration` is not. Default
125
+ configuration still constructs a concrete LLM adapter and tracer. This change
126
+ groups that existing composition but does not make it implementation-neutral.
127
+
128
+ Directory relocation does not establish that every remaining dependency is
129
+ downward or that all cycles disappear. Preserve and report actual references.
130
+ An analyzer must resolve namespace operations to their defining implementation
131
+ instead of treating the shortest namespace reopening as the owner of every
132
+ method. Do not mistake a loading entry point for the implementation it loads.
133
+
134
+ ## Verification obligations
135
+
136
+ - Check the direct-root allowlist and forbid internal entry-point requires.
137
+ - Verify normal and eager loading, independent common/exception loading,
138
+ preloaded common definitions, nested-namespace access orders, and preserved
139
+ lifecycle extension installation.
140
+ - Exercise the supported Zeitwerk lower bound and the current locked version.
141
+ - Preserve the API snapshot and RBS without regenerating away a difference.
142
+ - Run existing execution, Workflow, Agent, persistence/recovery, integration,
143
+ configuration, and serialization tests; run the repository style/type gates.
144
+ - Compare dependencies against the applied baseline with the same analyzer.
145
+ Mark candidate results as unapplied and identify the exact source tree.
@@ -0,0 +1,82 @@
1
+ # ADR-039: Runtime and Configuration Lifecycle Ownership
2
+
3
+ ## Status
4
+
5
+ Accepted on the architecture refactoring branch.
6
+
7
+ Concrete-default ownership in decision 1 is amended by
8
+ [040-configuration-default-composition](040-configuration-default-composition.md).
9
+ The reset ownership and algorithm below remain current.
10
+
11
+ Amends the configuration ownership in
12
+ [038-responsibility-based-source-layout](038-responsibility-based-source-layout.md).
13
+ Its loading rules, direct-root allowlist, and compatibility requirements remain
14
+ in force.
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
+
24
+ ## Context
25
+
26
+ `Phronomy.reset_runtime!` shuts down the default Runtime and replaces global
27
+ configuration only after successful Runtime cleanup. Its configuration grace
28
+ period preservation is application lifecycle coordination between two owners.
29
+ Placing this operation in `configuration/global_configuration.rb` made ordinary
30
+ configuration readers point to a file that also controlled Runtime shutdown.
31
+
32
+ Engine reads configuration for pool sizes, logging, and shutdown defaults.
33
+ Configuration access must not also own the reverse Runtime lifecycle operation.
34
+ Moving that operation into `common/` would give common definitions an Engine
35
+ dependency. Moving it into an Engine primitive would mix global configuration
36
+ replacement with Runtime execution mechanics.
37
+
38
+ ## Decision
39
+
40
+ 1. Keep configuration values, concrete defaults, global access, replacement,
41
+ and scoped overrides in `configuration/`.
42
+ 2. Place `Phronomy.reset_runtime!` in
43
+ `runtime_composition/global_runtime.rb`. This responsibility group coordinates
44
+ Runtime and configuration. Engine and configuration implementation files
45
+ must not require the composition file or the application entry point.
46
+ 3. Keep this namespace-reopening file outside Zeitwerk name inference. Load it
47
+ explicitly from `lib/phronomy.rb` after global configuration access is
48
+ available. Do not introduce a `Phronomy::RuntimeComposition` constant,
49
+ compatibility alias, registration hook, or alternate reset API.
50
+ 4. Preserve the reset method body and signature. In particular, Runtime cleanup
51
+ happens before configuration replacement; an error from cleanup propagates
52
+ without resetting configuration. Preserve the timeout default, previous
53
+ grace value handling, laziness of the default Runtime, and return value.
54
+
55
+ ## Dependency interpretation and remaining work
56
+
57
+ The direct configuration-to-Runtime reference moves to the composition owner.
58
+ Ordinary configuration readers still resolve to the configuration accessor
59
+ file. Reference analysis must resolve each `Phronomy` operation to its actual
60
+ method definition, not assign every operation to an arbitrary namespace file.
61
+
62
+ This step does not remove the separate cycle formed by concrete defaults:
63
+ `Configuration` constructs `LLMAdapter::RubyLLM`, its base supplies asynchronous
64
+ execution through `Runtime`, and Runtime reads global configuration. The
65
+ default tracer is also concrete. Preserving `Configuration.new` behavior while
66
+ separating default construction requires a separate design decision. Do not
67
+ hide these references with dynamic constant lookup or claim that the entire
68
+ configuration/Engine cycle has disappeared.
69
+
70
+ ## Verification obligations
71
+
72
+ - Guard that configuration files can be loaded without loading Engine or
73
+ Runtime composition, exposing the reset operation, or directly referencing
74
+ Runtime. This loading check does not promise a new public partial-loading API.
75
+ - Verify ordinary application loading exposes the existing reset API and eager
76
+ loading creates no synthetic composition namespace.
77
+ - Compare production method definitions against the preceding layout candidate;
78
+ this extraction changes no method bodies.
79
+ - Run the existing configuration, Runtime lifecycle, shutdown participant,
80
+ compatibility, and integration tests and repository style/type gates.
81
+ - Report remaining cycles with the same analyzer and distinguish the unapplied
82
+ candidate source tree from the applied baseline commit.