phronomy 0.27.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 (475) hide show
  1. checksums.yaml +4 -4
  2. data/.mutant.yml +9 -9
  3. data/CHANGELOG.md +52 -0
  4. data/CONTRIBUTING.md +8 -8
  5. data/README.md +9 -3
  6. data/benchmark/bench_agent_invoke.rb +25 -50
  7. data/benchmark/bench_context_assembler.rb +14 -11
  8. data/benchmark/bench_regression.rb +1 -1
  9. data/benchmark/bench_tool_schema.rb +1 -1
  10. data/docs/architecture/agent-chat-and-state-ownership.md +7 -1
  11. data/docs/architecture/agent-transition-ownership.md +13 -89
  12. data/docs/architecture/backend-groups.md +152 -0
  13. data/docs/architecture/before-llm-input.md +3 -3
  14. data/docs/architecture/context-management.md +1 -1
  15. data/docs/architecture/execution-abstraction-review.md +88 -0
  16. data/docs/architecture/execution-boundaries.md +28 -0
  17. data/docs/architecture/execution-metadata-and-values.md +6 -0
  18. data/docs/architecture/multi-agent-handoff.md +6 -5
  19. data/docs/architecture/persistence.md +27 -9
  20. data/docs/architecture/r8-unit1.md +104 -0
  21. data/docs/architecture/r8-unit10.md +72 -0
  22. data/docs/architecture/r8-unit11.md +71 -0
  23. data/docs/architecture/r8-unit12.md +67 -0
  24. data/docs/architecture/r8-unit13.md +61 -0
  25. data/docs/architecture/r8-unit14.md +72 -0
  26. data/docs/architecture/r8-unit15.md +65 -0
  27. data/docs/architecture/r8-unit16.md +54 -0
  28. data/docs/architecture/r8-unit17.md +73 -0
  29. data/docs/architecture/r8-unit18.md +92 -0
  30. data/docs/architecture/r8-unit19.md +61 -0
  31. data/docs/architecture/r8-unit2.md +55 -0
  32. data/docs/architecture/r8-unit20.md +51 -0
  33. data/docs/architecture/r8-unit21.md +79 -0
  34. data/docs/architecture/r8-unit22.md +74 -0
  35. data/docs/architecture/r8-unit23.md +81 -0
  36. data/docs/architecture/r8-unit3.md +130 -0
  37. data/docs/architecture/r8-unit4.md +79 -0
  38. data/docs/architecture/r8-unit5.md +115 -0
  39. data/docs/architecture/r8-unit6.md +71 -0
  40. data/docs/architecture/r8-unit7.md +70 -0
  41. data/docs/architecture/r8-unit8.md +78 -0
  42. data/docs/architecture/r8-unit9.md +73 -0
  43. data/docs/architecture/refactoring-closure.md +10 -1
  44. data/docs/architecture/remaining-refactoring-plan.md +16 -0
  45. data/docs/architecture/storage-execution-boundaries.md +54 -0
  46. data/docs/architecture/tool-schema-recording-gap.md +6 -0
  47. data/docs/architecture/tracing.md +1 -1
  48. data/docs/architecture/workflow-terminal-ownership-design.md +2 -2
  49. data/docs/architecture.md +24 -11
  50. data/docs/decisions/015-tool-public-facade-and-rbs-boundary.md +3 -3
  51. data/docs/decisions/027-llm-adapter-provider-boundary.md +2 -0
  52. data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +2 -0
  53. data/docs/decisions/031-durable-multi-agent-coordination.md +2 -0
  54. data/docs/decisions/032-storage-backend-composition.md +5 -0
  55. data/docs/decisions/034-handoff-runner-coordination-ownership.md +2 -0
  56. data/docs/decisions/035-tool-executor-capability-ownership.md +1 -1
  57. data/docs/decisions/038-responsibility-based-source-layout.md +14 -0
  58. data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +8 -0
  59. data/docs/decisions/040-configuration-default-composition.md +12 -1
  60. data/docs/decisions/045-worker-input-restriction-ownership.md +4 -0
  61. data/docs/decisions/051-execution-outcome-worker-ownership.md +2 -0
  62. data/docs/decisions/056-workflow-terminal-policy-ownership.md +1 -1
  63. data/docs/decisions/058-neutral-storage-primitives.md +5 -0
  64. data/docs/decisions/059-backend-contracts-and-async-clients.md +74 -0
  65. data/docs/decisions/060-runtime-settings-and-application-configuration.md +86 -0
  66. data/docs/decisions/061-persistence-failure-contracts.md +89 -0
  67. data/docs/decisions/062-content-store-service.md +52 -0
  68. data/docs/decisions/063-execution-contracts-and-services.md +88 -0
  69. data/docs/decisions/064-agent-execution-and-multi-agent-responsibility.md +36 -0
  70. data/docs/decisions/065-vector-and-embeddings-common-operations.md +38 -0
  71. data/docs/decisions/066-llm-and-tool-operation-contracts.md +20 -0
  72. data/docs/decisions/067-agent-progress-and-engine-connection.md +29 -0
  73. data/docs/decisions/068-agent-tool-child-progress-and-tool-operation.md +36 -0
  74. data/docs/decisions/README.md +18 -1
  75. data/docs/execution-boundaries-preview.md +45 -0
  76. data/docs/features.md +8 -3
  77. data/docs/getting-started.md +9 -6
  78. data/docs/migrations/0.22.md +2 -2
  79. data/docs/migrations/durable-semantic-coordination-v2.md +2 -0
  80. data/docs/migrations/handoff-runner-multi-agent.md +2 -0
  81. data/docs/migrations/persistence-failure-contracts.md +67 -0
  82. data/docs/migrations/r8-unit10.md +36 -0
  83. data/docs/migrations/r8-unit11.md +33 -0
  84. data/docs/migrations/r8-unit12.md +31 -0
  85. data/docs/migrations/r8-unit13.md +36 -0
  86. data/docs/migrations/r8-unit14.md +31 -0
  87. data/docs/migrations/r8-unit15.md +31 -0
  88. data/docs/migrations/r8-unit16.md +26 -0
  89. data/docs/migrations/r8-unit17.md +28 -0
  90. data/docs/migrations/r8-unit18.md +29 -0
  91. data/docs/migrations/r8-unit19.md +28 -0
  92. data/docs/migrations/r8-unit20.md +24 -0
  93. data/docs/migrations/r8-unit21.md +28 -0
  94. data/docs/migrations/r8-unit22.md +29 -0
  95. data/docs/migrations/r8-unit23.md +20 -0
  96. data/docs/migrations/r8-unit4.md +67 -0
  97. data/docs/migrations/r8-unit5.md +75 -0
  98. data/docs/migrations/r8-unit6.md +109 -0
  99. data/docs/migrations/r8-unit7.md +31 -0
  100. data/docs/migrations/r8-unit8.md +33 -0
  101. data/docs/migrations/r8-unit9.md +28 -0
  102. data/docs/migrations/storage-async-client.md +103 -0
  103. data/docs/migrations/vector-async-clients.md +110 -0
  104. data/docs/persistence-backends.md +38 -21
  105. data/docs/runtime-and-concurrency.md +26 -1
  106. data/lib/phronomy/agent/admission.rb +78 -0
  107. data/lib/phronomy/agent/{lifecycle_contract/agent_already_exists_error.rb → agent_already_exists_error.rb} +1 -1
  108. data/lib/phronomy/agent/{lifecycle_contract/agent_busy_error.rb → agent_busy_error.rb} +1 -1
  109. data/lib/phronomy/agent/{lifecycle_contract/agent_purged_error.rb → agent_purged_error.rb} +1 -1
  110. data/lib/phronomy/{recovery → agent/api}/execution_rehydration_required_error.rb +1 -1
  111. data/lib/phronomy/agent/async_event_api.rb +37 -32
  112. data/lib/phronomy/agent/base.rb +74 -72
  113. data/lib/phronomy/agent/before_llm_input.rb +64 -0
  114. data/lib/phronomy/agent/composition/run_once.rb +1 -1
  115. data/lib/phronomy/agent/{context_assembly/context_candidate_resolver.rb → context_candidate_resolver.rb} +2 -2
  116. data/lib/phronomy/agent/{context_assembly/context_assembler.rb → context_preparation.rb} +35 -221
  117. data/lib/phronomy/agent/control_request.rb +21 -0
  118. data/lib/phronomy/agent/execution/agent_execution.rb +1 -1
  119. data/lib/phronomy/agent/execution/agent_invocation.rb +27 -53
  120. data/lib/phronomy/agent/execution/approval_resume_commit.rb +1 -1
  121. data/lib/phronomy/agent/execution/dispatch_preparation.rb +17 -127
  122. data/lib/phronomy/agent/execution/exact_execution.rb +44 -23
  123. data/lib/phronomy/agent/execution/execution_cancellation.rb +8 -4
  124. data/lib/phronomy/agent/execution/execution_coordinator.rb +214 -395
  125. data/lib/phronomy/agent/execution/execution_metadata.rb +1 -0
  126. data/lib/phronomy/agent/execution/execution_outcome_committer.rb +70 -126
  127. data/lib/phronomy/agent/execution/execution_registry.rb +6 -2
  128. data/lib/phronomy/agent/execution/execution_session_runner.rb +22 -27
  129. data/lib/phronomy/agent/execution/initial_preparation.rb +18 -116
  130. data/lib/phronomy/agent/execution/{agent_invocation_session_builder.rb → invocation_actions.rb} +54 -194
  131. data/lib/phronomy/agent/execution/invocation_transitions.rb +39 -1
  132. data/lib/phronomy/agent/execution/runtime_record_encoder.rb +7 -7
  133. data/lib/phronomy/agent/execution_change.rb +161 -0
  134. data/lib/phronomy/agent/execution_environment.rb +36 -0
  135. data/lib/phronomy/agent/execution_extension_state.rb +21 -0
  136. data/lib/phronomy/agent/execution_observation.rb +35 -0
  137. data/lib/phronomy/agent/filterable.rb +182 -0
  138. data/lib/phronomy/agent/handoff/{handoff_context.rb → transfer_context.rb} +4 -4
  139. data/lib/phronomy/agent/handoff/{handoff_projection.rb → transfer_projection.rb} +14 -33
  140. data/lib/phronomy/{llm_contract/transport_error.rb → agent/handoff_error.rb} +1 -1
  141. data/lib/phronomy/agent/journal/journal_projection.rb +1 -1
  142. data/lib/phronomy/agent/knowledge_item.rb +13 -0
  143. data/lib/phronomy/agent/lifecycle/agent_root.rb +1 -1
  144. data/lib/phronomy/agent/lifecycle/ownership_registry.rb +18 -23
  145. data/lib/phronomy/agent/persistence/agent_repository.rb +29 -21
  146. data/lib/phronomy/agent/persistence/cancellation_repository.rb +51 -0
  147. data/lib/phronomy/agent/persistence/codec.rb +1 -21
  148. data/lib/phronomy/agent/persistence/execution_repository.rb +57 -41
  149. data/lib/phronomy/agent/persistence/journal_repository.rb +27 -18
  150. data/lib/phronomy/agent/persistence/records.rb +33 -0
  151. data/lib/phronomy/agent/persistence/retention_repository.rb +70 -0
  152. data/lib/phronomy/agent/persistence/storage_schema.rb +7 -2
  153. data/lib/phronomy/agent/persistence/watermark.rb +13 -11
  154. data/lib/phronomy/agent/recovery/invocation_restorer.rb +13 -21
  155. data/lib/phronomy/agent/recovery/recovery_coordinator/continuation.rb +10 -9
  156. data/lib/phronomy/agent/recovery/recovery_coordinator/installation.rb +27 -27
  157. data/lib/phronomy/agent/recovery/recovery_coordinator/resolution.rb +19 -21
  158. data/lib/phronomy/agent/recovery/recovery_coordinator.rb +23 -16
  159. data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
  160. data/lib/phronomy/agent/recovery/recovery_support.rb +8 -11
  161. data/lib/phronomy/agent/reserved_execution.rb +16 -0
  162. data/lib/phronomy/agent/retention.rb +17 -0
  163. data/lib/phronomy/agent/runtime_binding/engine_environment.rb +60 -0
  164. data/lib/phronomy/agent/runtime_binding/engine_session_builder.rb +34 -0
  165. data/lib/phronomy/agent/runtime_binding/phase_machine_builder.rb +64 -0
  166. data/lib/phronomy/agent/runtime_binding/tool_session_builder.rb +34 -0
  167. data/lib/phronomy/agent/{context_assembly/ruby_llm_materializer.rb → runtime_input.rb} +18 -35
  168. data/lib/phronomy/agent/{context_assembly/saved_context_reader.rb → saved_context_reader.rb} +6 -4
  169. data/lib/phronomy/agent/settings.rb +47 -0
  170. data/lib/phronomy/agent/{context_assembly/state_writer.rb → state_writer.rb} +4 -3
  171. data/lib/phronomy/agent/store.rb +253 -0
  172. data/lib/phronomy/agent/{lifecycle_contract/stream_callback_error.rb → stream_callback_error.rb} +1 -1
  173. data/lib/phronomy/agent/tool_execution/tool_binding.rb +4 -64
  174. data/lib/phronomy/agent/tool_execution/tool_invocation.rb +50 -219
  175. data/lib/phronomy/agent/tool_execution/tool_invocation_actions.rb +107 -0
  176. data/lib/phronomy/agent/tool_execution/tool_invocation_transitions.rb +70 -0
  177. data/lib/phronomy/configuration/runtime_settings.rb +49 -0
  178. data/lib/phronomy/content_store/storage_schema.rb +1 -0
  179. data/lib/phronomy/content_store/stored_contents.rb +2 -1
  180. data/lib/phronomy/context/assembly.rb +202 -0
  181. data/lib/phronomy/{llm_contract/context_budget_exceeded_error.rb → context/budget_exceeded_error.rb} +3 -1
  182. data/lib/phronomy/context/candidate.rb +51 -0
  183. data/lib/phronomy/context/constraint.rb +47 -0
  184. data/lib/phronomy/{agent/context_contract → context}/context_plan.rb +1 -1
  185. data/lib/phronomy/{agent/context_contract → context}/context_plan_validator.rb +3 -3
  186. data/lib/phronomy/{agent/context_contract → context}/context_policy.rb +1 -1
  187. data/lib/phronomy/{agent/context_contract → context}/context_policy_input.rb +1 -1
  188. data/lib/phronomy/{agent/context_assembly → context}/context_policy_input_builder.rb +1 -1
  189. data/lib/phronomy/context/default_policy.rb +140 -0
  190. data/lib/phronomy/context/final_budget_validator.rb +33 -0
  191. data/lib/phronomy/{agent/context_contract → context}/llm_input_build_context.rb +1 -1
  192. data/lib/phronomy/{agent/context_contract → context}/llm_input_manifest.rb +19 -19
  193. data/lib/phronomy/{agent/context_contract → context}/llm_input_patch.rb +1 -1
  194. data/lib/phronomy/context/manifest_error.rb +10 -0
  195. data/lib/phronomy/context/prompt_template.rb +98 -0
  196. data/lib/phronomy/{vector_store → documents}/loader/base.rb +1 -1
  197. data/lib/phronomy/{vector_store → documents}/loader/csv_loader.rb +2 -2
  198. data/lib/phronomy/{vector_store → documents}/loader/markdown_loader.rb +3 -3
  199. data/lib/phronomy/{vector_store → documents}/loader/plain_text_loader.rb +2 -2
  200. data/lib/phronomy/{vector_store → documents}/splitter/base.rb +1 -1
  201. data/lib/phronomy/{vector_store → documents}/splitter/fixed_size_splitter.rb +2 -2
  202. data/lib/phronomy/{vector_store → documents}/splitter/recursive_splitter.rb +2 -2
  203. data/lib/phronomy/embeddings/async/async_client.rb +44 -0
  204. data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +48 -0
  205. data/lib/phronomy/embeddings/base.rb +43 -0
  206. data/lib/phronomy/embeddings/invalid_result_error.rb +11 -0
  207. data/lib/phronomy/embeddings/transport_error.rb +11 -0
  208. data/lib/phronomy/engine/concurrency/offload_pool.rb +36 -21
  209. data/lib/phronomy/engine/concurrency/pool_registry.rb +47 -12
  210. data/lib/phronomy/engine/diagnostics.rb +1 -1
  211. data/lib/phronomy/engine/event_loop.rb +7 -7
  212. data/lib/phronomy/engine/execution_binding.rb +23 -0
  213. data/lib/phronomy/engine/execution_receiver_binding.rb +43 -0
  214. data/lib/phronomy/engine/fsm_protocol.rb +1 -6
  215. data/lib/phronomy/engine/fsm_session.rb +3 -3
  216. data/lib/phronomy/engine/metrics.rb +16 -14
  217. data/lib/phronomy/engine/runtime/timer_queue.rb +1 -1
  218. data/lib/phronomy/engine/runtime.rb +25 -12
  219. data/lib/phronomy/engine/terminal_decision.rb +7 -0
  220. data/lib/phronomy/execution/async_operation.rb +41 -0
  221. data/lib/phronomy/{engine → execution}/blocking.rb +2 -2
  222. data/lib/phronomy/{engine → execution}/concurrency/cancellation_token.rb +1 -1
  223. data/lib/phronomy/{engine → execution}/concurrency/deadline.rb +0 -17
  224. data/lib/phronomy/{engine → execution}/concurrency/physical_completion_task.rb +1 -1
  225. data/lib/phronomy/{engine → execution}/concurrency/result_collector.rb +1 -1
  226. data/lib/phronomy/{engine → execution}/concurrency/result_composition.rb +33 -12
  227. data/lib/phronomy/{engine/concurrency/subscriptions.rb → execution/concurrency/result_subscriptions.rb} +14 -18
  228. data/lib/phronomy/execution/concurrency/subscriptions.rb +25 -0
  229. data/lib/phronomy/{engine → execution}/execution.rb +61 -27
  230. data/lib/phronomy/execution/execution_receiver.rb +78 -0
  231. data/lib/phronomy/execution/execution_scope_state.rb +35 -0
  232. data/lib/phronomy/{engine → execution}/invocation_context.rb +0 -15
  233. data/lib/phronomy/execution/invocation_controls.rb +73 -0
  234. data/lib/phronomy/execution/runnable.rb +24 -0
  235. data/lib/phronomy/{engine → execution}/task_result.rb +3 -3
  236. data/lib/phronomy/execution/wait_policy.rb +24 -0
  237. data/lib/phronomy/filter/{contract/filter_block_error.rb → filter_block_error.rb} +1 -1
  238. data/lib/phronomy/generation/generator_verifier/agent_operation.rb +65 -0
  239. data/lib/phronomy/generation/generator_verifier/default_parser.rb +27 -0
  240. data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +2 -2
  241. data/lib/phronomy/generation/generator_verifier.rb +7 -7
  242. data/lib/phronomy/llm_adapter/async/async_client.rb +47 -0
  243. data/lib/phronomy/{llm_contract → llm_adapter}/authentication_error.rb +3 -1
  244. data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +183 -0
  245. data/lib/phronomy/llm_adapter/base.rb +49 -68
  246. data/lib/phronomy/{llm_contract → llm_adapter}/context_length_error.rb +3 -1
  247. data/lib/phronomy/llm_adapter/invalid_result_error.rb +10 -0
  248. data/lib/phronomy/llm_adapter/message.rb +62 -0
  249. data/lib/phronomy/{llm_contract → llm_adapter}/rate_limit_error.rb +3 -1
  250. data/lib/phronomy/llm_adapter/request.rb +79 -0
  251. data/lib/phronomy/llm_adapter/response.rb +36 -0
  252. data/lib/phronomy/llm_adapter/stream_chunk.rb +18 -0
  253. data/lib/phronomy/llm_adapter/token_usage.rb +64 -0
  254. data/lib/phronomy/llm_adapter/transport_error.rb +9 -0
  255. data/lib/phronomy/llm_adapter.rb +3 -16
  256. data/lib/phronomy/multi_agent/admission_registry.rb +1 -8
  257. data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +108 -84
  258. data/lib/phronomy/multi_agent/execution_environment.rb +29 -0
  259. data/lib/phronomy/{agent/handoff → multi_agent}/handoff.rb +2 -2
  260. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_capability_factory.rb +21 -2
  261. data/lib/phronomy/multi_agent/handoff_participant.rb +79 -0
  262. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_policy.rb +1 -1
  263. data/lib/phronomy/multi_agent/handoff_runner.rb +77 -100
  264. data/lib/phronomy/{agent/handoff → multi_agent}/handoff_state.rb +1 -1
  265. data/lib/phronomy/multi_agent/orchestrator.rb +61 -75
  266. data/lib/phronomy/multi_agent/persistence/codec.rb +20 -0
  267. data/lib/phronomy/multi_agent/persistence/handoff_state_repository.rb +77 -0
  268. data/lib/phronomy/multi_agent/persistence/records.rb +27 -0
  269. data/lib/phronomy/multi_agent/persistence/storage_schema.rb +21 -0
  270. data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +58 -42
  271. data/lib/phronomy/multi_agent/persistence/team_repository.rb +29 -21
  272. data/lib/phronomy/multi_agent/reserved_child_admission.rb +88 -0
  273. data/lib/phronomy/multi_agent/runtime_binding/engine_environment.rb +35 -0
  274. data/lib/phronomy/multi_agent/shared_state.rb +2 -2
  275. data/lib/phronomy/multi_agent/store.rb +156 -0
  276. data/lib/phronomy/multi_agent/team_coordinator.rb +83 -74
  277. data/lib/phronomy/multi_agent/team_ownership_registry.rb +2 -12
  278. data/lib/phronomy/output_parser/parse_error.rb +7 -0
  279. data/lib/phronomy/persistence/content_repository.rb +26 -0
  280. data/lib/phronomy/persistence/errors.rb +16 -0
  281. data/lib/phronomy/persistence/migration/initial_format_migration.rb +2 -2
  282. data/lib/phronomy/persistence/persistence.rb +23 -0
  283. data/lib/phronomy/persistence/save_outcome.rb +24 -0
  284. data/lib/phronomy/persistence/snapshot_comparison.rb +81 -0
  285. data/lib/phronomy/persistence/storage_boundary.rb +32 -0
  286. data/lib/phronomy/persistence/transaction.rb +86 -0
  287. data/lib/phronomy/persistence_composition/storage_schema.rb +9 -4
  288. data/lib/phronomy/persistence_composition/stores.rb +34 -0
  289. data/lib/phronomy/persistence_composition/unit4_migration.rb +276 -0
  290. data/lib/phronomy/runtime_composition/agent_defaults.rb +5 -1
  291. data/lib/phronomy/runtime_composition/configuration.rb +146 -0
  292. data/lib/phronomy/runtime_composition/evaluation_defaults.rb +7 -0
  293. data/lib/phronomy/runtime_composition/execution_defaults.rb +5 -0
  294. data/lib/phronomy/runtime_composition/generation_defaults.rb +6 -0
  295. data/lib/phronomy/runtime_composition/global_configuration.rb +38 -0
  296. data/lib/phronomy/runtime_composition/multi_agent_defaults.rb +9 -0
  297. data/lib/phronomy/runtime_composition/workflow_defaults.rb +4 -0
  298. data/lib/phronomy/storage/async/async_client.rb +60 -0
  299. data/lib/phronomy/storage/backend.rb +8 -2
  300. data/lib/phronomy/testing/eval/metrics.rb +1 -1
  301. data/lib/phronomy/testing/eval/scorer/llm_judge.rb +19 -3
  302. data/lib/phronomy/testing/persistence_contract/a_content_store.rb +2 -2
  303. data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +6 -6
  304. data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +55 -52
  305. data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +3 -3
  306. data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +7 -7
  307. data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +11 -11
  308. data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +57 -51
  309. data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +1 -1
  310. data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +23 -22
  311. data/lib/phronomy/tool/authorization.rb +77 -0
  312. data/lib/phronomy/tool/base.rb +549 -9
  313. data/lib/phronomy/tool/call_request.rb +40 -0
  314. data/lib/phronomy/{agent/tool_execution/tool_definition_set.rb → tool/definition_set.rb} +7 -8
  315. data/lib/phronomy/tool/operation.rb +88 -0
  316. data/lib/phronomy/tool/schema.rb +214 -0
  317. data/lib/phronomy/tool/settings.rb +31 -0
  318. data/lib/phronomy/tool/tool_error.rb +7 -0
  319. data/lib/phronomy/tool/tool_executor.rb +58 -0
  320. data/lib/phronomy/tools/agent.rb +22 -90
  321. data/lib/phronomy/tools/mcp.rb +21 -14
  322. data/lib/phronomy/tools/vector_search.rb +4 -4
  323. data/lib/phronomy/tracing/automatic.rb +11 -6
  324. data/lib/phronomy/tracing/base.rb +1 -1
  325. data/lib/phronomy/tracing/observation.rb +37 -0
  326. data/lib/phronomy/tracing/settings.rb +36 -0
  327. data/lib/phronomy/vector_store/{async_backend.rb → async/async_client.rb} +35 -29
  328. data/lib/phronomy/vector_store/{in_memory.rb → backends/in_memory.rb} +12 -10
  329. data/lib/phronomy/vector_store/{pgvector.rb → backends/pgvector.rb} +44 -16
  330. data/lib/phronomy/vector_store/{redis_search.rb → backends/redis_search.rb} +74 -37
  331. data/lib/phronomy/vector_store/base.rb +118 -49
  332. data/lib/phronomy/vector_store/invalid_result_error.rb +12 -0
  333. data/lib/phronomy/vector_store.rb +2 -17
  334. data/lib/phronomy/version.rb +1 -1
  335. data/lib/phronomy/workflow/completion.rb +11 -0
  336. data/lib/phronomy/workflow/execution/workflow.rb +7 -7
  337. data/lib/phronomy/workflow/execution/workflow_action_rules.rb +67 -0
  338. data/lib/phronomy/workflow/execution/workflow_context.rb +2 -2
  339. data/lib/phronomy/workflow/execution/workflow_execution_environment.rb +27 -0
  340. data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +3 -5
  341. data/lib/phronomy/workflow/execution/workflow_runner.rb +58 -79
  342. data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -0
  343. data/lib/phronomy/workflow/persistence/state_repository.rb +28 -22
  344. data/lib/phronomy/workflow/persistence/storage_schema.rb +13 -0
  345. data/lib/phronomy/workflow/runtime_binding/workflow_engine_environment.rb +38 -0
  346. data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +156 -0
  347. data/lib/phronomy/workflow/{execution → runtime_binding}/workflow_terminal_policy.rb +4 -4
  348. data/lib/phronomy.rb +57 -16
  349. data/scripts/api_snapshot.rb +35 -15
  350. data/sig/_private/phronomy/agent/settings.rbs +19 -0
  351. data/sig/_private/phronomy/configuration/runtime_settings.rbs +20 -0
  352. data/sig/_private/phronomy/llm_adapter/async/async_client.rbs +10 -0
  353. data/sig/_private/phronomy/multi_agent/store.rbs +8 -0
  354. data/sig/_private/phronomy/persistence/storage_boundary.rbs +7 -0
  355. data/sig/_private/phronomy/tool/settings.rbs +13 -0
  356. data/sig/_private/phronomy/tracing/settings.rbs +15 -0
  357. data/sig/_private/phronomy/workflow/execution/workflow_settings.rbs +13 -0
  358. data/sig/phronomy/agent/admission.rbs +19 -0
  359. data/sig/phronomy/agent/execution_contract.rbs +132 -0
  360. data/sig/phronomy/agent/execution_environment.rbs +20 -0
  361. data/sig/phronomy/agent/store.rbs +73 -0
  362. data/sig/phronomy/agent.rbs +14 -138
  363. data/sig/phronomy/common.rbs +7 -0
  364. data/sig/phronomy/content_store/contracts.rbs +13 -0
  365. data/sig/phronomy/context.rbs +152 -0
  366. data/sig/phronomy/embeddings/async/async_client.rbs +9 -0
  367. data/sig/phronomy/embeddings/base.rbs +17 -0
  368. data/sig/phronomy/engine/concurrency/timer_bindings.rbs +22 -0
  369. data/sig/phronomy/engine/control_bindings.rbs +11 -0
  370. data/sig/phronomy/engine/control_protocols.rbs +23 -0
  371. data/sig/phronomy/engine/execution_binding.rbs +6 -0
  372. data/sig/phronomy/engine/execution_receiver.rbs +15 -0
  373. data/sig/phronomy/engine/observability.rbs +13 -0
  374. data/sig/phronomy/execution/async_operation.rbs +7 -0
  375. data/sig/phronomy/execution/blocking.rbs +5 -0
  376. data/sig/phronomy/execution/concurrency/cancellation_token.rbs +13 -0
  377. data/sig/phronomy/execution/concurrency/deadline.rbs +10 -0
  378. data/sig/phronomy/execution/concurrency/result_composition.rbs +7 -0
  379. data/sig/phronomy/execution/control_protocols.rbs +18 -0
  380. data/sig/phronomy/execution/errors.rbs +7 -0
  381. data/sig/phronomy/execution/execution.rbs +41 -0
  382. data/sig/phronomy/execution/execution_receiver.rbs +40 -0
  383. data/sig/phronomy/execution/execution_scope_state.rbs +9 -0
  384. data/sig/phronomy/execution/invocation_context.rbs +18 -0
  385. data/sig/phronomy/execution/invocation_controls.rbs +13 -0
  386. data/sig/phronomy/execution/task_result.rbs +29 -0
  387. data/sig/phronomy/extensions.rbs +0 -21
  388. data/sig/phronomy/handoff.rbs +10 -4
  389. data/sig/phronomy/llm_adapter/backends/ruby_llm.rbs +6 -0
  390. data/sig/phronomy/llm_adapter/base.rbs +14 -0
  391. data/sig/phronomy/llm_adapter/usage.rbs +14 -0
  392. data/sig/phronomy/llm_adapter/values.rbs +43 -0
  393. data/sig/phronomy/llm_context_window.rbs +10 -0
  394. data/sig/phronomy/multi_agent/reserved_child_admission.rbs +8 -0
  395. data/sig/phronomy/multi_agent/store.rbs +54 -0
  396. data/sig/phronomy/multi_agent.rbs +6 -3
  397. data/sig/phronomy/persistence/errors.rbs +18 -0
  398. data/sig/phronomy/persistence/migration.rbs +13 -0
  399. data/sig/phronomy/persistence/transaction.rbs +19 -0
  400. data/sig/phronomy/persistence.rbs +1 -99
  401. data/sig/phronomy/persistence_composition.rbs +19 -0
  402. data/sig/phronomy/runtime_composition/configuration.rbs +36 -0
  403. data/sig/phronomy/storage/async/async_client.rbs +8 -0
  404. data/sig/phronomy/storage/backends/in_memory.rbs +9 -0
  405. data/sig/phronomy/{storage.rbs → storage/contracts.rbs} +2 -16
  406. data/sig/phronomy/tool.rbs +48 -4
  407. data/sig/phronomy/tracing/observation.rbs +7 -0
  408. data/sig/phronomy/vector_store/async/async_client.rbs +13 -0
  409. data/sig/phronomy/vector_store/base.rbs +23 -0
  410. data/sig/phronomy/workflow/execution/workflow_execution_environment.rbs +14 -0
  411. data/sig/phronomy/workflow/runtime_binding/workflow_terminal_policy.rbs +7 -0
  412. data/sig/phronomy/workflow/store.rbs +8 -0
  413. data/sig/phronomy/workflow.rbs +1 -1
  414. data/sig/phronomy.rbs +0 -49
  415. metadata +318 -117
  416. data/lib/phronomy/agent/concerns/before_llm_input.rb +0 -66
  417. data/lib/phronomy/agent/concerns/error_translation.rb +0 -45
  418. data/lib/phronomy/agent/concerns/filterable.rb +0 -184
  419. data/lib/phronomy/agent/context/capability/base.rb +0 -548
  420. data/lib/phronomy/agent/context/capability/tool_executor.rb +0 -62
  421. data/lib/phronomy/agent/context/instruction/prompt_template.rb +0 -102
  422. data/lib/phronomy/agent/context_assembly/runtime_chat_builder.rb +0 -36
  423. data/lib/phronomy/agent/context_assembly/token_budget_resolver.rb +0 -22
  424. data/lib/phronomy/agent/context_parts/validators/final_budget_validator.rb +0 -37
  425. data/lib/phronomy/agent/context_policies/default.rb +0 -142
  426. data/lib/phronomy/agent/execution/phase_machine_builder.rb +0 -101
  427. data/lib/phronomy/agent/execution/provider_call_outcome.rb +0 -106
  428. data/lib/phronomy/agent/handoff/handoff_execution_coordinator.rb +0 -15
  429. data/lib/phronomy/agent/handoff/handoff_outcome_committer.rb +0 -131
  430. data/lib/phronomy/agent/handoff/handoff_request.rb +0 -45
  431. data/lib/phronomy/agent/lifecycle_contract/handoff_error.rb +0 -7
  432. data/lib/phronomy/agent/persistence/handoff_state_repository.rb +0 -58
  433. data/lib/phronomy/agent/persistence/queries.rb +0 -61
  434. data/lib/phronomy/agent/selection/candidate.rb +0 -53
  435. data/lib/phronomy/agent/selection/constraint.rb +0 -49
  436. data/lib/phronomy/agent/tool_execution/tool_call_intercepted.rb +0 -29
  437. data/lib/phronomy/agent/tool_execution/tool_invocation_session_builder.rb +0 -276
  438. data/lib/phronomy/configuration/configuration.rb +0 -68
  439. data/lib/phronomy/configuration/global_configuration.rb +0 -26
  440. data/lib/phronomy/engine/concurrency/cancellation_scope.rb +0 -124
  441. data/lib/phronomy/engine/concurrency/operation_binding.rb +0 -43
  442. data/lib/phronomy/engine/execution_receiver.rb +0 -65
  443. data/lib/phronomy/engine/runnable.rb +0 -54
  444. data/lib/phronomy/llm_adapter/ruby_llm.rb +0 -47
  445. data/lib/phronomy/llm_contract/token_usage.rb +0 -85
  446. data/lib/phronomy/multi_agent/persistence/queries.rb +0 -30
  447. data/lib/phronomy/multi_agent/storage_contract/team_storage_schema.rb +0 -15
  448. data/lib/phronomy/output_parser/contract/parse_error.rb +0 -7
  449. data/lib/phronomy/persistence/api/persistence.rb +0 -140
  450. data/lib/phronomy/persistence_composition/repositories.rb +0 -77
  451. data/lib/phronomy/recovery/recovery.rb +0 -186
  452. data/lib/phronomy/tool/contract/tool_error.rb +0 -7
  453. data/lib/phronomy/vector_store/embeddings/base.rb +0 -44
  454. data/lib/phronomy/vector_store/embeddings/ruby_llm_embeddings.rb +0 -47
  455. data/lib/phronomy/workflow/phase_machine_builder.rb +0 -205
  456. data/lib/phronomy/workflow/storage_contract/workflow_storage_schema.rb +0 -9
  457. data/sig/phronomy/execution_receiver.rbs +0 -34
  458. data/sig/phronomy/llm_adapter.rbs +0 -11
  459. data/sig/phronomy/runtime.rbs +0 -76
  460. /data/lib/phronomy/agent/{context_assembly/context_importer.rb → context_importer.rb} +0 -0
  461. /data/lib/phronomy/{engine → execution}/backpressure_error.rb +0 -0
  462. /data/lib/phronomy/{engine → execution}/cancellation_error.rb +0 -0
  463. /data/lib/phronomy/{engine → execution}/concurrency/worker_input_restricted.rb +0 -0
  464. /data/lib/phronomy/{engine → execution}/event_loop_reentrancy_error.rb +0 -0
  465. /data/lib/phronomy/{engine → execution}/execution_cancellation_error.rb +0 -0
  466. /data/lib/phronomy/{engine → execution}/execution_timeout_error.rb +0 -0
  467. /data/lib/phronomy/{engine → execution}/invalid_async_entry_action_error.rb +0 -0
  468. /data/lib/phronomy/{engine → execution}/invalid_async_transition_action_error.rb +0 -0
  469. /data/lib/phronomy/{engine → execution}/invalid_async_workflow_action_error.rb +0 -0
  470. /data/lib/phronomy/{engine → execution}/pool_shutdown_error.rb +0 -0
  471. /data/lib/phronomy/{engine → execution}/recursion_limit_error.rb +0 -0
  472. /data/lib/phronomy/{engine → execution}/runtime_shutdown_error.rb +0 -0
  473. /data/lib/phronomy/{engine → execution}/runtime_shutdown_reentrancy_error.rb +0 -0
  474. /data/lib/phronomy/{engine → execution}/scheduler_reentrancy_error.rb +0 -0
  475. /data/lib/phronomy/{engine → execution}/timeout_error.rb +0 -0
@@ -0,0 +1,71 @@
1
+ # r8 unit 11: C04 concrete Policy and LLM connection selection
2
+
3
+ Contract placement follows ownership of meaning and invariants, not reuse.
4
+ This unit addresses review findings B01 and B02: Agent::Base selected the
5
+ concrete DefaultPolicy, and InvocationActions constructed the concrete LLM
6
+ AsyncClient. Neither choice belongs to Agent progress decisions.
7
+
8
+ | Owner | Responsibility |
9
+ | --- | --- |
10
+ | Agent::Base / C04 | Declare, validate, inherit and use a ContextPolicy |
11
+ | ContextPolicy / C05 | Context-selection operation contract |
12
+ | DefaultPolicy implementation / I01 | Existing selection strategy and token-budget allocation |
13
+ | runtime_composition/agent_defaults.rb / A01 | Install DefaultPolicy through the existing Base.context_policy DSL |
14
+ | Agent InvocationActions / C04 | Prepare the LLM request, request a client through the owning environment, track completion and deliver progress |
15
+ | Agent ExecutionEnvironment | Private connection capability to build an LLM client for the supplied adapter |
16
+ | Agent EngineEnvironment / I07 | Select AsyncClient and bind submission to the captured Runtime |
17
+ | LLM AsyncClient / I06 | Run the complete C09 operation through C13 submission; forward stream chunks and cancellation |
18
+ | LLMAdapter / C09 | Synchronous complete/stream operations and request/response rules |
19
+
20
+ Ordinary require "phronomy" installs the existing DefaultPolicy instance.
21
+ Base no longer supplies a concrete fallback; an unconfigured root raises a
22
+ ConfigurationError. No supported loading path is left unconfigured. Class
23
+ inheritance and explicit Policy overrides retain their existing semantics.
24
+ Selecting the default does not create configuration, stores or a Runtime.
25
+ This does not change DefaultPolicy's algorithm or introduce a policy registry.
26
+
27
+ InvocationActions now asks its retained environment for the LLM client.
28
+ It still reads the configured adapter at dispatch time. The Engine binding
29
+ constructs AsyncClient with itself as the existing C13 submitter protocol;
30
+ AsyncClient does not depend on the Agent environment type. No generic factory
31
+ registry, new logical Contract or public application API is introduced.
32
+
33
+ The client forwards the original TaskResult rather than replacing it. Logical
34
+ cancellation and physical worker completion remain distinct. An explicit pool
35
+ still uses Execution's existing pool-selection protocol and overrides the
36
+ injected submitter. A standalone client with no injected submitter continues
37
+ to resolve the current default Runtime at each call. Client construction
38
+ starts no Runtime resources.
39
+
40
+ For Agent calls, submission now uses the Agent's captured Runtime, matching
41
+ its sessions and other work. Replacing the default Runtime cannot redirect
42
+ only its LLM worker to a different owner. A stopped owner rejects new work
43
+ through the existing RuntimeShutdownError. Provider errors, admission failure,
44
+ chunk ordering, cancellation and completion are not translated by this change.
45
+ Public Agent/Policy signatures, manifests, durable schemas and recovery rules
46
+ are unchanged. The private AsyncClient constructor adds an optional submitter;
47
+ its private RBS uses the existing _ExecutionSubmitter interface.
48
+
49
+ ## Evidence and remaining scope
50
+
51
+ Regression tests cover ordinary lazy loading, inherited/explicit Policies,
52
+ complete and streaming Agent calls after default Runtime replacement, live
53
+ adapter selection, provider worker ownership and EventLoop callback ownership.
54
+ Connection tests cover resource-free construction and stopped-owner rejection.
55
+ Async client tests cover the narrow submitter, explicit pool precedence and
56
+ physical completion after cancellation; existing failure/backpressure tests
57
+ remain acceptance gates.
58
+
59
+ Ruby AST guards reject DefaultPolicy and AsyncClient references in Agent domain
60
+ files. The Ruby/RBS graph gate separately rejects Agent domain dependencies on
61
+ llm_adapter/async and permits the binding connection. Existing lower-level
62
+ reverse-dependency rules remain intact. These checks have the same static
63
+ analysis limitations as the existing architecture tooling; they do not prove
64
+ that all logical Contract dependencies are acyclic or complete.
65
+
66
+ B01 and B02 are addressed in this candidate. C04 is not declared globally
67
+ complete. Remaining review includes C01 Orchestrator inheritance from the
68
+ concrete Agent tool, C02 Workflow execution connections and separately scoped
69
+ durable child behavior, and Recovery's domain/persistence responsibilities.
70
+ Existing domain-level explicit/configured/default store selection is not itself
71
+ a defect: concrete default persistence factories are already in composition.
@@ -0,0 +1,67 @@
1
+ # r8 unit 12: C01 subagent operations use the C06 Tool contract
2
+
3
+ Contract placement follows ownership of meaning and invariants, not reuse.
4
+ This unit addresses B03: Orchestrator.subagent generated a subclass of the
5
+ concrete Tools::Agent implementation (I04). The generated class replaced Agent
6
+ creation and child coordination, but inherited Tool operation rules incidentally.
7
+
8
+ | Owner | Responsibility |
9
+ | --- | --- |
10
+ | MultiAgent / C01 | Define the subagent operation, child class, knowledge/context inheritance, child error policy and durable reconciliation |
11
+ | Agent / C04 | Public child invocation and recovery outcomes |
12
+ | Tool / C06 | Input schema, Tool error policy, result limits and completion-handle requirements |
13
+ | Execution / C13 | Nonblocking completion composition and physical completion propagation |
14
+ | Tools::Agent / I04 | Standalone concrete Agent Tool construction through from_agent |
15
+
16
+ Orchestrator remains an Agent::Base subclass: a coordinating Agent is a valid
17
+ C01-to-C04 relationship. Its generated subagent Tool now derives directly from
18
+ Tool::Base and explicitly declares cooperative execution and its input schema.
19
+ Generating this domain-owned operation belongs to C01; no runtime registry,
20
+ factory, new logical Contract or composition layer is needed for that operation.
21
+
22
+ Tool::Base has a private call_async_operation helper that validates inputs,
23
+ requires a completion handle, applies Tool error policy and limits successful
24
+ results. Its block supplies the domain operation. It does not create Agents,
25
+ select implementations, wait for completion or decide how many application
26
+ filters to run. Both the subagent operation and Tools::Agent use this helper.
27
+ The default Tool::Base#call_async path and synchronous-call delegation are
28
+ unchanged, including the unit 9 result-transformation behavior.
29
+
30
+ ExecutionRehydrationRequiredError remains an Agent-domain outcome. Tools::Agent
31
+ and the C01 operation retain their private pass-through hooks; C06 does not
32
+ reference this error or interpret recovery. Generic errors retain their original
33
+ backtrace when wrapped; ToolError and CancellationError remain unchanged.
34
+ Suppression logging uses C06's existing RuntimeSettings logger capability.
35
+
36
+ An ordinary asynchronous subagent call still checks cancellation before schema
37
+ validation, starts the child without occupying a waiting offload worker, maps
38
+ its output and applies Tool policy. The subagent on_error option continues to
39
+ control child failure (raise or skip); it is distinct from Tool on_error policy.
40
+
41
+ An admitted durable child follows the existing reconciliation path directly.
42
+ It is reconciled even with a cancelled parent token; unknown outcomes and
43
+ recovery requirements are not hidden. This path retains its existing validation,
44
+ result and cancellation behavior, without adding the ordinary-call truncation
45
+ or error-suppression pipeline. Agent-owned configured result transformations
46
+ still wrap either path in the configured order, including repeated filters.
47
+ Parent/child IDs, reservations, stores, persistence schemas and recovery rules
48
+ are unchanged. Logical settlement does not falsely imply physical completion.
49
+
50
+ ## Evidence and remaining scope
51
+
52
+ Non-Agent Tool tests cover asynchronous validation/coercion, errors, result
53
+ limits, cancellation and separate physical completion. Subagent tests cover
54
+ operation without Tools::Agent, ordinary and admitted-child cancellation,
55
+ recovery error identity and repeated transformations after truncation. Existing
56
+ pool-starvation, knowledge inheritance, durable coordination/restart and result
57
+ transformation tests remain acceptance gates.
58
+
59
+ The AST gate rejects concrete Tools references in C01 domain files and
60
+ Agent recovery interpretation in C06. The Ruby/RBS graph gate rejects C01
61
+ domain-to-tools implementation dependencies. Existing lower-level and Engine
62
+ binding rules remain intact. These are targeted regression checks, not proof
63
+ of all logical Contract dependencies or global acyclicity.
64
+
65
+ B03 is addressed in this candidate. C02 Workflow execution connections, its
66
+ separately scoped durable child guarantees, and broader Recovery responsibility
67
+ review remain. No completed status is asserted for all of C01/C02/C04.
@@ -0,0 +1,61 @@
1
+ # r8 unit 13: C02 Workflow rules and Engine connections
2
+
3
+ Contract placement follows ownership of meaning and invariants, not reuse.
4
+ This unit addresses B04: WorkflowRunner and its registry previously selected
5
+ Runtime, built FSMSession instances and constructed Engine event envelopes.
6
+ The phase compiler also contained Workflow callback rules alongside the
7
+ state_machines translation.
8
+
9
+ | Owner | Responsibility |
10
+ | --- | --- |
11
+ | Workflow / C02 | Topology, callback rules, segment admission, identity/owner checks, hydration, snapshots, persistence outcome classification and recovery-required retention |
12
+ | Workflow runtime binding | Compile topology into state_machines, build/register sessions, select the owning Runtime and translate classified outcomes into terminal decisions |
13
+ | Execution / C13 | Completion handles and receiver lifecycle/routing protocol |
14
+ | Engine | Serial dispatch, atomic delivery, generic FSM execution and terminal gate |
15
+ | Application | State actions, guards, external event correlation and child operation choices |
16
+
17
+ WorkflowActionRules owns synchronous entry, transition and exit callback
18
+ constraints, optional event arguments and adoption of returned WorkflowContext
19
+ values. The compiler installs these rules as machine callbacks. Initial entry
20
+ callbacks also pass through the rules before reaching the generic FSM session.
21
+ Application callback order remains exit, transition action, entry.
22
+
23
+ WorkflowExecutionEnvironment is a private C02 connection port. Composition
24
+ installs its provider; WorkflowEngineEnvironment implements it. Compiling a
25
+ Workflow captures its environment without starting an EventLoop, workers or
26
+ execution registration. Starts, durable loads, live signals, terminal saves,
27
+ completion and admission release use that same owner. Changing the default
28
+ Runtime does not silently move a compiled Workflow or its continuations to a
29
+ different owner. Recompile the Workflow after replacing/stopping that Runtime.
30
+ Scalar per-call configuration and configured repository resolution retain their
31
+ existing behavior. Tracing keeps its independent existing execution composition.
32
+
33
+ WorkflowExecutionRegistry remains in C02. workflow_instance_id, opaque owner
34
+ token and fsm_session_id remain distinct. Routing resolves the current target
35
+ under the existing lifecycle lock; ExecutionReceiverBinding constructs the
36
+ Engine event within the same atomic delivery operation. No new registry or
37
+ public extension API is introduced.
38
+
39
+ Runner continues to classify terminal persistence results as success, known
40
+ failure or outcome unknown. The binding only translates these outcomes into
41
+ complete, fail or retire instructions. A successful terminal notification still
42
+ requires confirmed persistence. An uncertain outcome still retires the session
43
+ while retaining recovery-required admission; it does not announce success or
44
+ release another owner's segment. Readback/reconciliation does not retry a save.
45
+ Admission is acquired before durable load, and rejected competitors do not load.
46
+
47
+ ## Evidence and remaining scope
48
+
49
+ Existing tests cover competing admission, immutable terminal snapshots, lost
50
+ responses, unknown outcomes, shutdown, wait/resume, live event routing and action
51
+ ordering. New tests cover standalone callback rules, resource-free compilation,
52
+ owner retention across blocked load/save and default replacement, and rejection
53
+ on a stopped owner. Ruby AST and Ruby/RBS graph checks reject C02-to-Engine or
54
+ C02-to-binding dependencies while preserving lower-layer restrictions.
55
+
56
+ The targeted C02 execution connection boundary is addressed. This is not proof
57
+ that every logical Contract is complete or that the whole source graph is
58
+ acyclic. F01 durable Workflow children still need an explicit specification for
59
+ identity, reservation, completion persistence and recovery; application actions
60
+ may still launch ordinary asynchronous work. Broader Recovery ownership review
61
+ also remains. No durable child protocol or persistence schema is added here.
@@ -0,0 +1,72 @@
1
+ # r8 unit 14: assign existing recovery rules to their owners
2
+
3
+ The former private `Phronomy::Recovery` combined Agent operation subjects and
4
+ factual resolutions with general persistence evidence comparison. Sharing a
5
+ file or using the word recovery does not make these one Contract.
6
+
7
+ | Responsibility | Owner after this change |
8
+ | --- | --- |
9
+ | LLM/Tool subject identity, resolution material, resumability classification | C04 Agent, private `Agent::RecoveryRules` |
10
+ | Revision/snapshot evidence comparison and normalization | C07 Persistence, private `Persistence::SnapshotComparison` |
11
+ | Selection of Workflow evidence and interpretation of pre/post/conflict | C02 Workflow, existing WorkflowRunner |
12
+ | Agent restoration, resolution save/readback and continuation | C04 Agent, existing RecoveryCoordinator |
13
+ | Parent/child coordination and durable reconciliation | C01 MultiAgent, unchanged |
14
+
15
+ There is no independent Recovery Contract. C14 remains retired; C17 is
16
+ OutputParser. M50/G34 are retired in the current source architecture without
17
+ reusing their identifiers. Historical phase configurations retain their history.
18
+
19
+ ## Behavioral scope
20
+
21
+ This is a relocation of existing rules and their call sites. No public API,
22
+ persisted schema, outcome value, retry, observer, admission or ownership rule is
23
+ added. Error classes/messages and validation ordering are retained. Ordinary
24
+ framework boot still loads the relocated definitions. The former private
25
+ namespace and file are removed, without a compatibility alias. The existing
26
+ public `Phronomy::ExecutionRehydrationRequiredError` moves to `agent/api` while
27
+ retaining its root namespace, superclass and lazy-loading behavior; it remains
28
+ an Agent-domain outcome, also consumed by delegation callers.
29
+
30
+ `Agent::RecoveryRules` describes external operation facts as `succeeded`,
31
+ `failed` or `not_performed`. Its `Classification` describes resumability. The
32
+ existing structural `persistence_operation` subject normalization is retained
33
+ to avoid changing accepted input or errors; it does not provide a new generic
34
+ durable operation identity or a new supported Agent resolution operation.
35
+
36
+ `Persistence::SnapshotComparison` returns `pre_state`, `post_state` or
37
+ `conflict`. It performs no I/O. Workflow supplies authoritative readback and
38
+ intended evidence, handles read errors, and decides completion, known failure
39
+ or recovery-waiting admission retention. In particular:
40
+
41
+ - An absent record with an absent expected pre revision remains pre-state.
42
+ - Without an explicit post revision, a matching normalized snapshot and a
43
+ revision different from the expected pre revision identifies post-state.
44
+ - With an explicit post revision, both revision and snapshot must match.
45
+ - Otherwise a matching pre revision identifies pre-state, even if the snapshot
46
+ differs. The explicit post comparison still precedes this check.
47
+ - Accessors precede symbol keys, which precede string keys. Nested hash keys
48
+ and symbol values normalize to strings. Read/accessor errors propagate to
49
+ the owning domain as before.
50
+
51
+ `Persistence::SaveOutcome` is unchanged. It compares domain-supplied before/after
52
+ evidence using its existing equality and reports `committed`, `not_committed`
53
+ or `unknown`. It is not substituted for snapshot comparison: their predicates
54
+ and error handling differ. Agent-specific execution metadata comparisons also
55
+ remain in Agent.
56
+
57
+ ## Verification and limits
58
+
59
+ The relocated specs retain existing cases. Additional regressions fix comparison
60
+ priority, normalization, accessor precedence, error identity, resolution error
61
+ ordering and subject immutability. The same 45 primitive examples pass against
62
+ the unit13 definitions and the relocated definitions. Existing Agent recovery
63
+ and Workflow terminal persistence tests cover their surrounding behavior.
64
+
65
+ AST and combined Ruby/RBS graph gates reject dependencies from other domains on
66
+ Agent recovery rules and domain references in generic persistence comparison.
67
+ These checks guard this boundary, not all possible semantic coupling. Root
68
+ loader wiring and dynamic injection require separate review and runtime tests.
69
+
70
+ Durable Workflow children (F01) remain deferred feature work, outside this
71
+ responsibility refactor and outside its acceptance criteria. This change does
72
+ not establish global acyclicity or completion of every Contract.
@@ -0,0 +1,65 @@
1
+ # r8 unit15: Generation contract boundaries
2
+
3
+ This responsibility refactor is based on applied unit14, commit
4
+ `97c3d76b35594bb971a60a2932410ddf22e48d3a` (tree
5
+ `c326196212a4ac369294a9ccb936619813e51250`).
6
+
7
+ ## B05: Agent operation connection
8
+
9
+ Generation previously used `send(:__invoke_async_with_event_sink, ...)` to
10
+ select Agent's private per-execution listener. It now constructs each Agent
11
+ once with its public `on_event:` option and calls public `invoke_async`.
12
+
13
+ The private Generation `AgentOperation` owns the connection, not Agent execution:
14
+
15
+ - Each returned TaskResult supplies that call's terminal result or original
16
+ failure. Terminal incarnation notifications are not interpreted a second time.
17
+ - Approval remains a listener notification while the Agent TaskResult is pending.
18
+ Generation retains its existing policy: approval suspension fails the pipeline.
19
+ - Pending submissions retain their Generation listeners in Workflow entry order.
20
+ Agent continues to own admission. A rejected overlapping call cannot replace
21
+ another call's approval listener; a queued call may be admitted after the prior
22
+ result settles. Only the corresponding settled or synchronously failed request
23
+ is removed. Result callbacks are thread-safe and never wait on the EventLoop.
24
+ - Agent instances and their conversations are reused across iterations and
25
+ pipeline invocations. No per-call Agent creation, automatic cancellation,
26
+ retry policy, durable child tracking, or new runtime registry is introduced.
27
+ - The unused private Agent event-sink method is removed. Per-invocation public
28
+ `on_event:` arguments remain unsupported.
29
+
30
+ `AgentResultReceiver` and `PipelineState` retain event interpretation, parsing,
31
+ request correlation, stale-result rejection, review feedback and trust decisions.
32
+ Their rule bodies are unchanged. `WorkflowBuilder` retains state definitions and
33
+ entry order. Its private operation port is not a new public Agent API.
34
+
35
+ The connection relies on existing public Agent guarantees: one admitted
36
+ execution per Agent, ordered incarnation notifications, and TaskResult settlement
37
+ for terminal results. Approval does not settle the TaskResult. Handoff remains
38
+ outside GeneratorVerifier completion semantics, as before.
39
+
40
+ ## B06: Default parser composition
41
+
42
+ `runtime_composition/generation_defaults.rb` selects the existing JsonParser
43
+ through a private one-time factory binding. Generation lazily creates and reuses
44
+ one default parser per pipeline only when default parsing is needed. Boot creates
45
+ no parser, Agent, Persistence or Runtime for this binding.
46
+
47
+ Generation owns `default_parse_draft` and `default_parse_review`, including the
48
+ existing ParseError fallback payloads. Existing custom parser callables take
49
+ precedence. No application configuration changes are required. OutputParser's
50
+ contract and its concrete implementations are unchanged.
51
+
52
+ ## Scope and verification
53
+
54
+ AST regression gates reject concrete parser selection and the removed private
55
+ Agent invocation in Generation. Public-only Agent doubles cover inline completion,
56
+ busy failure, queued admission, stale terminal notifications, timeout, cancellation
57
+ and approval while pending. Real Agent integration covers approval in both phases
58
+ and retained conversations. Domain event-rule tests use the private Generation
59
+ operation port; they no longer pretend a private Agent method is the public API.
60
+
61
+ Public signatures, result shape, stored schemas, generation/review decisions,
62
+ parser fallback values and default iteration limits are preserved. The internal
63
+ result-observation plumbing changes; this is not merely a physical file move.
64
+ F01 durable Workflow children remain deferred feature work. This checkpoint does
65
+ not certify all framework dependencies or all concrete Engine responsibilities.
@@ -0,0 +1,54 @@
1
+ # r8 unit16: Explicit cancellation subscription ownership
2
+
3
+ This responsibility refactor is based on applied unit15, commit
4
+ `9aebef9217383cebb7fa3ec8b2d17b5763cd3c5e` (tree
5
+ `fcc1bd3bc72ed611a7d4e9090dcf2391b6bc7471`). It addresses B07 only.
6
+
7
+ ## C13 owns registration lifetime
8
+
9
+ `Concurrency::ResultSubscriptions#explicit_cancellation` registers the existing
10
+ CancellationToken notification and owns its disposal through `close`. This is
11
+ an internal Execution operation, reusing the existing subscription collection;
12
+ it is not a new public registry or a new Tool implementation.
13
+
14
+ The existing `cancellation` operation delegates its registration bookkeeping to
15
+ this method and retains its additional `cancelled?` check. Its `Subscriptions`
16
+ subclass retains deadline scheduling. An explicit registration alone neither
17
+ checks an elapsed deadline nor schedules a timer.
18
+
19
+ CancellationToken still owns callback storage, delivery, exception isolation,
20
+ and private removal. `on_cancel` still returns the token. Public signatures,
21
+ exception types, and the callback behavior are unchanged. In particular, closing
22
+ a registration does not retract a callback already taken by concurrent `cancel!`.
23
+
24
+ ## Consumers retain their execution decisions
25
+
26
+ - C01 TeamCoordinator registers its existing cancellation callback through C13
27
+ and closes the collection in the existing `ensure` block. Team still owns the
28
+ durable cancel request, child cancellation, and terminal outcome interpretation.
29
+ - I09 OffloadPool registers its existing operation cancellation callback through
30
+ the same operation. It still owns queue/worker admission, logical settlement,
31
+ deadline promotion, abandonment, and physical completion. Timer registrations
32
+ are closed before cancellation registrations, preserving cleanup order.
33
+ - C06 Tool already passes its token to the standard offloaded submitter. Its
34
+ operation dispatch and cooperative/custom-async paths are unchanged. No
35
+ Tool-specific subscription or symmetric copy of Team logic is introduced.
36
+
37
+ An already-cancelled token may deliver during registration and close the
38
+ subscription collection before registration returns. The existing collection's
39
+ `add` behavior disposes such a late-added registration immediately. The same
40
+ mechanism covers a concurrent `close` during registration.
41
+
42
+ ## Verification and remaining scope
43
+
44
+ Behavioral checks cover explicit cancellation, expired deadlines without explicit
45
+ cancellation, inline and concurrent close, delivery already in flight, callback
46
+ failure isolation, and Team/worker cleanup after success and failure. Existing
47
+ OffloadPool timeout, cancellation, and physical-completion tests remain applicable.
48
+ The AST gate rejects private token-removal calls outside Execution, including
49
+ literal reflective calls in Engine and domain code.
50
+
51
+ B08 configuration access and F01 durable Workflow children are not implemented
52
+ here. Public API/RBS, storage schemas, default configuration, and domain rules
53
+ are retained. This change does not certify all Contract boundaries or eliminate
54
+ the aggregate implementation graph's cycles.
@@ -0,0 +1,73 @@
1
+ # r8 unit17: Domain settings consumption
2
+
3
+ This responsibility-only refactor is based on applied unit16, commit
4
+ `fb551e1a1a8334b2547ecad126dd9c152c1b0f8c` (tree
5
+ `1ddb3b0e3f4eb97c1738ad02f9035eeefa180c90`). It addresses B08.
6
+
7
+ ## Values and composition have different owners
8
+
9
+ Agent::Settings owns Agent option values and the existing stream callback error
10
+ policy validation. WorkflowSettings owns the Workflow progress limit and optional
11
+ state repository. They contain actual domain values, never the application
12
+ Configuration object. Their readers do not select a concrete adapter or backend.
13
+ Configuration remains the application-facing facade and composes these values;
14
+ its existing readers, writers, default values and zero-argument constructor remain.
15
+ The application composition boundary supplies the defaults and lazy providers.
16
+
17
+ The existing MultiAgent::Store receives a provider for the optional configured
18
+ store. It does not construct a fallback. Team still falls back to its fresh-store
19
+ factory; Orchestrator still permits no coordination store unless durable children
20
+ require one. Explicit stores and execution participants keep their priority.
21
+ A single store reader does not require a separate MultiAgent settings class.
22
+
23
+ Logger reads use the existing neutral RuntimeSettings. Agent authorization pool
24
+ size and queue capacity belong to the execution connection, which reads them
25
+ when submitting authorization work to the owning Runtime. Agent retains timeout
26
+ selection, approval evaluation, result interpretation, and operation supervision.
27
+ The private ExecutionEnvironment#submit_authorization operation separates those
28
+ resource choices from ToolInvocation. Generic Tool submission is unchanged.
29
+
30
+ ## Preserve read timing without notifications
31
+
32
+ Each existing read remains at its previous execution boundary. Providers are
33
+ bound without evaluating Configuration or starting Runtime resources. A read
34
+ resolves the current domain values; it does not subscribe, poll, cache, or push
35
+ changes. There is no observer, change event, background task, version counter,
36
+ refresh loop, or new in-flight reconfiguration guarantee.
37
+
38
+ The existing read positions and short-circuit rules remain significant:
39
+
40
+ - Agent class model fallback is read when model is requested. Explicit class
41
+ models keep precedence. Already-created Agent stores are not replaced.
42
+ - Hooks and LLM adapter operations are read at the existing input preparation,
43
+ identity check, and call sites. Hook order and validation remain Agent rules.
44
+ - Workflow limits are read when starting or resuming execution. An admitted
45
+ execution retains its limit; a changed global default does not update it.
46
+ - Explicit nil, per-invocation overrides, configured stores, and fresh fallback
47
+ stores retain their existing meanings. No new defaults are created on reads.
48
+ - Configuration copies duplicate the domain value containers while retaining
49
+ injected component identities, preserving nested scoped overrides and reset.
50
+
51
+ The new domain value types are internal, grouped by responsibility rather than
52
+ one class per setting. Public Configuration continues to offer the same settings;
53
+ applications do not need to inject every value manually. Its private instance
54
+ variables and internal containers are not an application extension API.
55
+
56
+ ## Verification and limits
57
+
58
+ Regression checks cover lazy boot and direct Configuration loading, nested scope
59
+ restoration after failure, reset, component identities, nil, class and invocation
60
+ overrides, hook read timing/order, Workflow admission-time limits, persistent
61
+ Agent stores, and the distinct Team/Orchestrator fallback behavior. Execution
62
+ connection tests verify authorization resource options and owning Runtime.
63
+ Existing failure-policy/logging tests configure values through public writers
64
+ instead of mocking the old composition getter. RBS records the new internal
65
+ boundaries without erasing domain operation types.
66
+
67
+ AST gates reject application Configuration references from Agent, Workflow, and
68
+ MultiAgent domain code, including literal reflective access. They also reject
69
+ pool sizing in domain code. These are targeted regression checks, not a proof of
70
+ all dynamic dependencies or a whole-framework completion claim.
71
+
72
+ B07 remains applied. F01 durable Workflow children and other feature work are
73
+ outside this change. There are no storage schema or public operation changes.
@@ -0,0 +1,92 @@
1
+ # R8 unit18: durable cancellation receipt
2
+
3
+ ## Problem
4
+
5
+ An Orchestrator load can return while recovery of a framework-owned child is still
6
+ in flight. If the child needs external factual resolution, Agent captures an
7
+ immutable terminal command that will retain the active parent in coordination
8
+ wait. A cancelled token supplied to `resume` after command capture previously
9
+ cancelled only the live invocation. The earlier command could then persist a
10
+ false cancellation snapshot and release the owner. Restart lost the request.
11
+
12
+ Controlled scheduling reproduced this in both unit16 and unit17, three times out
13
+ of three. The original example passed 200 natural repetitions. Without the
14
+ applicant's original failure log, equivalence to that initial failure is not
15
+ established. The controlled race is independently demonstrated.
16
+
17
+ ## Ownership
18
+
19
+ Agent owns receipt of cancellation for an exact execution, its existing durable
20
+ cancellation ledger, and persistence of the parent execution. MultiAgent still
21
+ owns the unresolved-child and pending-parent rules. Execution owns notification
22
+ registration and delivery; Engine owns runtime connections. No Agent decision is
23
+ moved into those mechanisms or into neutral Persistence/Storage.
24
+
25
+ `ExactExecution` validates identity, reservation, input and participant binding
26
+ before recording a supplied cancellation through `Store#request_cancellation`.
27
+ The write runs in its existing off-EventLoop preparation, before recovery or
28
+ waiting. If cancellation first becomes visible during EventLoop delivery,
29
+ preparation runs again before the live owner is signalled. Recording errors fail
30
+ the observer and do not proceed to recovery or notification.
31
+
32
+ `ExecutionChange#prepare_in` already reads the monotonic cancellation ledger
33
+ inside the participant transaction. `ExecutionOutcomeCommitter` now uses that
34
+ prepared fact for a pending execution's cancellation metadata. The worker's
35
+ captured command remains immutable; it does not query a live invocation or token.
36
+
37
+ ## Ordering and preserved semantics
38
+
39
+ - Before outcome commit: the transaction sees the accepted ledger entry and saves
40
+ cancellation in both Agent pending metadata and MultiAgent extension state.
41
+ - After outcome commit: the ledger retains newly accepted intent without changing
42
+ execution revision or invalidating the in-flight result. The previously saved
43
+ metadata/extension remain a snapshot; the next recovery/change incorporates the
44
+ ledger. Immediate equality between those snapshots and the ledger is not an API
45
+ guarantee. The ledger is the durable source of accepted cancellation intent.
46
+ - After owner release: receipt records intent before recovery installation.
47
+ - An absent execution is not assigned a cancellation record. A terminal result,
48
+ including one that wins against cancellation receipt, remains unchanged.
49
+ - Unknown child external outcomes still require factual resolution. No LLM replay,
50
+ forced child completion or new recovery capability is introduced.
51
+
52
+ There is no schema change, public API change, new Contract, Registry, subscription
53
+ or polling mechanism. This fixes receipt of cancellation observed by the existing
54
+ exact-execution path; it does not introduce continuous subscription to an incoming
55
+ token after observer registration.
56
+
57
+ ## Verification design
58
+
59
+ Queue gates hold the outcome worker before commit and after commit/before result
60
+ publication. Gates never block EventLoop or hold a storage transaction. Tests
61
+ assert ledger persistence, unchanged revision during receipt, pending snapshots,
62
+ restart preservation, unknown-child activity and zero LLM replay. Additional
63
+ component tests cover validation rejection, write failure, recovery ordering,
64
+ late token observation and terminal-result preservation. The pending commit test
65
+ also covers committed-response loss.
66
+
67
+ The original checkpoint fixture now performs phase inspection and snapshot copy
68
+ under one backend lock, preventing concurrent after-commit hooks from replacing a
69
+ selected checkpoint. Its initial assertion uses the durable ledger because a
70
+ request arriving after a saved waiting snapshot need not rewrite that snapshot.
71
+ Separate deterministic tests assert the snapshot on each side of the commit.
72
+
73
+ ## Unit18 delivery correction
74
+
75
+ The first unit18 version checked the incoming token twice inside delivery: once
76
+ to decide whether to record, and again to decide whether to signal. Cancellation
77
+ between those observations could skip recording but still signal the owner.
78
+ A suspended approval execution then exited without a completion reconciliation,
79
+ leaving the durable ledger empty.
80
+
81
+ Delivery now uses one cancellation observation for both decisions. After finding
82
+ and validating the current owner, an observed cancellation returns to off-loop
83
+ preparation if unrecorded, or signals the owner if already recorded. The separate
84
+ preparation and delivery observations remain intentional: scheduling between those
85
+ stages can change the token. A notification is never authorized by a different
86
+ observation from the one used to enforce its recording prerequisite.
87
+
88
+ Regression tests use the real suspended owner, registry and EventLoop. They
89
+ cancel the incoming token just before delivery or during the owner lookup, and
90
+ cover both successful recording and recording failure. They assert recording
91
+ before notification, no notification on write failure, off-loop persistence and
92
+ unchanged suspended execution contents. No polling or new subscription is added.
@@ -0,0 +1,61 @@
1
+ # R8 unit19: Engine resource lifetime
2
+
3
+ ## Confirmed failures
4
+
5
+ Overlapping first default-pool lookups could construct two pools and retain only
6
+ one. A pool lookup that passed Runtime's state check could also create a pool
7
+ after shutdown had captured its resource list. Both cases left live workers
8
+ outside the claimed completed cleanup.
9
+
10
+ OffloadPool previously returned after each worker join timeout without reporting
11
+ whether workers remained. Runtime interpreted the absence of an exception as
12
+ successful cleanup. A real blocked worker was still active after the default
13
+ 30-second join while Runtime reported terminated, clean and complete.
14
+
15
+ ## Ownership
16
+
17
+ PoolRegistry owns pool creation, registration and closure of that registration.
18
+ The same mutex protects default and named pool construction and the transition
19
+ to a closed registry. Runtime still admits resources during its draining phase
20
+ for previously accepted continuations. PoolRegistry rejects requests after the
21
+ shutdown resource set is captured, including lookups that passed an earlier
22
+ Runtime check.
23
+
24
+ OffloadPool owns worker admission and physical worker lifetime. begin_shutdown
25
+ closes admission without waiting and preserves queue draining. shutdown waits
26
+ using one monotonic deadline; its existing self return is preserved. terminated?
27
+ reports that admission is closed and every owned worker has actually exited.
28
+ TaskResult cancellation or timeout is not proof of physical worker termination.
29
+
30
+ PoolRegistry first closes all pools, then waits outside its registration lock.
31
+ Every pool uses the same absolute deadline. Cleanup continues for the remaining
32
+ pools after an individual error; the first error is propagated after those
33
+ attempts. Runtime still attempts timer cleanup in ensure.
34
+
35
+ Runtime owns the aggregate decision. Its existing stop-phase deadline is shared
36
+ by EventLoop and pool joins. Cleanup is incomplete while any worker remains;
37
+ domain finalization and default-Runtime replacement remain blocked. Runtime's
38
+ existing cached-result behavior is unchanged: an incomplete result is not later
39
+ promoted to complete by calling shutdown again.
40
+
41
+ ## Scope
42
+
43
+ This is an Engine lifecycle correctness fix, not only a file relocation. Pool
44
+ shutdown no longer silently reports completed resource cleanup when workers
45
+ remain. The pool waiting budget is shared instead of being restarted per worker
46
+ or per pool. No worker is forcibly interrupted, and queued accepted work still
47
+ drains. Applications retain responsibility for bounded synchronous operations
48
+ and native I/O timeouts.
49
+
50
+ Agent cancellation persistence, MultiAgent parent/child policy, Workflow
51
+ persistence decisions, C13 result/subscription contracts, settings providers and
52
+ durable formats are unchanged. No new domain Contract or notification mechanism
53
+ is introduced. E03 passive metrics collection remains a separate follow-up.
54
+
55
+ ## Verification
56
+
57
+ Queue-controlled tests reproduce overlapping first pool creation and lookups
58
+ delayed until after shutdown. Real worker gates verify bounded shutdown,
59
+ incomplete results, retained Runtime, withheld finalization and the difference
60
+ between logical cancellation and physical completion. Additional cases preserve
61
+ draining continuations and ensure all resources receive cleanup attempts.