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,83 @@
1
+ # ADR-058: Neutral Storage primitives and scoped transactions
2
+
3
+ ## Status
4
+
5
+ Accepted. Applied and verified in Refactor 35 (Storage S2b/S2c), core
6
+ `ebd99623f94c8b2db2d74355bfa39f01550778a0` and examples
7
+ `68a0bbd0e354b9e00bbfed728ad2b769b389ed8a`.
8
+
9
+ Domain-facing exception ownership is further amended by
10
+ [061-persistence-failure-contracts](061-persistence-failure-contracts.md).
11
+ Raw backend exceptions remain owned by Storage; domain repository exits now
12
+ translate their known categories to independent Persistence exceptions.
13
+
14
+ ## Context
15
+
16
+ S1 inventoried 37 raw methods across eight required domain slots. Moving their
17
+ classes did not remove Agent watermark or active-owner policy from shared
18
+ storage. S2a fixed concrete transaction and update differences first. S2b now
19
+ changes the extension contract while preserving domain APIs and durable data.
20
+
21
+ ## Decision
22
+
23
+ 1. Replace the eight-slot Backend/Repositories SPI with declared Resources and
24
+ Records, Streams, Blobs accessed through View. Storage has no domain codecs,
25
+ active-execution interpretation, content digest or Agent watermark method.
26
+ 2. Keep schemas, encoding, initial revisions, active-state interpretation and
27
+ metadata validation in their features. Composition gathers declarations and
28
+ builds domain wrappers. Team/Workflow schema loader roots do not load runtime.
29
+ 3. Use named equality indexes, conditional unique constraints, immutable metadata,
30
+ revision CAS, stream head CAS and a closed guarded-condition set. Parent guards
31
+ precede child locks. Required parent absence is uniformly NotFoundError.
32
+ 4. Keep one transaction domain, scoped views, same-connection savepoints and root
33
+ handle routing. Reject expired/cross-thread views and failed physical scopes.
34
+ Reject non-local block exits with TransactionError and rollback. A successful
35
+ optional read returning nil is not a failed physical operation.
36
+ 5. Report neutral UniqueConstraintError(resource ID, constraint name) and
37
+ ConditionFailedError(condition). Only owning domain repositories map exact
38
+ active constraints to AgentBusyError. Remove the old domain-named error alias.
39
+ 6. Share neutral SQL operations in examples/shared/storage, with explicit dialect
40
+ differences and separate domain/table composition. Keep all existing tables,
41
+ indexes, envelope formats, payloads, IDs and content bytes. Nullable unique-key
42
+ fields are distinct, matching SQL default uniqueness semantics.
43
+
44
+ ## Supersession scope
45
+
46
+ This amends ADR-032's raw eight-slot contract, ADR-033's remaining fixed raw
47
+ boundary, ADR-043's domain-named raw exception and ADR-057's old-SPI-only limit.
48
+ Their domain ownership, composition, savepoint and uncertainty decisions remain.
49
+ No historical artifact is silently reinterpreted as a current SPI specification.
50
+
51
+ ## Public contract and migration
52
+
53
+ Persistence's constructor, in_memory, eight accessors, result queries and public
54
+ capabilities remain. Backend SPI 2 is intentionally breaking; legacy duck-typed
55
+ backends fail capability validation. There is no compatibility facade or alias.
56
+ See the [contract](../persistence-backends.md), [migration guide](../migrations/neutral-storage-spi.md),
57
+ RBS and explicit SPI 2 snapshot. Ordinary product API snapshots remain separate.
58
+
59
+ ## Validation and remaining gates
60
+
61
+ Shared conformance tests cover opaque data, CAS, named constraints, parents,
62
+ Unicode cursor ordering, streams, binary blobs, all-resource rollback, nested
63
+ savepoints, view lifetime, thread confinement and non-local exits. Domain tests
64
+ retain F0/F1/F4 behavior and X0 limitations. SQLite old/new/old round-trip checks
65
+ cover all eight resources and unchanged schema. The applied SPI 2 pair passed
66
+ [PostgreSQL 17.11 CI](https://github.com/Raizo-TCS/phronomy-examples/actions/runs/35827495677)
67
+ on Ruby 3.2/3.3/3.4, with 119 examples per version and fresh-pool reload. Both
68
+ checkout SHAs were verified. Earlier SPI CI was not used as substitute evidence.
69
+ No stronger commit certainty, distributed Workflow admission or external-effect
70
+ retry is introduced.
71
+
72
+ ## S3 internal responsibility clarification
73
+
74
+ Refactor 36 keeps all public SPI 2 signatures and Resource identity rules.
75
+ Resource normalizes a schema object or resource ID before GuardRef/Condition
76
+ construction; the cooperation method is `@api private`, not a new backend
77
+ extension point. Generic Validation handles scalar validation and copying and
78
+ must not depend on Resource. View still enforces catalog membership and exact
79
+ schema identity. This removes the internal Resource/Validation cycle without
80
+ changing a public name, transaction, stored record or physical backend.
81
+
82
+ See the [closure review](../architecture/refactoring-closure.md) for retained
83
+ placements and the separate distribution application gate.
@@ -0,0 +1,74 @@
1
+ # ADR-059: Backend Contracts, Implementations and Execution Clients
2
+
3
+ ## Status
4
+
5
+ Accepted; P1/P2/P3/P4 (LLM, VectorStore, Embeddings, Storage/ContentStore and
6
+ diagram tooling) implemented. Final P5 review remains pending, as recorded in
7
+ [Backend responsibilities](../architecture/backend-groups.md).
8
+
9
+ ContentStore's classification and directory split are superseded by
10
+ [ADR-062](062-content-store-service.md): content management is a service over
11
+ Storage, outside Backend Contracts and Backend Implementations. The other
12
+ contract/client/backend separations remain in force.
13
+
14
+ ## Context
15
+
16
+ The synchronous LLMAdapter SPI and its RubyLLM implementation shared a directory
17
+ with private async methods that referenced Runtime. Adapter authors were told
18
+ to implement only synchronous methods, but Base still coupled the SPI to Engine.
19
+ Numbered diagram bands also implied an ordering between independent concerns.
20
+
21
+ ## Decision
22
+
23
+ 1. Use independent responsibility groups with stable identifiers. Engine,
24
+ Contracts, Async Clients and Implementations are distinct; coordinates and
25
+ group numbers do not define dependency permissions. For readability, restore
26
+ the earlier B1-B6 horizontal display bands and topical columns; these are
27
+ presentation metadata independent of the responsibility annotations. Place
28
+ separated Contracts in B5, distinct from Engine, and Async Clients in B4.
29
+ Keep Implementations separately grouped in B4; mark unsplit backends there
30
+ as pending instead of presenting their contracts as already separated.
31
+ 2. Keep `LLMAdapter::Base` synchronous. Move internal async wrappers into
32
+ `LLMAdapter::AsyncClient`; Agent supplies its configured adapter to the client.
33
+ The public SPI, configuration setting and RubyLLM constant remain unchanged.
34
+ 3. Separate contract/client/implementation directories, using explicit Zeitwerk
35
+ collapse to retain feature namespaces. Do not make a common Async namespace,
36
+ add a Base-to-client factory, or install an include/prepend compatibility hook.
37
+ 4. Implementations depend on Contracts. Contracts and implementations do not
38
+ reference Engine or clients; clients use Contracts and Engine through normal
39
+ constant references or object injection, without selecting concrete providers.
40
+ 5. Preserve original TaskResult, non-waiting admission failure, token semantics,
41
+ no additional operation timeout, provider-owned retries and EventLoop callback
42
+ delivery. Resolve the default pool at operation time; do not cache it across
43
+ Runtime resets. Explicit pool injection leaves lifecycle ownership to its owner.
44
+ 6. Generate SVG and boundary evidence from each committed source revision.
45
+ Maintain the individual module boxes, IDs, full dependency matrix and source
46
+ evidence. A phase cannot declare completion while legacy dependencies remain.
47
+
48
+ The vector/embedding SPI and namespace clauses are amended by
49
+ [ADR-065](065-vector-and-embeddings-common-operations.md).
50
+
51
+ ## Consequences
52
+
53
+ This supersedes the remaining LLM Base-to-Runtime coupling described in ADR-040.
54
+ ADR-027's synchronous public provider-call boundary and materialization caveat
55
+ still apply: this change does not make RubyLLMMaterializer provider-neutral.
56
+ P2 keeps the LLM client internal. P3 introduces public VectorStore/Embeddings
57
+ AsyncClients and moves async receivers off the synchronous backends. Their
58
+ argument conventions and execution semantics are unchanged; the receiver
59
+ migration is intentional and documented. Storage operations do not change in
60
+ P3. P4 adds public raw `transaction_async` and a private submit path for existing
61
+ Agent/Workflow/coordination units. The latter opens no transaction and leaves
62
+ uncertain-result policy with each owner. P4 originally moved ContentStore's
63
+ implementation into a backend directory; ADR-062 removes that unnecessary split
64
+ and classifies it as a content service. Other repository cycles remain visible.
65
+
66
+ Transparent module/caption panels and hidden incoming arrows to M33/M41/M44 are
67
+ presentation settings only. The full measured graph, matrix and boundary rules
68
+ remain unchanged by that filtering.
69
+
70
+ Boundary tests cover direct and indirect reverse dependencies and keep group
71
+ IDs independent from policy. Runtime tests cover sync-only custom adapters,
72
+ worker/EventLoop separation, rejection, exceptions, cancellation and Runtime
73
+ reset. CI produces artifacts with the actual source SHA rather than committing
74
+ a diagram containing its own commit hash.
@@ -0,0 +1,86 @@
1
+ # ADR-060: Runtime Settings and Application Configuration
2
+
3
+ ## Status
4
+
5
+ The settings membership is amended by
6
+ [r8 unit21](../architecture/r8-unit21.md): Tool owns its result limit and Tracing
7
+ owns tracer/recording settings. RuntimeSettings retains logger and execution
8
+ resource values. The original decision below records the earlier checkpoint;
9
+ lazy composition, public compatibility and the strict dependency rules remain.
10
+
11
+ Accepted for this refactoring. Amends the configuration ownership in
12
+ [038-responsibility-based-source-layout](038-responsibility-based-source-layout.md),
13
+ [039-runtime-configuration-lifecycle-ownership](039-runtime-configuration-lifecycle-ownership.md)
14
+ and [040-configuration-default-composition](040-configuration-default-composition.md).
15
+
16
+ ## Context
17
+
18
+ Engine consumes pool sizes, time thresholds, a logger and an injected tracer.
19
+ Application `Configuration` also exposes an LLM adapter, Agent input hook and
20
+ other domain options. Their correct public RBS types reveal an Engine-to-domain
21
+ path when Engine reads the whole Configuration. A two-reference baseline allowed
22
+ this old type debt through the regression gate. Weakening the types, hiding
23
+ arrows or misassigning RBS owners would not repair the dependency.
24
+
25
+ ## Decision
26
+
27
+ 1. `configuration/` owns private `RuntimeSettings`: neutral runtime values and
28
+ injected logger/tracer objects, with no application-specific type references.
29
+ Engine and automatic tracing read this limited object.
30
+ 2. Application `Configuration` and the global `configuration`, `configure`,
31
+ `reset_configuration!` and `with_configuration` operations belong to
32
+ `runtime_composition/`. Canonical Ruby names, constructor and public RBS types
33
+ remain unchanged. The directory is collapsed by Zeitwerk; no public
34
+ `RuntimeComposition` namespace is introduced.
35
+ 3. Configuration composes RuntimeSettings and explicitly delegates its existing
36
+ runtime-setting accessors. It retains adapter, Agent and application options.
37
+ RBS follows the actual Ruby owner: application declarations live under
38
+ `sig/phronomy/runtime_composition/`, internal settings under `sig/_private/`.
39
+ 4. Composition installs a lazy, typed provider returning only RuntimeSettings.
40
+ Every read resolves the current object so reset/scoped restoration cannot
41
+ leave Engine reading an expired configuration. Binding does not initialize
42
+ global configuration or start Runtime. This provider is private framework
43
+ wiring, not an application extension point or a new execution service.
44
+ 5. Copying Configuration copies its settings container while retaining injected
45
+ component identities. This preserves the previous flat object's shallow-copy
46
+ behavior, including nested scopes, exception restoration and a first scope
47
+ entered before global configuration exists. This change adds no thread-local
48
+ configuration semantics or live pool resizing.
49
+ 6. Remove the two-reference baseline. Require the complete Ruby + RBS union to
50
+ pass all existing responsibility rules. Also reject settings paths reaching
51
+ any non-common responsibility.
52
+
53
+ ## Direct dependencies are evaluated by responsibility
54
+
55
+ LLM error/TokenUsage contracts are already abstract vocabulary, so routing them
56
+ through a concrete adapter would make coupling worse. Backend implementation,
57
+ schema, migration, async bridge and conformance-suite dependencies on Storage
58
+ contracts are intentional. Domain repositories translate records, guards and
59
+ backend errors and legitimately know that SPI.
60
+
61
+ Domain runners that raise StorageConflictError for ownership/revision decisions
62
+ are a separate candidate for a persistence/domain error contract. Existing
63
+ recovery distinguishes known failure from uncertain commit outcomes; introduce
64
+ such a vocabulary only with an explicit compatibility and failure-classification
65
+ design. Do not substitute a forwarding wrapper or broadly catch StandardError.
66
+
67
+ Engine's TaskResult, Runnable and FSM contracts are the execution abstractions
68
+ used by runners and async clients. A higher-level Agent facade is not a
69
+ replacement for the mechanism that implements Agent itself. Ordinary synchronous
70
+ evaluation work can use `Blocking.call_async`: LlmJudge now does so instead of
71
+ accessing Runtime's pool. Dedicated-pool cleanup, concurrency-limited orchestration
72
+ and tracing with nonwaiting admission handling retain their specialized owners.
73
+
74
+ ## Verification and graph interpretation
75
+
76
+ Preserve public signature declarations, settings defaults/accessor semantics,
77
+ subclass construction, cold loading, reset/scoped restoration and runtime pool
78
+ configuration. Check scorer provider/admission failures, the full regression
79
+ suite, RBS validation and strict dependency rules. No network provider is needed
80
+ for these behavior checks.
81
+
82
+ SVG topology must show the actual declaration owners and keep all evidence,
83
+ even for display-hidden arrows. Application configuration shares the composition
84
+ directory with lifecycle/default wiring; its directory SCC may grow because
85
+ unrelated members aggregate. Report directory SCCs and Ruby file SCCs separately;
86
+ do not claim that all cycles have disappeared or that fewer arrows is the goal.
@@ -0,0 +1,89 @@
1
+ # ADR-061: Domain Persistence failure contracts
2
+
3
+ - Status: Accepted
4
+ - Date: 2026-09-26
5
+ - Amends: [032-storage-backend-composition](032-storage-backend-composition.md) and [058-neutral-storage-primitives](058-neutral-storage-primitives.md), only for the exception surface exposed above raw Storage.
6
+
7
+ ## Context
8
+
9
+ Agent execution, ownership, Handoff, Recovery, Team coordination and Workflow
10
+ interpret durable failures, but previously referenced raw Storage exception
11
+ classes even when they did not perform raw storage operations. A domain state
12
+ contradiction and a physical compare-and-swap rejection had the same owner.
13
+ Moving or aliasing those classes would keep backend and domain contracts coupled.
14
+
15
+ ## Decision
16
+
17
+ Define independent public errors in `persistence/contract/`, under the existing
18
+ `Phronomy::Persistence` namespace: Error, ConflictError, StateConflictError,
19
+ NotFoundError, SerializationError and UnsupportedBackendError. Error inherits
20
+ Phronomy::Error. StateConflictError inherits Persistence::ConflictError; the other
21
+ four categories inherit Persistence::Error. No class inherits a Storage error,
22
+ and no compatibility alias is introduced. The contract depends only on Common.
23
+
24
+ The selected upper domain consumers raise StateConflictError for their own
25
+ ownership/revision/state contradictions. Backend CAS conflicts, including
26
+ repository precondition conflicts, expose Persistence::ConflictError. Existing
27
+ conflict retry/catch sites also accept StateConflictError by inheritance.
28
+
29
+ An internal `Persistence::StorageBoundary` maps exactly four Storage categories
30
+ (ConflictError, NotFoundError, SerializationError, UnsupportedBackendError) to
31
+ the corresponding Persistence category. It preserves message and backtrace and
32
+ sets the original exception as `cause`. Mapping happens at domain repository
33
+ exits and Persistence construction/transaction exits. Existing repository-local
34
+ constraint interpretation runs first: only the matching active-owner unique
35
+ constraint or exact NoRows condition becomes AgentBusyError. Other raw conflict
36
+ subclasses map to Persistence::ConflictError with their metadata in `cause`.
37
+
38
+ Domain repositories continue to own codecs and record validation. Decode checks
39
+ remain inside the physical atomic block, so a malformed write response still
40
+ rolls back before translation. The translator creates no transaction or task.
41
+ The same boundary covers root and transaction repository views, watermark checks,
42
+ and persisted manifest reading. A private ContentRepository adapts the existing
43
+ StoredContents primitive methods for the upper failure contract; the independent
44
+ ContentStore backend retains its content identity and integrity semantics.
45
+
46
+ Unknown exceptions, Storage::TransactionError, ContentStore::IntegrityError,
47
+ AgentBusyError and already translated Persistence errors pass through unchanged.
48
+ Persistence::Error is a base type, not a blanket known-not-committed classifier.
49
+ Each existing caller retains its exact category set, including intentional
50
+ three-category/four-category differences and ArgumentError/ConfigurationError.
51
+ A lost commit acknowledgement must not become a known rejection or trigger a
52
+ new retry. F0/F1/F4 recovery and X0 limitations are unchanged.
53
+
54
+ ## Loading and ownership
55
+
56
+ Contracts can be loaded without Storage, Engine, Agent or a driver. Ordinary
57
+ framework loading explicitly installs the canonical Persistence service before
58
+ Zeitwerk setup, so an earlier contract load cannot suppress service methods or
59
+ change class identity. This does not construct a backend or start a Runtime.
60
+ The API class is still defined in `persistence/api/persistence.rb`. Namespace
61
+ reopenings in helpers are not its declaration owner for dependency analysis.
62
+
63
+ ## Public migration and preservation
64
+
65
+ Calls through Persistence now expose Persistence errors rather than Storage
66
+ errors. This is an intentional public exception contract change; applications
67
+ must migrate relevant rescue clauses. Raw backend/driver code keeps Storage
68
+ errors. See the [migration guide](../migrations/persistence-failure-contracts.md).
69
+
70
+ Existing public method/RBS declarations remain; six error classes are added.
71
+ SPI 2, tables, record envelopes, revisions, content IDs and all eight repository
72
+ transaction semantics remain unchanged. Stored error class names are diagnostic
73
+ data: new failures may name Persistence errors, while old saved names remain
74
+ readable without rewriting or constantizing them.
75
+
76
+ ## Verification and diagram
77
+
78
+ Tests inject real backend failures through all eight repository accessors and
79
+ check cause/trace, no double translation, unknown-error identity, commit-response
80
+ loss, nested savepoints, post-write validation rollback and AgentBusyError.
81
+ Existing domain recovery, admission, conformance and integration suites remain
82
+ required. Raw Storage isolation tests continue to reject domain/Engine loading.
83
+
84
+ Ruby + RBS boundary validation rejects raw Storage references from the eight
85
+ reviewed upper directories and rejects non-Common reachability from Persistence
86
+ Contracts. It does not whitelist the new dependencies. G55 shows the translation
87
+ boundary and G56 the independent domain failure contracts in the existing banded
88
+ layout. All measured edges remain in evidence and the matrix; presentation-only
89
+ incoming-arrow filters do not change boundary results.
@@ -0,0 +1,52 @@
1
+ # ADR-062: ContentStore is a content service over Storage
2
+
3
+ - Status: Accepted
4
+ - Date: 2026-09-28
5
+ - Amends: ADR-059's ContentStore classification and source subdivision only.
6
+
7
+ ## Context
8
+
9
+ ContentStore was grouped with synchronous backend contracts, and StoredContents
10
+ with physical backend implementations. InMemory and SQL instead implement
11
+ Storage::Backend. Composition always constructs StoredContents over that
12
+ backend's view. ContentStore adds content-derived IDs, canonical text/JSON and
13
+ digest verification; it is not another physical-storage selection point.
14
+
15
+ ## Decision
16
+
17
+ Treat `content_store/` as a content management service. Move StoredContents from
18
+ `content_store/backends/` into this directory, next to Base and StorageSchema.
19
+ Delete the empty backend subdivision and its Zeitwerk collapse, without a
20
+ forwarding file, alias or alternative implementation-selection API.
21
+
22
+ Keep Base: both StoredContents and Persistence::ContentRepository use its shared
23
+ text/JSON operations. Keep ContentRepository: it translates known Storage
24
+ failures at the Persistence boundary. These classes are used responsibilities,
25
+ not obsolete backend scaffolding. StorageSchema is owned by the content service.
26
+
27
+ Retain the dependency from the service to neutral Storage. Storage owns physical
28
+ I/O, immutable blobs and transactions. The content service must not select a
29
+ physical backend or depend on Engine, Async Clients or domain orchestration;
30
+ Storage contracts and implementations must not depend on the content service.
31
+
32
+ ## Compatibility and presentation
33
+
34
+ Public constants and RBS, private constant identities, content IDs, resource IDs,
35
+ database schema, exception behavior and root/transaction composition stay the
36
+ same. In particular, StoredContents' missing-content errors are still raw Storage
37
+ errors, translated by the Persistence facade. This change does not introduce an
38
+ independent ContentStore exception contract or alter commit uncertainty policy.
39
+
40
+ M10 moves to G57 Content Service, displayed in B3's persistence column. M73 is
41
+ retired and never reused. G47/G48 contain no ContentStore modules. Keep the
42
+ existing banded layout, group colors, module outlines, transparent text panels
43
+ and presentation-only common-arrow filters. Preserve every measured Ruby/RBS
44
+ edge, including the service-to-Storage edge; compare counts knowing that two
45
+ source directories have become one. Historical baseline evidence is immutable.
46
+
47
+ ## Verification
48
+
49
+ Existing loading, content, Persistence conformance and transaction tests cover
50
+ the source move. The full Ruby + RBS boundary gate allows the intended Storage
51
+ dependency and rejects direct/indirect reverse or concrete-backend coupling.
52
+ The independent architecture regression also injects RBS-only violations.
@@ -0,0 +1,88 @@
1
+ # ADR-063: Execution Contracts, Services and Engine Internals
2
+
3
+ > Historical decision. Superseded by [r8 unit 1](../architecture/r8-unit1.md): Execution contracts and services are now united, with mechanism binding in Engine.
4
+
5
+ **Status**: Accepted for implementation
6
+ **Date**: 2026-09-28
7
+ **Refines**: [038-source-layout](038-responsibility-based-source-layout.md),
8
+ [045-worker-input](045-worker-input-restriction-ownership.md) and
9
+ [059-backend-groups](059-backend-contracts-and-async-clients.md)
10
+
11
+ ## Problem
12
+
13
+ Engine grouped public result/call APIs, shared value/error/marker contracts and
14
+ private schedulers together. A WorkerInputRestricted include or an RBS token
15
+ reference consequently appeared to be a dependency on worker machinery.
16
+ ToolBinding also implemented its own result transformation. It forwarded the
17
+ source's physical-completion signal before the result filter had finished;
18
+ Agent execution quiescence could therefore observe an incomplete transformation
19
+ as physically complete.
20
+
21
+ ## Decision
22
+
23
+ Keep public constants and split source ownership into three responsibility groups:
24
+
25
+ | Group | Directory | Owns |
26
+ |---|---|---|
27
+ | G58 Execution Contracts | `execution_contract/`, `execution_contract/concurrency/` | Runnable, InvocationContext, Event, FSMProtocol, shared failures, CancellationToken and WorkerInputRestricted |
28
+ | G59 Execution Services | `execution_services/` | TaskResult, Execution, Blocking, and outcome-bearing execution errors |
29
+ | G14 Engine Internals | `engine/`, `engine/concurrency/`, `engine/runtime/` | Runtime, EventLoop, FSMSession, receivers, pools, queues and control/result-composition machinery |
30
+
31
+ Zeitwerk collapses the two new root directories. Existing `Phronomy::*` and
32
+ `Phronomy::Concurrency::*` constants keep their identity, signatures and
33
+ behavior. No new public namespace or forwarding file is introduced. Public RBS
34
+ declarations remain in `sig/` but follow their actual source owners.
35
+
36
+ Contracts may depend only on Execution Contracts and Common responsibilities,
37
+ including neutral RuntimeSettings. This is a boundary contract, not a claim
38
+ that every class is methodless: CancellationToken retains its existing state
39
+ and callbacks, and Runnable retains its default tracing switch. InvocationContext
40
+ can carry opaque execution bindings without constructing a scheduler.
41
+
42
+ Execution Services contain real implementation. TaskResult uses Engine's result
43
+ composition and wait guards; Engine pools create TaskResults. This mutual
44
+ dependency remains explicit. The split does not assert an acyclic layer
45
+ hierarchy. Backend Contracts and implementations may not reach either services
46
+ or Engine, including through RBS references.
47
+
48
+ ToolBinding delegates callback-based transformation to a private TaskResult
49
+ entry point backed by ResultComposition. Physical completion now requires both
50
+ source physical completion and transformation completion. The callback-only
51
+ path preserves custom result handles, failure identity, name, no inherited
52
+ execution scope, and the existing behavior that cancelling the filtered result
53
+ does not cancel its source or suppress the later filter. Public map/flat_map
54
+ scope and parent semantics are unchanged.
55
+
56
+ Tracing finish and approval notification use Blocking.call_async for generic
57
+ default-pool work. Both observe the returned failure because Blocking converts
58
+ admission errors into failed results. Approval callbacks that fail after dispatch
59
+ are now also logged. Checks that only ask whether code runs on EventLoop use
60
+ Runtime.in_event_loop_context?, avoiding construction of a Runtime merely to
61
+ answer that question.
62
+
63
+ ## Retained direct dependencies
64
+
65
+ AsyncClients are execution bridges and retain Runtime/pool access, specialized
66
+ pools, tokens and result types. Agent/Workflow runners and registries still own
67
+ FSM sessions, control delivery, single-writer state and lifecycle coordination.
68
+ Replacing these with a generic wrapper would conceal required ownership rather
69
+ than remove it. Registry receiver lookup is not redesigned in this change.
70
+ See the [usage inventory](../architecture/execution-boundaries.md).
71
+
72
+ ## Compatibility and verification
73
+
74
+ `require "phronomy"` remains the public loading contract. Old implementation
75
+ file paths move without compatibility shims. Public signatures and API snapshot,
76
+ transactions, pool admission policy and timeout/cancellation ownership are
77
+ unchanged. No backend author must implement another async method.
78
+
79
+ Test blocked success/failure filters against a real pool, cancellation and custom
80
+ completion handles; rejected tracing/approval dispatch and asynchronous callback
81
+ failure; standalone marker loading and eager loading without Runtime creation;
82
+ the public signatures and full Ruby/RBS boundary graph. Existing unit,
83
+ integration, coverage, style, benchmark and SQLite contracts remain required.
84
+
85
+ The measured SVG retains B1-B6 display bands, pastel group backgrounds, module
86
+ boxes and transparent text. G59 is in B4 and G58 in B5; these positions grant
87
+ no dependency permission. Incoming M33/M41/M44 arrows remain visually hidden
88
+ while every dependency stays in the matrix, audit and boundary checks.
@@ -0,0 +1,36 @@
1
+ # ADR-064: Agent execution and MultiAgent responsibility
2
+
3
+ Status: accepted for the r8 unit 4 implementation. This amends the Handoff and
4
+ coordination ownership portions of ADR-030, ADR-031, ADR-034 and ADR-051.
5
+ Acceptance records the authorized design; database validation is reported separately.
6
+
7
+ Agent owns execution identity, durable admission, semantic observations, finalized
8
+ input projection, dispatch prerequisites, terminal changes, retention and
9
+ cancellation intent. MultiAgent owns subagent slot reservations/import progress
10
+ and Handoff policy, routing, target reservations and history lifecycle.
11
+
12
+ A versioned, synchronous participant joins Agent's `ExecutionChange` in one outer
13
+ Persistence scope. It receives semantic inputs, acquires ordered guards, captures
14
+ the pre-state through `prepare_in`, writes its own records and invokes `commit_in`
15
+ once. Agent owns validation, record writes and publication after commit. Complete
16
+ before/after evidence reconciles ambiguous responses; revision equality alone
17
+ does not prove success. No generic raw-record update hook or compatibility alias
18
+ is introduced.
19
+
20
+ Current application wiring is supplied on resume/load and is never serialized.
21
+ A saved extension records only binding key, version and content reference.
22
+ MultiAgent calls exact execution APIs rather than Agent repositories or private
23
+ recovery machinery. Persisted holds prevent purge until the referencing domain
24
+ atomically removes its history and releases its own holds.
25
+
26
+ AgentExecution format 0.2 replaces old coordination metadata. An explicit,
27
+ quiescent export/convert/import/verify process preserves IDs, revisions, content
28
+ and unresolved outcomes in a separate destination. Runtime does not interpret
29
+ old formats. The shared SQL drivers provide runnable migration and rejection of
30
+ populated destinations. The complete migration path must be tested on each
31
+ production backend before cutover.
32
+
33
+ Runtime shutdown/AdmissionRegistry and other Engine dependencies remain later r8
34
+ work. The measured source graph continues to expose them. See
35
+ [implementation responsibilities](../architecture/r8-unit4.md) and
36
+ [API/data migration](../migrations/r8-unit4.md).
@@ -0,0 +1,38 @@
1
+ # ADR-065: Vector and Embeddings common operations
2
+
3
+ Status: accepted for the authorized r8 unit 5 implementation. Actual-service
4
+ verification is reported separately from the design decision.
5
+
6
+ This amends ADR-059's vector/embedding extension and namespace provisions.
7
+ Its synchronous backend boundary, separate AsyncClients and no production worker
8
+ Threads rule remain in force. It implements C10/C11 and DP09/DP10 from the agreed
9
+ contract foundation target.
10
+
11
+ VectorStore::Base and Embeddings::Base own the public operation templates,
12
+ validation and cancellation checkpoint. Concrete backends override protected
13
+ perform_* hooks, retaining algorithms, database/SDK adaptation and physical state.
14
+ VectorStore does not require an embedding provider, and Embeddings does not depend
15
+ on VectorStore. Documents groups the existing Loader/Splitter helpers without
16
+ creating another domain Contract.
17
+
18
+ Placement is decided by domain meaning and observable rules, not shared use.
19
+ Generic reusable code does not become a Contract merely because multiple callers
20
+ need it. Database response parsing and SDK/serialization adaptation remain
21
+ implementation responsibilities even when several backends perform similar work.
22
+
23
+ Malformed public inputs fail before backend I/O. Malformed backend results fail
24
+ explicitly. Provider exceptions are adapted at the provider boundary, never by
25
+ rescuing arbitrary application failures in the common framework. No generic retry,
26
+ commit reconciliation or stronger concurrency guarantee is added.
27
+
28
+ Backends must reject malformed external data before converting it to the public
29
+ result. Redis RESP2 fields/counts/distances and Pgvector rows/JSON are decoded
30
+ inside their own backends, with `VectorStore::InvalidResultError` as the public
31
+ failure for invalid data. Legitimate absent metadata and Redis's documented
32
+ expired-document response are distinguished from corruption. The common Base
33
+ then validates the domain result; it contains no external-protocol decoder.
34
+
35
+ Old namespaces and public-template overrides are intentionally replaced without
36
+ compatibility aliases. Runtime API, RBS, contract tests, examples and migration
37
+ guidance move together. See [unit 5](../architecture/r8-unit5.md) and
38
+ [migration](../migrations/r8-unit5.md).
@@ -0,0 +1,20 @@
1
+ # ADR-066: LLM and Tool operation contracts
2
+
3
+ Status: Accepted for the r8 unit 6 candidate; application verification is separate.
4
+
5
+ C09 owns model-turn values, operation invariants, usage and failures. C06 owns Tool
6
+ requests, schemas, validation, authorization and execution rules. Shared usage is
7
+ not a placement criterion. SDK wire parsing/rendering and callback interception
8
+ remain in the RubyLLM backend. Agent owns context, approval, durable execution and
9
+ recovery; AsyncClient submits the complete backend operation to Execution.
10
+
11
+ Tool::Base becomes independent of RubyLLM::Tool. The schema used for advertisement
12
+ is also the validation source for both declaration paths. C09 depends only on C06
13
+ value/schema semantics, never executable Tool instances. Protected hooks allow a
14
+ minimal independent backend; public complete/stream enforce the common contract.
15
+ No forwarding namespace or legacy SDK-shaped adapter SPI is retained.
16
+
17
+ Consequences and compatibility are recorded in
18
+ [unit 6 architecture](../architecture/r8-unit6.md) and
19
+ [unit 6 migration](../migrations/r8-unit6.md). Existing pending execution schema
20
+ comparisons remain strict; deployment must account for changed Tool definitions.
@@ -0,0 +1,29 @@
1
+ # ADR-067: Agent progress owns policy; composition supplies its execution connection
2
+
3
+ Status: accepted for r8 unit 7 candidate. Supersedes the construction ownership
4
+ portion of the Agent transition design; durable guarantees are unchanged.
5
+
6
+ ## Decision
7
+
8
+ Keep progress rules, entry operations, admission, approval and recovery decisions
9
+ inside Agent. Introduce the private ExecutionEnvironment connection and an Engine
10
+ implementation. Bind a live Agent to the environment of its ownership registry.
11
+ Move concrete session/phase-machine construction to agent/runtime_binding.
12
+ Keep state_machines out of InvocationTransitions. Extract the serial receiver
13
+ lifecycle framework to Execution with an Engine-owned channel implementation.
14
+
15
+ ## Why
16
+
17
+ The old session builder mixed domain operations with concrete FSM construction.
18
+ Repeated Runtime.instance lookups made execution connection selection implicit.
19
+ Moving all code into a binding would relocate the same semantic mixture.
20
+ A contract owns executable rules, not just signatures or forwarding methods.
21
+
22
+ ## Consequences
23
+
24
+ The application invoke/stream/approval/recovery API is unchanged. Internal
25
+ AgentInvocationSessionBuilder is removed with no alias. Private receiver
26
+ constructors now accept a channel. Internal embedders must adopt the composition
27
+ port and respect serial mutation, bounded submission, shutdown and session
28
+ incarnation rules. Tool child and other domain FSM decomposition remain separate
29
+ work. See ../architecture/r8-unit7.md for scope and verification.
@@ -0,0 +1,36 @@
1
+ # ADR-068: Agent owns Tool child progress; Tool owns its operation protocol
2
+
3
+ Status: accepted for the r8 unit 8 candidate. Extends
4
+ [067-agent-progress-and-engine-connection](067-agent-progress-and-engine-connection.md)
5
+ to Tool children and refines the operation boundary in
6
+ [066-llm-and-tool-operation-contracts](066-llm-and-tool-operation-contracts.md).
7
+
8
+ ## Decision
9
+
10
+ Keep Tool child transitions, approval waiting, dispatch eligibility, outcome
11
+ application and parent notification in C04. Use one ordered transition definition
12
+ for both concrete FSM construction and source admission. Move FSMSession and
13
+ state_machines construction into Agent runtime_binding. Pass the original Agent
14
+ execution environment explicitly to child authorization and execution.
15
+
16
+ C06 owns standard/custom Tool operation dispatch, execution-mode validity,
17
+ completion protocol and result adaptation. It accepts the C13 submitter protocol
18
+ for standard offloaded work. Agent uses the public operation rather than
19
+ inspecting the implementation owner and calling the private default executor.
20
+ Custom Tool#call_async overrides keep their public signature and own mechanism.
21
+
22
+ ## Reason
23
+
24
+ The previous builder mixed Agent rules with concrete connections and duplicated
25
+ transition definitions. Agent also selected Tool implementation paths in both
26
+ invocation and result binding. Moving whole classes to an adapter or assigning
27
+ all Tool-related progress to C06 would preserve or misplace those responsibilities.
28
+
29
+ ## Consequences
30
+
31
+ The boundary now supports independent Agent policy tests and Engine adaptation
32
+ tests. No concrete Runtime or Agent type enters C06. Existing durable identity,
33
+ approval/recovery, causal revision and physical-quiescence guarantees remain.
34
+ No new exactly-once or in-flight version compatibility is claimed. See
35
+ [the unit 8 scope](../architecture/r8-unit8.md) and
36
+ [migration instructions](../migrations/r8-unit8.md).