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.
- checksums.yaml +4 -4
- data/.mutant.yml +9 -9
- data/CHANGELOG.md +92 -0
- data/CONTRIBUTING.md +8 -8
- data/README.md +13 -3
- data/VERIFY.sh +27 -27
- data/benchmark/bench_agent_invoke.rb +26 -47
- data/benchmark/bench_context_assembler.rb +17 -15
- data/benchmark/bench_regression.rb +1 -1
- data/benchmark/bench_tool_schema.rb +1 -1
- data/docs/architecture/agent-chat-and-state-ownership.md +153 -0
- data/docs/architecture/agent-configuration-and-tool-binding.md +139 -0
- data/docs/architecture/agent-context.md +4 -2
- data/docs/architecture/agent-transition-ownership.md +13 -0
- data/docs/architecture/backend-groups.md +152 -0
- data/docs/architecture/before-llm-input.md +9 -3
- data/docs/architecture/context-management.md +31 -1
- data/docs/architecture/context-preparation-steps.md +90 -0
- data/docs/architecture/entry-action-and-team-wording.md +72 -0
- data/docs/architecture/execution-abstraction-review.md +88 -0
- data/docs/architecture/execution-boundaries.md +28 -0
- data/docs/architecture/execution-metadata-and-values.md +86 -0
- data/docs/architecture/generator-verifier-ownership.md +111 -0
- data/docs/architecture/multi-agent-handoff.md +11 -4
- data/docs/architecture/persistence-refactoring-plan.md +50 -0
- data/docs/architecture/persistence.md +45 -4
- data/docs/architecture/r8-unit1.md +104 -0
- data/docs/architecture/r8-unit10.md +72 -0
- data/docs/architecture/r8-unit11.md +71 -0
- data/docs/architecture/r8-unit12.md +67 -0
- data/docs/architecture/r8-unit13.md +61 -0
- data/docs/architecture/r8-unit14.md +72 -0
- data/docs/architecture/r8-unit15.md +65 -0
- data/docs/architecture/r8-unit16.md +54 -0
- data/docs/architecture/r8-unit17.md +73 -0
- data/docs/architecture/r8-unit18.md +92 -0
- data/docs/architecture/r8-unit19.md +61 -0
- data/docs/architecture/r8-unit2.md +55 -0
- data/docs/architecture/r8-unit20.md +51 -0
- data/docs/architecture/r8-unit21.md +79 -0
- data/docs/architecture/r8-unit22.md +74 -0
- data/docs/architecture/r8-unit23.md +81 -0
- data/docs/architecture/r8-unit3.md +130 -0
- data/docs/architecture/r8-unit4.md +79 -0
- data/docs/architecture/r8-unit5.md +115 -0
- data/docs/architecture/r8-unit6.md +71 -0
- data/docs/architecture/r8-unit7.md +70 -0
- data/docs/architecture/r8-unit8.md +78 -0
- data/docs/architecture/r8-unit9.md +73 -0
- data/docs/architecture/refactoring-closure.md +343 -0
- data/docs/architecture/remaining-refactoring-plan.md +390 -0
- data/docs/architecture/rubyllm-2-token-ownership.md +82 -0
- data/docs/architecture/storage-execution-boundaries.md +54 -0
- data/docs/architecture/tool-schema-recording-gap.md +56 -0
- data/docs/architecture/tracing.md +2 -2
- data/docs/architecture/workflow-terminal-ownership-design.md +104 -0
- data/docs/architecture.md +222 -0
- data/docs/decisions/014-unified-persistence-durable-state.md +11 -0
- data/docs/decisions/015-tool-public-facade-and-rbs-boundary.md +3 -3
- data/docs/decisions/024-event-loop-single-writer-agent-runtime.md +5 -1
- data/docs/decisions/025-process-local-agent-ownership-and-runtime-admission.md +13 -3
- data/docs/decisions/026-workflow-runtime-admission-and-durable-terminal-barrier.md +5 -1
- data/docs/decisions/027-llm-adapter-provider-boundary.md +2 -0
- data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +7 -0
- data/docs/decisions/031-durable-multi-agent-coordination.md +7 -0
- data/docs/decisions/032-storage-backend-composition.md +85 -0
- data/docs/decisions/033-domain-persistence-ownership.md +79 -0
- data/docs/decisions/034-handoff-runner-coordination-ownership.md +78 -0
- data/docs/decisions/035-tool-executor-capability-ownership.md +68 -0
- data/docs/decisions/036-context-contract-ownership.md +86 -0
- data/docs/decisions/037-common-definition-ownership.md +62 -0
- data/docs/decisions/038-responsibility-based-source-layout.md +145 -0
- data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +82 -0
- data/docs/decisions/040-configuration-default-composition.md +105 -0
- data/docs/decisions/041-feature-owned-identity-registries.md +100 -0
- data/docs/decisions/042-feature-owned-execution-state.md +106 -0
- data/docs/decisions/043-storage-execution-constraint-notifications.md +75 -0
- data/docs/decisions/044-agent-default-and-one-shot-composition.md +106 -0
- data/docs/decisions/045-worker-input-restriction-ownership.md +104 -0
- data/docs/decisions/046-agent-responsibility-layout-and-shared-records.md +110 -0
- data/docs/decisions/047-recovered-execution-continuation-contract.md +116 -0
- data/docs/decisions/048-dispatch-preparation-worker-ownership.md +120 -0
- data/docs/decisions/049-initial-preparation-worker-ownership.md +111 -0
- data/docs/decisions/050-approval-resume-snapshot-and-commit-ownership.md +98 -0
- data/docs/decisions/051-execution-outcome-worker-ownership.md +153 -0
- data/docs/decisions/052-tool-invocation-restoration-ownership.md +92 -0
- data/docs/decisions/053-shared-state-coordination-ownership.md +71 -0
- data/docs/decisions/054-workflow-terminal-save-single-owner.md +76 -0
- data/docs/decisions/055-terminal-observer-failure-settlement.md +60 -0
- data/docs/decisions/056-workflow-terminal-policy-ownership.md +87 -0
- data/docs/decisions/057-storage-transaction-boundaries.md +73 -0
- data/docs/decisions/058-neutral-storage-primitives.md +83 -0
- data/docs/decisions/059-backend-contracts-and-async-clients.md +74 -0
- data/docs/decisions/060-runtime-settings-and-application-configuration.md +86 -0
- data/docs/decisions/061-persistence-failure-contracts.md +89 -0
- data/docs/decisions/062-content-store-service.md +52 -0
- data/docs/decisions/063-execution-contracts-and-services.md +88 -0
- data/docs/decisions/064-agent-execution-and-multi-agent-responsibility.md +36 -0
- data/docs/decisions/065-vector-and-embeddings-common-operations.md +38 -0
- data/docs/decisions/066-llm-and-tool-operation-contracts.md +20 -0
- data/docs/decisions/067-agent-progress-and-engine-connection.md +29 -0
- data/docs/decisions/068-agent-tool-child-progress-and-tool-operation.md +36 -0
- data/docs/decisions/README.md +52 -6
- data/docs/design/durable-semantic-coordination/IMPLEMENTATION_DESIGN_V2.md +6 -0
- data/docs/design/durable-semantic-coordination/IMPLEMENTATION_REPORT.md +6 -0
- data/docs/execution-boundaries-preview.md +45 -0
- data/docs/features.md +16 -5
- data/docs/getting-started.md +11 -8
- data/docs/migrations/0.15.md +5 -0
- data/docs/migrations/0.22.md +2 -2
- data/docs/migrations/durable-semantic-coordination-v2.md +8 -0
- data/docs/migrations/handoff-runner-multi-agent.md +37 -0
- data/docs/migrations/neutral-storage-spi.md +43 -0
- data/docs/migrations/parallel-tool-chat-removal.md +49 -0
- data/docs/migrations/persistence-failure-contracts.md +67 -0
- data/docs/migrations/r8-unit10.md +36 -0
- data/docs/migrations/r8-unit11.md +33 -0
- data/docs/migrations/r8-unit12.md +31 -0
- data/docs/migrations/r8-unit13.md +36 -0
- data/docs/migrations/r8-unit14.md +31 -0
- data/docs/migrations/r8-unit15.md +31 -0
- data/docs/migrations/r8-unit16.md +26 -0
- data/docs/migrations/r8-unit17.md +28 -0
- data/docs/migrations/r8-unit18.md +29 -0
- data/docs/migrations/r8-unit19.md +28 -0
- data/docs/migrations/r8-unit20.md +24 -0
- data/docs/migrations/r8-unit21.md +28 -0
- data/docs/migrations/r8-unit22.md +29 -0
- data/docs/migrations/r8-unit23.md +20 -0
- data/docs/migrations/r8-unit4.md +67 -0
- data/docs/migrations/r8-unit5.md +75 -0
- data/docs/migrations/r8-unit6.md +109 -0
- data/docs/migrations/r8-unit7.md +31 -0
- data/docs/migrations/r8-unit8.md +33 -0
- data/docs/migrations/r8-unit9.md +28 -0
- data/docs/migrations/shared-state-multi-agent.md +44 -0
- data/docs/migrations/storage-async-client.md +103 -0
- data/docs/migrations/storage-backend-composition.md +117 -0
- data/docs/migrations/storage-transaction-boundaries.md +74 -0
- data/docs/migrations/vector-async-clients.md +110 -0
- data/docs/persistence-backends.md +190 -215
- data/docs/runtime-and-concurrency.md +142 -32
- data/lib/phronomy/agent/admission.rb +78 -0
- data/lib/phronomy/{agent_already_exists_error.rb → agent/agent_already_exists_error.rb} +2 -0
- data/lib/phronomy/{agent_busy_error.rb → agent/agent_busy_error.rb} +2 -0
- data/lib/phronomy/{agent_purged_error.rb → agent/agent_purged_error.rb} +2 -0
- data/lib/phronomy/agent/api/agent.rb +17 -0
- data/lib/phronomy/{execution_rehydration_required_error.rb → agent/api/execution_rehydration_required_error.rb} +2 -0
- data/lib/phronomy/agent/async_event_api.rb +38 -33
- data/lib/phronomy/agent/base.rb +106 -294
- data/lib/phronomy/agent/before_llm_input.rb +64 -0
- data/lib/phronomy/{agent.rb → agent/composition/run_once.rb} +4 -13
- data/lib/phronomy/agent/context_candidate_resolver.rb +2 -2
- data/lib/phronomy/agent/context_importer.rb +2 -2
- data/lib/phronomy/agent/{context_assembler.rb → context_preparation.rb} +157 -288
- data/lib/phronomy/agent/control_request.rb +21 -0
- data/lib/phronomy/agent/{agent_execution.rb → execution/agent_execution.rb} +8 -4
- data/lib/phronomy/agent/{agent_invocation.rb → execution/agent_invocation.rb} +32 -63
- data/lib/phronomy/agent/execution/approval_resume_commit.rb +108 -0
- data/lib/phronomy/agent/execution/dispatch_preparation.rb +195 -0
- data/lib/phronomy/agent/{exact_execution.rb → execution/exact_execution.rb} +43 -23
- data/lib/phronomy/agent/{execution_cancellation.rb → execution/execution_cancellation.rb} +8 -5
- data/lib/phronomy/agent/execution/execution_coordinator.rb +1744 -0
- data/lib/phronomy/agent/execution/execution_failure.rb +30 -0
- data/lib/phronomy/agent/execution/execution_metadata.rb +54 -0
- data/lib/phronomy/agent/execution/execution_outcome_committer.rb +288 -0
- data/lib/phronomy/agent/execution/execution_registry.rb +463 -0
- data/lib/phronomy/agent/execution/execution_session_runner.rb +113 -0
- data/lib/phronomy/agent/execution/initial_preparation.rb +323 -0
- data/lib/phronomy/agent/execution/invocation_actions.rb +368 -0
- data/lib/phronomy/agent/execution/invocation_transitions.rb +124 -0
- data/lib/phronomy/agent/execution/runtime_record_encoder.rb +210 -0
- data/lib/phronomy/agent/execution_change.rb +161 -0
- data/lib/phronomy/agent/execution_environment.rb +36 -0
- data/lib/phronomy/agent/execution_extension_state.rb +21 -0
- data/lib/phronomy/agent/execution_observation.rb +35 -0
- data/lib/phronomy/agent/filterable.rb +182 -0
- data/lib/phronomy/agent/{handoff_context.rb → handoff/transfer_context.rb} +6 -6
- data/lib/phronomy/agent/{handoff_projection.rb → handoff/transfer_projection.rb} +14 -33
- data/lib/phronomy/agent/handoff_error.rb +7 -0
- data/lib/phronomy/agent/{journal_projection.rb → journal/journal_projection.rb} +4 -0
- data/lib/phronomy/agent/{journal_record.rb → journal/journal_record.rb} +3 -3
- data/lib/phronomy/agent/{llm_call_record.rb → journal/llm_call_record.rb} +2 -2
- data/lib/phronomy/agent/knowledge_item.rb +13 -0
- data/lib/phronomy/agent/{agent_root.rb → lifecycle/agent_root.rb} +6 -2
- data/lib/phronomy/agent/lifecycle/default_persistence.rb +29 -0
- data/lib/phronomy/{engine/runtime/agent_ownership_registry.rb → agent/lifecycle/ownership_registry.rb} +24 -15
- data/lib/phronomy/agent/persistence/agent_repository.rb +69 -0
- data/lib/phronomy/agent/persistence/cancellation_repository.rb +51 -0
- data/lib/phronomy/agent/persistence/codec.rb +338 -0
- data/lib/phronomy/agent/persistence/execution_repository.rb +124 -0
- data/lib/phronomy/agent/persistence/journal_repository.rb +63 -0
- data/lib/phronomy/agent/persistence/records.rb +33 -0
- data/lib/phronomy/agent/persistence/retention_repository.rb +70 -0
- data/lib/phronomy/agent/persistence/storage_schema.rb +29 -0
- data/lib/phronomy/agent/persistence/watermark.rb +29 -0
- data/lib/phronomy/agent/recovery/invocation_restorer.rb +124 -0
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/continuation.rb +28 -51
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/installation.rb +50 -55
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/resolution.rb +38 -43
- data/lib/phronomy/agent/{recovery_coordinator.rb → recovery/recovery_coordinator.rb} +26 -23
- data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
- data/lib/phronomy/agent/recovery/recovery_support.rb +224 -0
- data/lib/phronomy/agent/reserved_execution.rb +16 -0
- data/lib/phronomy/agent/retention.rb +17 -0
- data/lib/phronomy/agent/runtime_binding/engine_environment.rb +60 -0
- data/lib/phronomy/agent/runtime_binding/engine_session_builder.rb +34 -0
- data/lib/phronomy/agent/runtime_binding/phase_machine_builder.rb +64 -0
- data/lib/phronomy/agent/runtime_binding/tool_session_builder.rb +34 -0
- data/lib/phronomy/agent/{ruby_llm_materializer.rb → runtime_input.rb} +19 -39
- data/lib/phronomy/agent/saved_context_reader.rb +55 -0
- data/lib/phronomy/agent/settings.rb +47 -0
- data/lib/phronomy/agent/state_writer.rb +166 -0
- data/lib/phronomy/agent/store.rb +253 -0
- data/lib/phronomy/{stream_callback_error.rb → agent/stream_callback_error.rb} +2 -0
- data/lib/phronomy/agent/{approval_evaluation_request.rb → tool_execution/approval_evaluation_request.rb} +1 -12
- data/lib/phronomy/agent/{tool_approval_request.rb → tool_execution/tool_approval_request.rb} +1 -10
- data/lib/phronomy/agent/tool_execution/tool_binding.rb +30 -0
- data/lib/phronomy/agent/{tool_invocation.rb → tool_execution/tool_invocation.rb} +114 -248
- data/lib/phronomy/agent/tool_execution/tool_invocation_actions.rb +107 -0
- data/lib/phronomy/agent/tool_execution/tool_invocation_transitions.rb +70 -0
- data/lib/phronomy/common/configuration_error.rb +7 -0
- data/lib/phronomy/common/error.rb +5 -0
- data/lib/phronomy/{agent → common/values}/immutable.rb +9 -1
- data/lib/phronomy/common/values/serializable.rb +32 -0
- data/lib/phronomy/configuration/runtime_settings.rb +49 -0
- data/lib/phronomy/content_store/storage_schema.rb +12 -0
- data/lib/phronomy/content_store/stored_contents.rb +44 -0
- data/lib/phronomy/context/assembly.rb +202 -0
- data/lib/phronomy/{context_budget_exceeded_error.rb → context/budget_exceeded_error.rb} +5 -1
- data/lib/phronomy/context/candidate.rb +51 -0
- data/lib/phronomy/context/constraint.rb +47 -0
- data/lib/phronomy/{agent → context}/context_plan.rb +2 -2
- data/lib/phronomy/{agent → context}/context_plan_validator.rb +3 -3
- data/lib/phronomy/{agent → context}/context_policy.rb +1 -1
- data/lib/phronomy/{agent → context}/context_policy_input.rb +7 -7
- data/lib/phronomy/{agent → context}/context_policy_input_builder.rb +1 -1
- data/lib/phronomy/context/default_policy.rb +140 -0
- data/lib/phronomy/context/final_budget_validator.rb +33 -0
- data/lib/phronomy/{agent → context}/llm_input_build_context.rb +2 -2
- data/lib/phronomy/{agent → context}/llm_input_manifest.rb +21 -21
- data/lib/phronomy/{agent → context}/llm_input_patch.rb +3 -3
- data/lib/phronomy/context/manifest_error.rb +10 -0
- data/lib/phronomy/context/prompt_template.rb +98 -0
- data/lib/phronomy/{vector_store → documents}/loader/base.rb +1 -1
- data/lib/phronomy/{vector_store → documents}/loader/csv_loader.rb +2 -2
- data/lib/phronomy/{vector_store → documents}/loader/markdown_loader.rb +3 -3
- data/lib/phronomy/{vector_store → documents}/loader/plain_text_loader.rb +2 -2
- data/lib/phronomy/{vector_store → documents}/splitter/base.rb +1 -1
- data/lib/phronomy/{vector_store → documents}/splitter/fixed_size_splitter.rb +2 -2
- data/lib/phronomy/{vector_store → documents}/splitter/recursive_splitter.rb +2 -2
- data/lib/phronomy/embeddings/async/async_client.rb +44 -0
- data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +48 -0
- data/lib/phronomy/embeddings/base.rb +43 -0
- data/lib/phronomy/embeddings/invalid_result_error.rb +11 -0
- data/lib/phronomy/embeddings/transport_error.rb +11 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +39 -20
- data/lib/phronomy/engine/concurrency/pool_registry.rb +47 -12
- data/lib/phronomy/{diagnostics.rb → engine/diagnostics.rb} +1 -1
- data/lib/phronomy/engine/event_loop.rb +164 -630
- data/lib/phronomy/engine/execution_binding.rb +23 -0
- data/lib/phronomy/engine/execution_receiver_binding.rb +43 -0
- data/lib/phronomy/engine/fsm_protocol.rb +9 -0
- data/lib/phronomy/engine/fsm_session.rb +37 -30
- data/lib/phronomy/engine/metrics.rb +28 -0
- data/lib/phronomy/engine/runtime/timer_queue.rb +1 -1
- data/lib/phronomy/engine/runtime.rb +104 -95
- data/lib/phronomy/engine/terminal_decision.rb +7 -0
- data/lib/phronomy/execution/async_operation.rb +41 -0
- data/lib/phronomy/execution/backpressure_error.rb +7 -0
- data/lib/phronomy/{blocking.rb → execution/blocking.rb} +2 -2
- data/lib/phronomy/execution/cancellation_error.rb +7 -0
- data/lib/phronomy/{engine → execution}/concurrency/cancellation_token.rb +5 -1
- data/lib/phronomy/{engine → execution}/concurrency/deadline.rb +0 -17
- data/lib/phronomy/{engine → execution}/concurrency/physical_completion_task.rb +1 -1
- data/lib/phronomy/{engine → execution}/concurrency/result_collector.rb +1 -1
- data/lib/phronomy/{engine → execution}/concurrency/result_composition.rb +33 -12
- data/lib/phronomy/{engine/concurrency/subscriptions.rb → execution/concurrency/result_subscriptions.rb} +14 -18
- data/lib/phronomy/execution/concurrency/subscriptions.rb +25 -0
- data/lib/phronomy/execution/concurrency/worker_input_restricted.rb +14 -0
- data/lib/phronomy/execution/event_loop_reentrancy_error.rb +8 -0
- data/lib/phronomy/{execution.rb → execution/execution.rb} +57 -30
- data/lib/phronomy/{execution_cancellation_error.rb → execution/execution_cancellation_error.rb} +2 -0
- data/lib/phronomy/execution/execution_receiver.rb +78 -0
- data/lib/phronomy/execution/execution_scope_state.rb +35 -0
- data/lib/phronomy/{execution_timeout_error.rb → execution/execution_timeout_error.rb} +2 -0
- data/lib/phronomy/{invalid_async_entry_action_error.rb → execution/invalid_async_entry_action_error.rb} +2 -0
- data/lib/phronomy/{invalid_async_transition_action_error.rb → execution/invalid_async_transition_action_error.rb} +2 -0
- data/lib/phronomy/{invalid_async_workflow_action_error.rb → execution/invalid_async_workflow_action_error.rb} +2 -0
- data/lib/phronomy/{invocation_context.rb → execution/invocation_context.rb} +0 -15
- data/lib/phronomy/execution/invocation_controls.rb +73 -0
- data/lib/phronomy/execution/pool_shutdown_error.rb +7 -0
- data/lib/phronomy/execution/recursion_limit_error.rb +7 -0
- data/lib/phronomy/execution/runnable.rb +24 -0
- data/lib/phronomy/execution/runtime_shutdown_error.rb +7 -0
- data/lib/phronomy/execution/runtime_shutdown_reentrancy_error.rb +7 -0
- data/lib/phronomy/execution/scheduler_reentrancy_error.rb +9 -0
- data/lib/phronomy/{engine → execution}/task_result.rb +7 -3
- data/lib/phronomy/execution/timeout_error.rb +7 -0
- data/lib/phronomy/execution/wait_policy.rb +24 -0
- data/lib/phronomy/filter/filter_block_error.rb +14 -0
- data/lib/phronomy/generation/generator_verifier/agent_operation.rb +65 -0
- data/lib/phronomy/generation/generator_verifier/agent_result_receiver.rb +89 -0
- data/lib/phronomy/generation/generator_verifier/default_parser.rb +27 -0
- data/lib/phronomy/generation/generator_verifier/pipeline_state.rb +57 -0
- data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +112 -0
- data/lib/phronomy/generation/generator_verifier.rb +118 -0
- data/lib/phronomy/generation/low_confidence_error.rb +14 -0
- data/lib/phronomy/llm_adapter/async/async_client.rb +47 -0
- data/lib/phronomy/llm_adapter/authentication_error.rb +9 -0
- data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +183 -0
- data/lib/phronomy/llm_adapter/base.rb +49 -68
- data/lib/phronomy/llm_adapter/context_length_error.rb +9 -0
- data/lib/phronomy/llm_adapter/invalid_result_error.rb +10 -0
- data/lib/phronomy/llm_adapter/message.rb +62 -0
- data/lib/phronomy/llm_adapter/rate_limit_error.rb +9 -0
- data/lib/phronomy/llm_adapter/request.rb +79 -0
- data/lib/phronomy/llm_adapter/response.rb +36 -0
- data/lib/phronomy/llm_adapter/stream_chunk.rb +18 -0
- data/lib/phronomy/llm_adapter/token_usage.rb +64 -0
- data/lib/phronomy/llm_adapter/transport_error.rb +9 -0
- data/lib/phronomy/llm_adapter.rb +3 -16
- data/lib/phronomy/llm_context_window/token_budget.rb +6 -7
- data/lib/phronomy/multi_agent/admission_registry.rb +15 -2
- data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +108 -84
- data/lib/phronomy/multi_agent/execution_environment.rb +29 -0
- data/lib/phronomy/{agent → multi_agent}/handoff.rb +2 -2
- data/lib/phronomy/{agent → multi_agent}/handoff_capability_factory.rb +21 -2
- data/lib/phronomy/multi_agent/handoff_participant.rb +79 -0
- data/lib/phronomy/{agent → multi_agent}/handoff_policy.rb +1 -1
- data/lib/phronomy/multi_agent/handoff_runner.rb +156 -0
- data/lib/phronomy/{agent → multi_agent}/handoff_state.rb +2 -2
- data/lib/phronomy/multi_agent/orchestrator.rb +61 -75
- data/lib/phronomy/multi_agent/persistence/codec.rb +75 -0
- data/lib/phronomy/multi_agent/persistence/handoff_state_repository.rb +77 -0
- data/lib/phronomy/multi_agent/persistence/records.rb +27 -0
- data/lib/phronomy/multi_agent/persistence/storage_schema.rb +21 -0
- data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +124 -0
- data/lib/phronomy/multi_agent/persistence/team_repository.rb +69 -0
- data/lib/phronomy/multi_agent/reserved_child_admission.rb +88 -0
- data/lib/phronomy/multi_agent/runtime_binding/engine_environment.rb +35 -0
- data/lib/phronomy/{agent → multi_agent}/shared_state.rb +56 -39
- data/lib/phronomy/multi_agent/store.rb +156 -0
- data/lib/phronomy/multi_agent/team_coordinator.rb +87 -75
- data/lib/phronomy/multi_agent/team_execution.rb +1 -1
- data/lib/phronomy/{engine/runtime → multi_agent}/team_ownership_registry.rb +5 -5
- data/lib/phronomy/multi_agent/team_root.rb +1 -1
- data/lib/phronomy/output_parser/parse_error.rb +7 -0
- data/lib/phronomy/persistence/content_repository.rb +26 -0
- data/lib/phronomy/persistence/errors.rb +16 -0
- data/lib/phronomy/persistence/migration/initial_format_migration.rb +21 -21
- data/lib/phronomy/persistence/persistence.rb +23 -0
- data/lib/phronomy/persistence/save_outcome.rb +24 -0
- data/lib/phronomy/persistence/snapshot_comparison.rb +81 -0
- data/lib/phronomy/persistence/storage_boundary.rb +32 -0
- data/lib/phronomy/persistence/transaction.rb +86 -0
- data/lib/phronomy/persistence_composition/storage_schema.rb +29 -0
- data/lib/phronomy/persistence_composition/stores.rb +34 -0
- data/lib/phronomy/persistence_composition/unit4_migration.rb +276 -0
- data/lib/phronomy/runtime_composition/agent_defaults.rb +11 -0
- data/lib/phronomy/runtime_composition/configuration.rb +146 -0
- data/lib/phronomy/runtime_composition/configuration_defaults.rb +9 -0
- data/lib/phronomy/runtime_composition/evaluation_defaults.rb +7 -0
- data/lib/phronomy/runtime_composition/execution_defaults.rb +5 -0
- data/lib/phronomy/runtime_composition/generation_defaults.rb +6 -0
- data/lib/phronomy/runtime_composition/global_configuration.rb +38 -0
- data/lib/phronomy/runtime_composition/global_runtime.rb +19 -0
- data/lib/phronomy/runtime_composition/multi_agent_defaults.rb +9 -0
- data/lib/phronomy/runtime_composition/workflow_defaults.rb +4 -0
- data/lib/phronomy/storage/async/async_client.rb +60 -0
- data/lib/phronomy/storage/backend.rb +107 -0
- data/lib/phronomy/storage/backends/in_memory.rb +157 -0
- data/lib/phronomy/storage/blob_conflict_error.rb +10 -0
- data/lib/phronomy/storage/blobs.rb +31 -0
- data/lib/phronomy/storage/condition.rb +25 -0
- data/lib/phronomy/storage/condition_failed_error.rb +16 -0
- data/lib/phronomy/storage/conflict_error.rb +9 -0
- data/lib/phronomy/{persistence → storage}/durable_record.rb +12 -12
- data/lib/phronomy/storage/entry.rb +33 -0
- data/lib/phronomy/storage/guard_ref.rb +13 -0
- data/lib/phronomy/storage/not_found_error.rb +9 -0
- data/lib/phronomy/storage/record_codec.rb +177 -0
- data/lib/phronomy/storage/records.rb +61 -0
- data/lib/phronomy/storage/resource.rb +126 -0
- data/lib/phronomy/storage/scope.rb +25 -0
- data/lib/phronomy/storage/serialization_error.rb +9 -0
- data/lib/phronomy/storage/streams.rb +44 -0
- data/lib/phronomy/storage/transaction_error.rb +10 -0
- data/lib/phronomy/storage/unique_constraint_error.rb +17 -0
- data/lib/phronomy/storage/unsupported_backend_error.rb +9 -0
- data/lib/phronomy/storage/validation.rb +53 -0
- data/lib/phronomy/storage/view.rb +131 -0
- data/lib/phronomy/testing/eval/metrics.rb +1 -1
- data/lib/phronomy/testing/eval/scorer/llm_judge.rb +19 -3
- data/lib/phronomy/testing/persistence_contract/a_content_store.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +2 -2
- data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +54 -48
- data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +5 -5
- data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +52 -46
- data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +263 -0
- data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +124 -0
- data/lib/phronomy/testing/persistence_contract.rb +4 -0
- data/lib/phronomy/tool/authorization.rb +77 -0
- data/lib/phronomy/tool/base.rb +549 -9
- data/lib/phronomy/tool/call_request.rb +40 -0
- data/lib/phronomy/{agent/tool_definition_set.rb → tool/definition_set.rb} +16 -12
- data/lib/phronomy/tool/operation.rb +88 -0
- data/lib/phronomy/tool/schema.rb +214 -0
- data/lib/phronomy/tool/settings.rb +31 -0
- data/lib/phronomy/tool/tool_error.rb +7 -0
- data/lib/phronomy/{agent → tool}/tool_executor.rb +10 -7
- data/lib/phronomy/tools/agent.rb +22 -90
- data/lib/phronomy/tools/mcp.rb +21 -14
- data/lib/phronomy/tools/vector_search.rb +4 -4
- data/lib/phronomy/tracing/automatic.rb +11 -6
- data/lib/phronomy/tracing/base.rb +1 -1
- data/lib/phronomy/tracing/observation.rb +37 -0
- data/lib/phronomy/tracing/settings.rb +36 -0
- data/lib/phronomy/vector_store/{async_backend.rb → async/async_client.rb} +35 -29
- data/lib/phronomy/vector_store/{in_memory.rb → backends/in_memory.rb} +12 -10
- data/lib/phronomy/vector_store/{pgvector.rb → backends/pgvector.rb} +44 -16
- data/lib/phronomy/vector_store/{redis_search.rb → backends/redis_search.rb} +74 -37
- data/lib/phronomy/vector_store/base.rb +118 -49
- data/lib/phronomy/vector_store/invalid_result_error.rb +12 -0
- data/lib/phronomy/vector_store.rb +2 -17
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/workflow/completion.rb +11 -0
- data/lib/phronomy/{workflow.rb → workflow/execution/workflow.rb} +10 -8
- data/lib/phronomy/workflow/execution/workflow_action_rules.rb +67 -0
- data/lib/phronomy/{workflow_context.rb → workflow/execution/workflow_context.rb} +5 -1
- data/lib/phronomy/workflow/execution/workflow_context_ownership_error.rb +7 -0
- data/lib/phronomy/workflow/execution/workflow_execution_environment.rb +27 -0
- data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +186 -0
- data/lib/phronomy/{workflow_runner.rb → workflow/execution/workflow_runner.rb} +145 -115
- data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -0
- data/lib/phronomy/workflow/persistence/codec.rb +153 -0
- data/lib/phronomy/workflow/persistence/state_repository.rb +63 -0
- data/lib/phronomy/workflow/persistence/storage_schema.rb +13 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_engine_environment.rb +38 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +156 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_terminal_policy.rb +40 -0
- data/lib/phronomy.rb +97 -98
- data/scripts/api_snapshot.rb +36 -16
- data/scripts/storage_spi_snapshot.rb +36 -0
- data/sig/_private/phronomy/agent/settings.rbs +19 -0
- data/sig/_private/phronomy/configuration/runtime_settings.rbs +20 -0
- data/sig/_private/phronomy/llm_adapter/async/async_client.rbs +10 -0
- data/sig/_private/phronomy/multi_agent/store.rbs +8 -0
- data/sig/_private/phronomy/persistence/storage_boundary.rbs +7 -0
- data/sig/_private/phronomy/tool/settings.rbs +13 -0
- data/sig/_private/phronomy/tracing/settings.rbs +15 -0
- data/sig/_private/phronomy/workflow/execution/workflow_settings.rbs +13 -0
- data/sig/phronomy/agent/admission.rbs +19 -0
- data/sig/phronomy/agent/execution_contract.rbs +132 -0
- data/sig/phronomy/agent/execution_environment.rbs +20 -0
- data/sig/phronomy/agent/store.rbs +73 -0
- data/sig/phronomy/agent.rbs +14 -139
- data/sig/phronomy/common.rbs +7 -0
- data/sig/phronomy/content_store/contracts.rbs +13 -0
- data/sig/phronomy/context.rbs +152 -0
- data/sig/phronomy/embeddings/async/async_client.rbs +9 -0
- data/sig/phronomy/embeddings/base.rbs +17 -0
- data/sig/phronomy/engine/concurrency/timer_bindings.rbs +22 -0
- data/sig/phronomy/engine/control_bindings.rbs +11 -0
- data/sig/phronomy/engine/control_protocols.rbs +23 -0
- data/sig/phronomy/engine/execution_binding.rbs +6 -0
- data/sig/phronomy/engine/execution_receiver.rbs +15 -0
- data/sig/phronomy/engine/observability.rbs +13 -0
- data/sig/phronomy/execution/async_operation.rbs +7 -0
- data/sig/phronomy/execution/blocking.rbs +5 -0
- data/sig/phronomy/execution/concurrency/cancellation_token.rbs +13 -0
- data/sig/phronomy/execution/concurrency/deadline.rbs +10 -0
- data/sig/phronomy/execution/concurrency/result_composition.rbs +7 -0
- data/sig/phronomy/execution/control_protocols.rbs +18 -0
- data/sig/phronomy/execution/errors.rbs +7 -0
- data/sig/phronomy/execution/execution.rbs +41 -0
- data/sig/phronomy/execution/execution_receiver.rbs +40 -0
- data/sig/phronomy/execution/execution_scope_state.rbs +9 -0
- data/sig/phronomy/execution/invocation_context.rbs +18 -0
- data/sig/phronomy/execution/invocation_controls.rbs +13 -0
- data/sig/phronomy/execution/task_result.rbs +29 -0
- data/sig/phronomy/extensions.rbs +0 -21
- data/sig/phronomy/handoff.rbs +12 -4
- data/sig/phronomy/llm_adapter/backends/ruby_llm.rbs +6 -0
- data/sig/phronomy/llm_adapter/base.rbs +14 -0
- data/sig/phronomy/llm_adapter/usage.rbs +14 -0
- data/sig/phronomy/llm_adapter/values.rbs +43 -0
- data/sig/phronomy/llm_context_window.rbs +10 -0
- data/sig/phronomy/multi_agent/reserved_child_admission.rbs +8 -0
- data/sig/phronomy/multi_agent/store.rbs +54 -0
- data/sig/phronomy/multi_agent.rbs +24 -3
- data/sig/phronomy/persistence/errors.rbs +18 -0
- data/sig/phronomy/persistence/migration.rbs +13 -0
- data/sig/phronomy/persistence/transaction.rbs +19 -0
- data/sig/phronomy/persistence.rbs +3 -185
- data/sig/phronomy/persistence_composition.rbs +19 -0
- data/sig/phronomy/runtime_composition/configuration.rbs +36 -0
- data/sig/phronomy/storage/async/async_client.rbs +8 -0
- data/sig/phronomy/storage/backends/in_memory.rbs +9 -0
- data/sig/phronomy/storage/contracts.rbs +160 -0
- data/sig/phronomy/tool.rbs +58 -5
- data/sig/phronomy/tracing/observation.rbs +7 -0
- data/sig/phronomy/vector_store/async/async_client.rbs +13 -0
- data/sig/phronomy/vector_store/base.rbs +23 -0
- data/sig/phronomy/workflow/execution/workflow_execution_environment.rbs +14 -0
- data/sig/phronomy/workflow/runtime_binding/workflow_terminal_policy.rbs +7 -0
- data/sig/phronomy/workflow/store.rbs +8 -0
- data/sig/phronomy/workflow.rbs +1 -1
- data/sig/phronomy.rbs +0 -49
- metadata +462 -130
- data/lib/phronomy/agent/agent_invocation_session_builder.rb +0 -584
- data/lib/phronomy/agent/concerns/before_llm_input.rb +0 -66
- data/lib/phronomy/agent/concerns/error_translation.rb +0 -45
- data/lib/phronomy/agent/concerns/filterable.rb +0 -184
- data/lib/phronomy/agent/context/capability/base.rb +0 -507
- data/lib/phronomy/agent/context/instruction/prompt_template.rb +0 -102
- data/lib/phronomy/agent/context_parts/validators/final_budget_validator.rb +0 -37
- data/lib/phronomy/agent/context_policies/default.rb +0 -142
- data/lib/phronomy/agent/execution_coordinator.rb +0 -3151
- data/lib/phronomy/agent/handoff_execution_coordinator.rb +0 -143
- data/lib/phronomy/agent/handoff_request.rb +0 -45
- data/lib/phronomy/agent/handoff_runner.rb +0 -178
- data/lib/phronomy/agent/phase_machine_builder.rb +0 -152
- data/lib/phronomy/agent/provider_call_outcome.rb +0 -106
- data/lib/phronomy/agent/recovery_support.rb +0 -504
- data/lib/phronomy/agent/selection/candidate.rb +0 -53
- data/lib/phronomy/agent/selection/constraint.rb +0 -49
- data/lib/phronomy/agent/token_budget_resolver.rb +0 -70
- data/lib/phronomy/agent/tool_call_intercepted.rb +0 -29
- data/lib/phronomy/agent/tool_invocation_session_builder.rb +0 -276
- data/lib/phronomy/configuration.rb +0 -59
- data/lib/phronomy/engine/concurrency/cancellation_scope.rb +0 -124
- data/lib/phronomy/engine/concurrency/operation_binding.rb +0 -43
- data/lib/phronomy/generator_verifier.rb +0 -369
- data/lib/phronomy/invalid_context_budget_configuration_error.rb +0 -8
- data/lib/phronomy/llm_adapter/ruby_llm.rb +0 -47
- data/lib/phronomy/metrics.rb +0 -26
- data/lib/phronomy/multi_agent/parallel_tool_chat.rb +0 -116
- data/lib/phronomy/persistence/durable_codec.rb +0 -706
- data/lib/phronomy/persistence/in_memory.rb +0 -690
- data/lib/phronomy/persistence/repository_facades.rb +0 -535
- data/lib/phronomy/persistence.rb +0 -276
- data/lib/phronomy/recovery.rb +0 -186
- data/lib/phronomy/ruby_llm_patches.rb +0 -24
- data/lib/phronomy/runnable.rb +0 -54
- data/lib/phronomy/token_usage.rb +0 -85
- data/lib/phronomy/vector_store/embeddings/base.rb +0 -44
- data/lib/phronomy/vector_store/embeddings/ruby_llm_embeddings.rb +0 -47
- data/lib/phronomy/workflow/phase_machine_builder.rb +0 -205
- data/lib/phronomy/workflow_recovery.rb +0 -123
- data/sig/phronomy/llm_adapter.rbs +0 -11
- data/sig/phronomy/runtime.rbs +0 -76
- /data/lib/phronomy/agent/{llm_operation_result.rb → execution/llm_operation_result.rb} +0 -0
- /data/lib/phronomy/{canonical_json.rb → common/canonical_json.rb} +0 -0
- /data/lib/phronomy/{event.rb → engine/event.rb} +0 -0
|
@@ -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.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# r8 unit 2:親の予約確認とAgent受付
|
|
2
|
+
|
|
3
|
+
この単位はP02/P03の受付境界を実装する。基準はcore `16e6fcb2dd49836735598525114abfc256d0773e`。r8全体やPersistenceの全面整理の完了ではない。
|
|
4
|
+
|
|
5
|
+
## 責務と操作
|
|
6
|
+
|
|
7
|
+
| 担当 | 公開操作・共通規則 | 依存と内部実装 |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| 共通Persistence | `atomic`、`Transaction#participate`、`committed?`。同じPersistence、同期thread、有効scope、savepoint、commit応答を検証 | Storageの公開transaction・scope規則を利用。Agent/Team/Workflowや構成担当を選ばない |
|
|
10
|
+
| Agent | `Admission#accept_in`。入力記録・実行ID・Agentの受付とrevision更新を同一scopeへ保存 | Agentの保存担当を使用。親のkind・Team割当・subagent snapshot・Handoff予約を解釈しない |
|
|
11
|
+
| MultiAgent | `ReservedChildAdmission#admit`。親の取消・slot・子IDを検証し、Agent受付を同じscopeへ参加させる | 自分の保存担当が予約の根拠を読み、必要なguardを取得する |
|
|
12
|
+
| 保存担当 | `Agent::Persistence::Admission`、`MultiAgent::Persistence::Reservation` | raw Storage viewはこの境界で使用。ドメイン操作へraw viewを渡さない |
|
|
13
|
+
|
|
14
|
+
AgentのRuntime admission取得、FSM開始、live状態の反映は既存のExecutionCoordinatorが引き続き所有する。新しいAdmissionはその短い保存フェーズだけであり、Agent実行全体を親のDB transactionへ入れない。通常のアプリは新しい参加クラスを実装・生成する必要がない。
|
|
15
|
+
|
|
16
|
+
`phronomy_admission` は内部の現在の配線であり、Procやオブジェクトを保存しない。永続化するのは従来の相関情報と親子IDだけ。Team/subagent/Handoffの開始・再開担当が現在の参加者を渡す。保存済み実行への再接続はExactExecutionの同一ID照合と復旧規則を維持する。
|
|
17
|
+
|
|
18
|
+
## 保存順序と失敗
|
|
19
|
+
|
|
20
|
+
1. Agentが既存のRuntime受付を取得し、同期workerで保存操作を開始する。
|
|
21
|
+
2. MultiAgentが短い`atomic` scopeを開き、親のguardを取得してから予約を読み直す。
|
|
22
|
+
3. 親の取消・割当・子の識別子を検証する。Agentは同じscopeで入力内容・AgentExecution・AgentRootを保存する。
|
|
23
|
+
4. commit応答が成功した後に、Agent実行担当だけが受付結果を取得し、準備・FSM・live反映を進める。
|
|
24
|
+
|
|
25
|
+
参加操作の戻り値はcommit成功を意味しない。`accept_in`はnilを返し、Agent内部の`result`は外側のcommitまで利用できない。二重参加、別Persistence、別thread、終了後scopeは拒否する。同じbackendを包む別Persistenceも同一scopeと扱わない。raw backend transactionの中から新しくcommit所有者を名乗ることも拒否する。
|
|
26
|
+
|
|
27
|
+
明示的な入れ子はsavepointとして動く。内側が成功しても外側がrollbackした場合は未成立。参加処理中の例外を内側で捕捉しても、失敗したscopeの先行変更をcommitできない。LLM、Tool、scheduler、外部callback、非同期待機を参加処理へ入れない。
|
|
28
|
+
|
|
29
|
+
Storageのscope違反は`Persistence::TransactionError`へcause・backtraceを保持して変換する。この名前の変更は、保存成否が既知であるとの宣言ではない。IOError等の成否不明な保存失敗は変換・自動retryせず、既存のAgent復旧規則へ渡す。今回、一般化した保存成否照合APIは追加していない。
|
|
30
|
+
|
|
31
|
+
## 取消との競合
|
|
32
|
+
|
|
33
|
+
TeamはTeamRoot、subagentは親AgentRoot、Handoffはrouting recordをguardとする。PostgreSQLではそのguardの行ロックと既存の条件付き更新によって、取消・変更と子受付を順序付ける。子受付側の通常readだけでは、この保証は成立しなかった。
|
|
34
|
+
|
|
35
|
+
Handoff取消側は最初に子の状態を観測し、未完了/不在ならroutingをロックして**子の状態を再取得**する。待機中に子受付がcommitした場合、古い「不在」の判断を捨て、受付済みの子へ公開取消を送る。既に終端の実行への取消は従来どおり結果参照として扱う。
|
|
36
|
+
|
|
37
|
+
InMemoryは共有Monitor、SQLiteはtransactionと書込競合検出、PostgreSQLは行ロックを使用する。SQLiteで競合したtransactionは成功とみなさず、backendの失敗を扱う。分散leaseや外部副作用のexactly-onceは追加しない。実PostgreSQLでの待機順序はexamplesの新しい3件の並行テストで確認する対象であり、InMemory/SQLiteの成功から推定して済ませない。
|
|
38
|
+
|
|
39
|
+
## API・ファイル変更
|
|
40
|
+
|
|
41
|
+
- Agent::InitialPreparationの`build_admitted_execution`と3種の親検証・kind分岐を削除。Agent自身の受付共通処理とMultiAgentの予約判断へ分離した。
|
|
42
|
+
- 共通の参加frameworkを`persistence/transaction.rb`、Agent受付を`agent/admission.rb`、保存接続を既存の各domainの`persistence/`へ置いた。新しいディレクトリや独立Contractは増やしていない。
|
|
43
|
+
- Storage SPIに同期contextの`transaction_open?`を追加。Storage::Backendの継承実装には共通実装が提供される。継承しない独自SPI実装はこの操作も提供する必要がある。RBS・SPI snapshot・duck-typed backendの検証を更新した。
|
|
44
|
+
- Persistenceの既知scope失敗の公開型を`Persistence::TransactionError`へ統一し、旧Storage例外のaliasは設けない。Storageを直接使う処理では従来のStorage例外を使用する。
|
|
45
|
+
- RBSはsigに配置し、参加者factory、Agent受付、MultiAgentの依存を宣言する。動的な`phronomy_admission`注入も本書と利用箇所で追跡する。
|
|
46
|
+
- 依存解析のExecution境界規則を図のrevision表示名から分離した。unit名の更新で同期backendからExecutionへの禁止規則が解除されないことを回帰テストする。
|
|
47
|
+
- 保存recordの形式、ID、revision規則は変更していない。データ移行は不要。
|
|
48
|
+
|
|
49
|
+
## 残る課題
|
|
50
|
+
|
|
51
|
+
`Persistence#transaction`とdomain repositoryの一括窓口は現行利用箇所が残るため、この単位では全面削除していない。互換維持のために新しい旧名aliasを追加したものではないが、P01/DP04の完了条件は未達である。次にdomain照会・保存構成を移し、不要な窓口を利用側と同時に削除する。
|
|
52
|
+
|
|
53
|
+
MultiAgentの保存担当にはAgentのexecution/Handoff repositoryへの参照が残る。予約検証の所有者は整理したが、親子の公開投影・認可照会・結果取込まで隠蔽したとは扱わない。P04/F02/F03の残課題として、Agentが公開する操作と、MultiAgentが所有すべき保存形式を確定する。一般的なmetadata getterを足すだけの解決にはしない。
|
|
54
|
+
|
|
55
|
+
Agent/TeamのFSM接続、Workflowのdurableな子連携(P05)、複数記録の保存成否照合(P06)、残りの配置整理、155組・393件の意味的再判定も残る。今回のSVGは実装候補を描き、全体の循環解消を示す構想図にはしない。
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# R8 unit20: Passive Engine observation
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
Metrics.snapshot previously called Runtime.instance, Runtime#offload and
|
|
6
|
+
Runtime#event_loop. A cold snapshot constructed the default Runtime, started
|
|
7
|
+
default-pool workers and started the EventLoop. Looking at an existing Runtime
|
|
8
|
+
could initialize its other resources. The same calls rejected observation after
|
|
9
|
+
shutdown, precisely when diagnostics were useful. Diagnostics.snapshot and dump
|
|
10
|
+
inherited these effects through Metrics.snapshot.
|
|
11
|
+
|
|
12
|
+
## Responsibility
|
|
13
|
+
|
|
14
|
+
Runtime retains ownership of its singleton and resource references. PoolRegistry
|
|
15
|
+
retains ownership of its default pool. Both provide internal lookup operations
|
|
16
|
+
using their existing mutexes, without construction or admission checks. Runtime's
|
|
17
|
+
existing EventLoop lookup already provides the same behavior. These lookups can
|
|
18
|
+
observe retained resources after shutdown without reopening them.
|
|
19
|
+
|
|
20
|
+
Metrics samples the returned resources and formats the existing ten numeric
|
|
21
|
+
fields. It does not inspect instance variables, decide resource initialization,
|
|
22
|
+
read configuration as a substitute for measurements, or cache Runtime references.
|
|
23
|
+
The test-only singleton lookup delegates to the internal lookup; production code
|
|
24
|
+
does not call a test helper. RBS describes the optional resource references.
|
|
25
|
+
|
|
26
|
+
## Behavior and scope
|
|
27
|
+
|
|
28
|
+
Missing resources contribute zero. An uninitialized default pool therefore has
|
|
29
|
+
size zero even if configuration would allocate ten workers on first use. For an
|
|
30
|
+
existing pool, size continues to describe configured capacity, including after
|
|
31
|
+
shutdown; it is not a count of living workers. Named pools remain outside these
|
|
32
|
+
default-pool metrics. A subsequent snapshot follows the current default Runtime,
|
|
33
|
+
so a reset neither recreates it nor keeps stale metrics in a cache.
|
|
34
|
+
|
|
35
|
+
Counters remain independent observations. Concurrent activity or Runtime reset
|
|
36
|
+
can occur during a snapshot; no globally atomic observation or lifecycle barrier
|
|
37
|
+
is promised. Resource references are obtained under their owners' existing locks
|
|
38
|
+
and metrics are read after those lookup locks are released. No new lock ordering,
|
|
39
|
+
polling thread, subscription, observer registry or notification mechanism is added.
|
|
40
|
+
|
|
41
|
+
Unit19 pool creation and shutdown rules, cancellation, domain finalization,
|
|
42
|
+
shutdown deadlines and cached shutdown results are unchanged. Contract/domain
|
|
43
|
+
code and dependencies are unchanged. All product-code changes stay in Engine.
|
|
44
|
+
|
|
45
|
+
## Verification
|
|
46
|
+
|
|
47
|
+
A fresh-process test exercises all three observation entry points and checks that
|
|
48
|
+
no Runtime or thread is created. Tests cover partial initialization, named pools,
|
|
49
|
+
real active/queued/abandoned worker metrics, EventLoop backlog and lag, draining,
|
|
50
|
+
stopping, completed and incomplete shutdown, and default Runtime replacement.
|
|
51
|
+
Queue barriers control concurrent boundaries without relying on chance schedules.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# r8 unit21: Tool and Tracing settings ownership
|
|
2
|
+
|
|
3
|
+
This responsibility-only refactor is based on applied unit20, commit
|
|
4
|
+
`bda5da03da5a4da33041953cf0eebaa32de7bb81` (tree
|
|
5
|
+
`dc601f86825116b34ff294200815809ee9e0ea7a`). It addresses B10 from the
|
|
6
|
+
Contract review. It is not a new execution feature or a unit20 regression fix.
|
|
7
|
+
|
|
8
|
+
## Ownership
|
|
9
|
+
|
|
10
|
+
| Owner | Responsibility |
|
|
11
|
+
| --- | --- |
|
|
12
|
+
| C06 Tool | Own the default result-length value and the existing truncation rules |
|
|
13
|
+
| C15 Tracing | Own tracer access, the recording option and the existing observation/redaction rules |
|
|
14
|
+
| C05 Context | Obtain its default tracer through C15 at Assembly construction; honor explicit injection |
|
|
15
|
+
| Application composition | Select values and concrete tracers, expose the existing Configuration facade, bind lazy accessors |
|
|
16
|
+
| Neutral RuntimeSettings | Retain logger and execution resource sizes/time thresholds |
|
|
17
|
+
|
|
18
|
+
Tool::Settings contains one optional max_result_size value. Tracing::Settings
|
|
19
|
+
contains tracer and trace_pii. These private value containers have no settings
|
|
20
|
+
hierarchy, backend selection, notification service or execution resources.
|
|
21
|
+
Composition supplies them through lazy providers, following the existing Agent
|
|
22
|
+
and Workflow pattern. No Contract receives the whole application Configuration.
|
|
23
|
+
No new logical Contract is introduced merely because values are shared.
|
|
24
|
+
|
|
25
|
+
The public tool_result_max_size, tracer and trace_pii accessors keep their names,
|
|
26
|
+
defaults, writers and return values. Application choices remain application
|
|
27
|
+
choices. Tool truncation and Tracing redaction already belonged to their domains;
|
|
28
|
+
their algorithms are unchanged. Logger access remains neutral and is not moved
|
|
29
|
+
simply because Tracing also uses it for diagnostic messages.
|
|
30
|
+
|
|
31
|
+
This amends ADR-060's earlier grouping of tracer and recording options with
|
|
32
|
+
neutral runtime settings. The static graph treated that container as common;
|
|
33
|
+
its lack of reverse references did not prove that every field belonged there.
|
|
34
|
+
|
|
35
|
+
## Preserve lifecycle and read positions
|
|
36
|
+
|
|
37
|
+
- Binding providers does not evaluate global configuration or start Runtime.
|
|
38
|
+
- Tool reads its default at the existing result-processing site, after
|
|
39
|
+
synchronous execution or successful asynchronous completion. An explicit
|
|
40
|
+
class limit keeps priority and bypasses the default read. Nil and zero retain
|
|
41
|
+
their existing meanings. Result transformations retain their order and count.
|
|
42
|
+
- Automatic tracing reads settings at span start and retains the same tracer
|
|
43
|
+
and recording flag in its existing handle until finish. A configuration reset
|
|
44
|
+
during execution does not transfer an open span to a different tracer.
|
|
45
|
+
- Observation keeps its existing reads before entering the application block;
|
|
46
|
+
it does not adopt a new snapshot policy or re-read settings after the block.
|
|
47
|
+
- Context::Assembly keeps its constructor-time tracer. Explicit injection,
|
|
48
|
+
including explicit nil, does not resolve the default provider.
|
|
49
|
+
- Configuration copies duplicate the value containers and preserve injected
|
|
50
|
+
tracer/logger identities. Nested scopes, exception restoration and reset keep
|
|
51
|
+
the previous behavior. A read resolves the current container without caching.
|
|
52
|
+
|
|
53
|
+
There is no change notification, polling, version counter, cache, live resource
|
|
54
|
+
resizing or new thread-local configuration behavior. This does not add a
|
|
55
|
+
guarantee of atomic reconfiguration across several independent reads.
|
|
56
|
+
|
|
57
|
+
## Regression boundaries
|
|
58
|
+
|
|
59
|
+
Public behavior tests run unchanged on unit20 and unit21. They cover late Tool
|
|
60
|
+
limits for sync/cooperative/offloaded/deferred operations, transformation order
|
|
61
|
+
and repetition, physical completion, reset, nested scopes and tracer identity.
|
|
62
|
+
Tracing checks cover both recording policies, redaction, errors and open spans;
|
|
63
|
+
Context checks cover constructor timing and explicit injection.
|
|
64
|
+
|
|
65
|
+
Separate ownership tests inject domain values without the application facade
|
|
66
|
+
or neutral settings. Isolated loading verifies provider laziness and prevents
|
|
67
|
+
loading a concrete backend or Runtime. RBS assigns the internal declarations to
|
|
68
|
+
their actual owners. AST gates extend the application-configuration prohibition
|
|
69
|
+
to Tool, Tracing and Context, reject domain fields in neutral RuntimeSettings,
|
|
70
|
+
and reject direct or literal-reflective reads through its old accessors.
|
|
71
|
+
|
|
72
|
+
These are targeted regression guards. They do not prove arbitrary dynamic Ruby
|
|
73
|
+
dependencies. Full suite, integration, existing privacy tests, examples offline
|
|
74
|
+
verification and Ruby/RBS architecture analysis remain package validation gates.
|
|
75
|
+
The complete source/tree and validation results are recorded in the package.
|
|
76
|
+
|
|
77
|
+
Unit19/20 Engine lifecycle and passive metrics behavior remain unchanged.
|
|
78
|
+
F01 durable Workflow children remain separate feature work. There is no stored
|
|
79
|
+
data migration, public operation change or source change to examples.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# r8 unit22: MCP connection lifecycle
|
|
2
|
+
|
|
3
|
+
This change is based on applied unit21, commit
|
|
4
|
+
`4525e71ca808acac9eb0302a59c32f00478a7782` (tree
|
|
5
|
+
`957baf18c23ce5659c11454f3a89e893c07b2138`). It corrects two concrete MCP
|
|
6
|
+
lifecycle defects and removes an unnecessary application-composition reference.
|
|
7
|
+
It is not a new Contract or an Execution/Engine refactor.
|
|
8
|
+
|
|
9
|
+
## Ownership
|
|
10
|
+
|
|
11
|
+
| Owner | Responsibility |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| MCP Tool implementation | Translate SDK cancellation and results, own the client/transport, delimit one SDK call's notification lifetime |
|
|
14
|
+
| Existing Execution ResultSubscriptions | Register and remove explicit-cancellation callbacks |
|
|
15
|
+
| Existing Execution/Engine | Admit and execute cleanup work, reject submissions after shutdown, drain accepted work |
|
|
16
|
+
| Neutral RuntimeSettings | Supply the currently configured common logger |
|
|
17
|
+
|
|
18
|
+
The production change is confined to `lib/phronomy/tools/mcp.rb`. Execution,
|
|
19
|
+
Engine, Tool Contract, runtime composition, public signatures and storage
|
|
20
|
+
formats are unchanged.
|
|
21
|
+
|
|
22
|
+
## Cancellation bridge lifetime
|
|
23
|
+
|
|
24
|
+
Previously each SDK call registered a callback directly on its supplied
|
|
25
|
+
CancellationToken and retained it until that token was cancelled or collected.
|
|
26
|
+
Completed and failed calls therefore accumulated callbacks when a caller reused
|
|
27
|
+
a token. A later cancellation also touched obsolete MCP cancellation handles.
|
|
28
|
+
|
|
29
|
+
Each call now owns an existing ResultSubscriptions collection, registers its
|
|
30
|
+
bridge with explicit_cancellation, and closes the collection in ensure. This
|
|
31
|
+
also covers SDK errors, malformed responses and cleanup failures. Other
|
|
32
|
+
subscribers on the same token are preserved.
|
|
33
|
+
|
|
34
|
+
The lifetime is the concrete SDK invocation, not its caller-facing TaskResult.
|
|
35
|
+
If OffloadPool settles a timeout while SDK work is still running, a subsequent
|
|
36
|
+
explicit cancellation must still reach that work. No timer, deadline promotion,
|
|
37
|
+
polling thread or TaskResult completion callback is introduced by the bridge.
|
|
38
|
+
|
|
39
|
+
ResultSubscriptions.close does not revoke a callback already taken by a
|
|
40
|
+
concurrent cancel!. Such a callback can finish after the SDK call returns. It
|
|
41
|
+
only captures that call's MCP cancellation handle, whose cancellation is
|
|
42
|
+
idempotent; it does not look up the next client or cancel a replacement call.
|
|
43
|
+
This preserves the existing Execution notification semantics.
|
|
44
|
+
|
|
45
|
+
## Cleanup rejection at Runtime shutdown
|
|
46
|
+
|
|
47
|
+
After SDK cancellation the MCP instance detaches the old client before it can
|
|
48
|
+
be reused. Normally its transport is closed on the named Runtime cleanup pool.
|
|
49
|
+
Previously the synchronous fallback handled queue saturation and a stopped
|
|
50
|
+
pool, but not RuntimeShutdownError raised before pool acquisition. In that
|
|
51
|
+
case close was skipped and the shutdown error replaced the cancellation result.
|
|
52
|
+
|
|
53
|
+
MCP now applies its existing synchronous close fallback to RuntimeShutdownError
|
|
54
|
+
too. It does not reopen Runtime, create another worker, retry the Tool call or
|
|
55
|
+
relax Engine admission. Accepted cleanup remains owned and drained by Runtime.
|
|
56
|
+
MCP attempts to close a rejected transport and preserves the existing best-effort
|
|
57
|
+
close behavior if the SDK's close itself raises.
|
|
58
|
+
|
|
59
|
+
## Logging and validation
|
|
60
|
+
|
|
61
|
+
MCP warning output reads RuntimeSettings.current.logger once per warning and
|
|
62
|
+
retains the existing stderr fallback. It no longer reaches the application
|
|
63
|
+
Configuration facade just to obtain this common value. Logger choice is still
|
|
64
|
+
made by application configuration; no new setting or provider is introduced.
|
|
65
|
+
|
|
66
|
+
Focused regressions cover repeated success, SDK/response failures, explicit and
|
|
67
|
+
already-delivered cancellation, timeout before physical completion, cancellation
|
|
68
|
+
racing completion, accepted cleanup, stopped Runtime, rejected submission,
|
|
69
|
+
failing close and both logger paths. Concurrency tests use barriers and an
|
|
70
|
+
injected monotonic clock rather than timing-dependent sleeps.
|
|
71
|
+
|
|
72
|
+
These are lifecycle corrections, not merely file moves. They require no data
|
|
73
|
+
migration or examples source change. Deferred features, including durable
|
|
74
|
+
Workflow children, remain outside this change.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# r8 unit23: concrete consumer composition
|
|
2
|
+
|
|
3
|
+
This change is based on applied unit22, commit
|
|
4
|
+
`17cf02eb1ec0ec534b3dd8e1e64c75e13c961cfc` (tree
|
|
5
|
+
`dc591b3d8dfb1edace4f98e68f5e505a6c457f58`). It normalizes two concrete
|
|
6
|
+
composition paths identified as NC02 and NC08 in the target diagrams.
|
|
7
|
+
These were responsibility improvements, not demonstrated runtime failures.
|
|
8
|
+
|
|
9
|
+
## Agent Tool
|
|
10
|
+
|
|
11
|
+
The synchronous implementation previously called the application convenience
|
|
12
|
+
API `Agent.run_once`, which selected an ephemeral store through
|
|
13
|
+
`PersistenceComposition.agent`. Its asynchronous implementation already obtained
|
|
14
|
+
the same default through the boot-supplied `Agent::DefaultPersistence` factory.
|
|
15
|
+
|
|
16
|
+
Both paths now obtain a fresh store from that existing factory. The synchronous
|
|
17
|
+
path uses public Agent creation and invocation, preserving the explicit
|
|
18
|
+
`context: nil`, `knowledge: []`, and `on_event: nil` creation arguments that
|
|
19
|
+
`run_once` supplied. It forwards the same invocation options and converts the
|
|
20
|
+
output to a String as before. The asynchronous implementation is unchanged.
|
|
21
|
+
|
|
22
|
+
Each call still creates its own Agent and store, even when an application-level
|
|
23
|
+
Agent store is configured. No Agent or store is cached. Tool definitions and
|
|
24
|
+
instances do not acquire persistence. Cancellation propagation, asynchronous
|
|
25
|
+
config token priority, Tool validation, result transforms and recovery errors
|
|
26
|
+
retain their existing behavior.
|
|
27
|
+
|
|
28
|
+
`Agent.run_once` remains the public application convenience API. It continues to
|
|
29
|
+
own explicit composition; only the concrete Tool stops depending on that facade.
|
|
30
|
+
Calling a public composition API is not inherently invalid. Here the narrower
|
|
31
|
+
existing factory lets both Tool paths follow the same ownership boundary.
|
|
32
|
+
|
|
33
|
+
## LlmJudge
|
|
34
|
+
|
|
35
|
+
The scorer owns prompt construction, the public LLM Request, score parsing and
|
|
36
|
+
clamping, and its warning/raise policy. It no longer selects the configured
|
|
37
|
+
adapter or constructs `LLMAdapter::AsyncClient` inside `score`.
|
|
38
|
+
|
|
39
|
+
`runtime_composition/evaluation_defaults.rb` supplies a single factory during
|
|
40
|
+
normal application loading. The factory selects the currently configured
|
|
41
|
+
adapter and constructs the client. Installation creates no Configuration,
|
|
42
|
+
client or Runtime. It uses a private, one-time binding in the existing scorer
|
|
43
|
+
class, not a new Contract, module registry or application extension API.
|
|
44
|
+
|
|
45
|
+
Each score invokes the factory after prompt and Request preparation, at the
|
|
46
|
+
same point as the previous client construction. The adapter is therefore read
|
|
47
|
+
again after configuration updates, reset and scoped restoration. Neither the
|
|
48
|
+
adapter nor the client is cached by the scorer. The factory does not move client
|
|
49
|
+
construction onto a worker; the existing AsyncClient still offloads the whole
|
|
50
|
+
backend operation. No polling, notification, retry or scheduling mechanism is
|
|
51
|
+
introduced.
|
|
52
|
+
|
|
53
|
+
The constructor signature is unchanged. Subclasses inherit the same default
|
|
54
|
+
binding. Client construction/admission/provider failures remain within the
|
|
55
|
+
existing `raise_on_error` policy. Normal and eager loading remain resource-free
|
|
56
|
+
and do not load RSpec. The scorer can also be tested with an explicitly bound
|
|
57
|
+
client and its public Request dependency without loading composition or Execution.
|
|
58
|
+
|
|
59
|
+
## Boundaries and validation
|
|
60
|
+
|
|
61
|
+
| Owner | Responsibility |
|
|
62
|
+
| --- | --- |
|
|
63
|
+
| Concrete Agent Tool | Per-call Agent creation, invocation, cancellation forwarding and output conversion |
|
|
64
|
+
| Existing Agent default factory | Obtain a fresh store from the supplied boot binding |
|
|
65
|
+
| LlmJudge | Prompt, Request, score interpretation and scoring failure policy |
|
|
66
|
+
| Runtime composition | Select the configured LLM adapter and build its AsyncClient |
|
|
67
|
+
| Existing Execution and Engine | Submission, result completion, waiting and resource ownership |
|
|
68
|
+
|
|
69
|
+
Production changes are limited to the two consumers, the new composition file
|
|
70
|
+
and its explicit loader wiring. Contract source, Engine, Execution, persistence
|
|
71
|
+
formats, RBS and public API snapshots are unchanged. Examples need no source
|
|
72
|
+
change. The target diagrams remain at the applied unit22 baseline until this
|
|
73
|
+
candidate is applied; their two concrete composition items are addressed here.
|
|
74
|
+
|
|
75
|
+
Focused tests cover fresh construction and forwarding, default binding isolation,
|
|
76
|
+
score-time configuration changes, scoped restoration/reset, request/client order,
|
|
77
|
+
worker execution, failure behavior, inheritance and resource-free boot.
|
|
78
|
+
The targeted AST gate prevents either consumer from reintroducing these
|
|
79
|
+
composition dependencies; application composition itself remains permitted to
|
|
80
|
+
construct the client and public convenience API. Static graphs do not certify
|
|
81
|
+
all dynamically injected implementations or external providers.
|