phronomy 0.27.0 → 0.29.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 +52 -0
- data/CONTRIBUTING.md +8 -8
- data/README.md +28 -7
- data/benchmark/bench_agent_invoke.rb +25 -50
- data/benchmark/bench_context_assembler.rb +14 -11
- data/benchmark/bench_regression.rb +1 -1
- data/benchmark/bench_tool_schema.rb +1 -1
- data/docs/application-recipes.md +229 -0
- data/docs/architecture/agent-chat-and-state-ownership.md +7 -1
- data/docs/architecture/agent-transition-ownership.md +13 -89
- data/docs/architecture/backend-groups.md +152 -0
- data/docs/architecture/before-llm-input.md +3 -3
- data/docs/architecture/context-management.md +1 -1
- data/docs/architecture/dx05-agent-scope.md +119 -0
- data/docs/architecture/dx05-workflow-task-state.md +134 -0
- data/docs/architecture/error-api-review.md +245 -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 +6 -0
- data/docs/architecture/multi-agent-handoff.md +6 -5
- data/docs/architecture/persistence.md +27 -9
- 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 +10 -1
- data/docs/architecture/remaining-refactoring-plan.md +16 -0
- data/docs/architecture/storage-execution-boundaries.md +54 -0
- data/docs/architecture/tool-schema-recording-gap.md +6 -0
- data/docs/architecture/tracing.md +1 -1
- data/docs/architecture/workflow-terminal-ownership-design.md +2 -2
- data/docs/architecture.md +24 -11
- data/docs/decisions/015-tool-public-facade-and-rbs-boundary.md +3 -3
- data/docs/decisions/027-llm-adapter-provider-boundary.md +2 -0
- data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +2 -0
- data/docs/decisions/031-durable-multi-agent-coordination.md +2 -0
- data/docs/decisions/032-storage-backend-composition.md +5 -0
- data/docs/decisions/034-handoff-runner-coordination-ownership.md +2 -0
- data/docs/decisions/035-tool-executor-capability-ownership.md +1 -1
- data/docs/decisions/038-responsibility-based-source-layout.md +14 -0
- data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +8 -0
- data/docs/decisions/040-configuration-default-composition.md +12 -1
- data/docs/decisions/045-worker-input-restriction-ownership.md +4 -0
- data/docs/decisions/051-execution-outcome-worker-ownership.md +2 -0
- data/docs/decisions/056-workflow-terminal-policy-ownership.md +1 -1
- data/docs/decisions/058-neutral-storage-primitives.md +5 -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 +18 -1
- data/docs/execution-boundaries-preview.md +45 -0
- data/docs/failure-reason-codes.md +45 -0
- data/docs/features.md +12 -4
- data/docs/getting-started.md +52 -48
- data/docs/migrations/0.22.md +2 -2
- data/docs/migrations/durable-semantic-coordination-v2.md +2 -0
- data/docs/migrations/handoff-runner-multi-agent.md +2 -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/storage-async-client.md +103 -0
- data/docs/migrations/vector-async-clients.md +110 -0
- data/docs/ordered-event-delivery.md +54 -0
- data/docs/persistence-backends.md +38 -21
- data/docs/runtime-and-concurrency.md +26 -1
- data/docs/workflow-completion.md +92 -0
- data/gemfiles/http_minimum.gemfile +5 -0
- data/lib/phronomy/agent/admission.rb +78 -0
- data/lib/phronomy/agent/{lifecycle_contract/agent_already_exists_error.rb → agent_already_exists_error.rb} +1 -1
- data/lib/phronomy/agent/{lifecycle_contract/agent_busy_error.rb → agent_busy_error.rb} +1 -1
- data/lib/phronomy/agent/agent_not_found_error.rb +16 -0
- data/lib/phronomy/agent/{lifecycle_contract/agent_purged_error.rb → agent_purged_error.rb} +1 -1
- data/lib/phronomy/agent/agent_unloaded_error.rb +14 -0
- data/lib/phronomy/agent/api/agent.rb +13 -0
- data/lib/phronomy/{recovery → agent/api}/execution_rehydration_required_error.rb +1 -1
- data/lib/phronomy/agent/async_event_api.rb +132 -103
- data/lib/phronomy/agent/base.rb +146 -113
- data/lib/phronomy/agent/before_llm_input.rb +70 -0
- data/lib/phronomy/agent/composition/run_once.rb +1 -1
- data/lib/phronomy/agent/{context_assembly/context_candidate_resolver.rb → context_candidate_resolver.rb} +2 -2
- data/lib/phronomy/agent/{context_assembly/context_assembler.rb → context_preparation.rb} +35 -221
- data/lib/phronomy/agent/control_request.rb +21 -0
- data/lib/phronomy/agent/execution/agent_execution.rb +1 -1
- data/lib/phronomy/agent/execution/agent_invocation.rb +27 -53
- data/lib/phronomy/agent/execution/approval_resume_commit.rb +1 -1
- data/lib/phronomy/agent/execution/dispatch_preparation.rb +17 -127
- data/lib/phronomy/agent/execution/exact_execution.rb +55 -32
- data/lib/phronomy/agent/execution/execution_cancellation.rb +8 -4
- data/lib/phronomy/agent/execution/execution_coordinator.rb +229 -407
- data/lib/phronomy/agent/execution/execution_metadata.rb +1 -0
- data/lib/phronomy/agent/execution/execution_outcome_committer.rb +71 -127
- data/lib/phronomy/agent/execution/execution_registry.rb +6 -2
- data/lib/phronomy/agent/execution/execution_session_runner.rb +22 -27
- data/lib/phronomy/agent/execution/initial_preparation.rb +19 -120
- data/lib/phronomy/agent/execution/{agent_invocation_session_builder.rb → invocation_actions.rb} +54 -194
- data/lib/phronomy/agent/execution/invocation_transitions.rb +39 -1
- data/lib/phronomy/agent/execution/runtime_record_encoder.rb +8 -11
- 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 +188 -0
- data/lib/phronomy/agent/handoff/{handoff_context.rb → transfer_context.rb} +4 -4
- data/lib/phronomy/agent/handoff/{handoff_projection.rb → transfer_projection.rb} +14 -33
- data/lib/phronomy/{llm_contract/transport_error.rb → agent/handoff_error.rb} +1 -1
- data/lib/phronomy/agent/journal/journal_projection.rb +1 -1
- data/lib/phronomy/agent/knowledge_item.rb +13 -0
- data/lib/phronomy/agent/lifecycle/agent_root.rb +1 -1
- data/lib/phronomy/agent/lifecycle/lifetime_api.rb +76 -0
- data/lib/phronomy/agent/lifecycle/operation_lease.rb +33 -0
- data/lib/phronomy/agent/lifecycle/operation_result.rb +53 -0
- data/lib/phronomy/agent/lifecycle/ownership_registry.rb +117 -31
- data/lib/phronomy/agent/lifecycle/scope.rb +198 -0
- data/lib/phronomy/agent/lifecycle/scope_cleanup_error.rb +19 -0
- data/lib/phronomy/agent/lifecycle/unload_transition.rb +78 -0
- data/lib/phronomy/agent/persistence/agent_repository.rb +29 -21
- data/lib/phronomy/agent/persistence/cancellation_repository.rb +51 -0
- data/lib/phronomy/agent/persistence/codec.rb +1 -21
- data/lib/phronomy/agent/persistence/execution_repository.rb +57 -41
- data/lib/phronomy/agent/persistence/journal_repository.rb +27 -18
- 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 +7 -2
- data/lib/phronomy/agent/persistence/watermark.rb +13 -11
- data/lib/phronomy/agent/recovery/invocation_restorer.rb +13 -21
- data/lib/phronomy/agent/recovery/recovery_coordinator/continuation.rb +13 -12
- data/lib/phronomy/agent/recovery/recovery_coordinator/installation.rb +34 -34
- data/lib/phronomy/agent/recovery/recovery_coordinator/resolution.rb +33 -39
- data/lib/phronomy/agent/recovery/recovery_coordinator.rb +28 -25
- data/lib/phronomy/agent/recovery/recovery_rules.rb +119 -0
- data/lib/phronomy/agent/recovery/recovery_support.rb +10 -19
- 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/{context_assembly/ruby_llm_materializer.rb → runtime_input.rb} +18 -35
- data/lib/phronomy/agent/{context_assembly/saved_context_reader.rb → saved_context_reader.rb} +6 -4
- data/lib/phronomy/agent/settings.rb +47 -0
- data/lib/phronomy/agent/{context_assembly/state_writer.rb → state_writer.rb} +4 -3
- data/lib/phronomy/agent/store.rb +253 -0
- data/lib/phronomy/agent/{lifecycle_contract/stream_callback_error.rb → stream_callback_error.rb} +3 -3
- data/lib/phronomy/agent/tool_execution/tool_binding.rb +4 -64
- data/lib/phronomy/agent/tool_execution/tool_invocation.rb +50 -219
- 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/error.rb +65 -1
- data/lib/phronomy/configuration/runtime_settings.rb +49 -0
- data/lib/phronomy/content_store/base.rb +7 -2
- data/lib/phronomy/content_store/storage_schema.rb +1 -0
- data/lib/phronomy/content_store/stored_contents.rb +2 -1
- data/lib/phronomy/context/assembly.rb +195 -0
- data/lib/phronomy/{llm_contract/context_budget_exceeded_error.rb → context/budget_exceeded_error.rb} +3 -1
- data/lib/phronomy/context/candidate.rb +51 -0
- data/lib/phronomy/context/constraint.rb +47 -0
- data/lib/phronomy/{agent/context_contract → context}/context_plan.rb +1 -1
- data/lib/phronomy/{agent/context_contract → context}/context_plan_validator.rb +3 -3
- data/lib/phronomy/{agent/context_contract → context}/context_policy.rb +1 -1
- data/lib/phronomy/{agent/context_contract → context}/context_policy_input.rb +1 -1
- data/lib/phronomy/{agent/context_assembly → 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_contract → context}/llm_input_build_context.rb +1 -1
- data/lib/phronomy/{agent/context_contract → context}/llm_input_manifest.rb +19 -19
- data/lib/phronomy/{agent/context_contract → context}/llm_input_patch.rb +1 -1
- 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/authentication_error.rb +11 -0
- data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +52 -0
- data/lib/phronomy/embeddings/base.rb +43 -0
- data/lib/phronomy/embeddings/invalid_result_error.rb +11 -0
- data/lib/phronomy/embeddings/rate_limit_error.rb +11 -0
- data/lib/phronomy/embeddings/transport_error.rb +11 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +36 -21
- data/lib/phronomy/engine/concurrency/pool_registry.rb +47 -12
- data/lib/phronomy/engine/diagnostics.rb +1 -1
- data/lib/phronomy/engine/event_loop.rb +7 -7
- 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 +1 -6
- data/lib/phronomy/engine/fsm_session.rb +3 -3
- data/lib/phronomy/engine/metrics.rb +16 -14
- data/lib/phronomy/engine/runtime/timer_queue.rb +1 -1
- data/lib/phronomy/engine/runtime.rb +25 -12
- data/lib/phronomy/engine/terminal_decision.rb +7 -0
- data/lib/phronomy/execution/async_operation.rb +41 -0
- data/lib/phronomy/{engine → execution}/blocking.rb +2 -2
- data/lib/phronomy/{engine → execution}/concurrency/cancellation_token.rb +1 -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/{engine → execution}/execution.rb +61 -27
- data/lib/phronomy/{engine → execution}/execution_cancellation_error.rb +2 -2
- data/lib/phronomy/execution/execution_receiver.rb +78 -0
- data/lib/phronomy/execution/execution_scope_state.rb +35 -0
- data/lib/phronomy/{engine → execution}/execution_timeout_error.rb +2 -2
- data/lib/phronomy/{engine → execution}/invocation_context.rb +0 -15
- data/lib/phronomy/execution/invocation_controls.rb +73 -0
- data/lib/phronomy/execution/runnable.rb +24 -0
- data/lib/phronomy/{engine → execution}/task_result.rb +9 -4
- data/lib/phronomy/execution/wait_policy.rb +24 -0
- data/lib/phronomy/filter/{contract/filter_block_error.rb → filter_block_error.rb} +3 -3
- data/lib/phronomy/generation/generator_verifier/agent_operation.rb +65 -0
- data/lib/phronomy/generation/generator_verifier/default_parser.rb +27 -0
- data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +2 -2
- data/lib/phronomy/generation/generator_verifier.rb +7 -7
- data/lib/phronomy/generation/low_confidence_error.rb +2 -2
- data/lib/phronomy/integrations/ordered_event_delivery.rb +208 -0
- data/lib/phronomy/llm_adapter/async/async_client.rb +47 -0
- data/lib/phronomy/{llm_contract → llm_adapter}/authentication_error.rb +3 -1
- data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +183 -0
- data/lib/phronomy/llm_adapter/base.rb +49 -68
- data/lib/phronomy/{llm_contract → llm_adapter}/context_length_error.rb +3 -1
- data/lib/phronomy/llm_adapter/invalid_result_error.rb +10 -0
- data/lib/phronomy/llm_adapter/message.rb +62 -0
- data/lib/phronomy/{llm_contract → llm_adapter}/rate_limit_error.rb +3 -1
- 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/multi_agent/admission_registry.rb +1 -8
- 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/handoff → multi_agent}/handoff.rb +2 -2
- data/lib/phronomy/{agent/handoff → multi_agent}/handoff_capability_factory.rb +21 -2
- data/lib/phronomy/multi_agent/handoff_participant.rb +79 -0
- data/lib/phronomy/{agent/handoff → multi_agent}/handoff_policy.rb +1 -1
- data/lib/phronomy/multi_agent/handoff_runner.rb +77 -100
- data/lib/phronomy/{agent/handoff → multi_agent}/handoff_state.rb +1 -1
- data/lib/phronomy/multi_agent/orchestrator.rb +61 -75
- data/lib/phronomy/multi_agent/persistence/codec.rb +20 -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 +60 -44
- data/lib/phronomy/multi_agent/persistence/team_repository.rb +29 -21
- 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/multi_agent/shared_state.rb +2 -2
- data/lib/phronomy/multi_agent/store.rb +156 -0
- data/lib/phronomy/multi_agent/team_busy_error.rb +18 -0
- data/lib/phronomy/multi_agent/team_coordinator.rb +99 -77
- data/lib/phronomy/multi_agent/team_not_found_error.rb +18 -0
- data/lib/phronomy/multi_agent/team_ownership_registry.rb +2 -12
- 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 +2 -2
- 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 +9 -4
- 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 +5 -1
- data/lib/phronomy/runtime_composition/configuration.rb +146 -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/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 +8 -2
- data/lib/phronomy/storage/condition_failed_error.rb +2 -2
- data/lib/phronomy/storage/unique_constraint_error.rb +2 -2
- 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 +2 -2
- data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +6 -6
- data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +55 -52
- data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +3 -3
- data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +7 -7
- data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +11 -11
- data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +57 -51
- data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +23 -22
- data/lib/phronomy/tool/authorization.rb +77 -0
- data/lib/phronomy/tool/base.rb +551 -9
- data/lib/phronomy/tool/call_request.rb +40 -0
- data/lib/phronomy/{agent/tool_execution/tool_definition_set.rb → tool/definition_set.rb} +7 -8
- 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/tool/tool_executor.rb +58 -0
- 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 +36 -7
- data/lib/phronomy/tracing/observation.rb +37 -0
- data/lib/phronomy/tracing/open_telemetry_tracer.rb +4 -29
- 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/execution/workflow.rb +37 -9
- data/lib/phronomy/workflow/execution/workflow_action_rules.rb +67 -0
- data/lib/phronomy/workflow/execution/workflow_context.rb +2 -2
- data/lib/phronomy/workflow/execution/workflow_execution_environment.rb +28 -0
- data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +77 -8
- data/lib/phronomy/workflow/execution/workflow_runner.rb +105 -92
- data/lib/phronomy/workflow/execution/workflow_settings.rb +28 -0
- data/lib/phronomy/workflow/execution/workflow_task_execution.rb +153 -0
- data/lib/phronomy/workflow/execution/workflow_task_reception.rb +72 -0
- data/lib/phronomy/workflow/execution/workflow_task_resume_error.rb +14 -0
- data/lib/phronomy/workflow/persistence/state_repository.rb +28 -22
- data/lib/phronomy/workflow/persistence/storage_schema.rb +13 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_engine_environment.rb +61 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_phase_machine_builder.rb +158 -0
- data/lib/phronomy/workflow/runtime_binding/workflow_task_session.rb +76 -0
- data/lib/phronomy/workflow/{execution → runtime_binding}/workflow_terminal_policy.rb +4 -4
- data/lib/phronomy.rb +63 -16
- data/scripts/api_snapshot.rb +47 -15
- data/scripts/check_readme_ruby.rb +24 -29
- data/scripts/check_readme_runnable.rb +92 -81
- 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/agent_not_found_error.rbs +6 -0
- data/sig/phronomy/agent/agent_unloaded_error.rbs +6 -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/stream_callback_error.rbs +8 -0
- data/sig/phronomy/agent.rbs +29 -135
- 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 +23 -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 +1 -21
- data/sig/phronomy/filter/filter_block_error.rbs +6 -0
- data/sig/phronomy/generation/low_confidence_error.rbs +6 -0
- data/sig/phronomy/handoff.rbs +10 -4
- data/sig/phronomy/integrations.rbs +14 -0
- 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/team_busy_error.rbs +8 -0
- data/sig/phronomy/multi_agent/team_not_found_error.rbs +8 -0
- data/sig/phronomy/multi_agent.rbs +6 -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 +1 -99
- 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.rbs → storage/contracts.rbs} +4 -18
- data/sig/phronomy/tool.rbs +48 -4
- 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 +15 -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 +5 -1
- data/sig/phronomy.rbs +4 -49
- metadata +365 -117
- 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 -548
- data/lib/phronomy/agent/context/capability/tool_executor.rb +0 -62
- data/lib/phronomy/agent/context/instruction/prompt_template.rb +0 -102
- data/lib/phronomy/agent/context_assembly/runtime_chat_builder.rb +0 -36
- data/lib/phronomy/agent/context_assembly/token_budget_resolver.rb +0 -22
- 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/phase_machine_builder.rb +0 -101
- data/lib/phronomy/agent/execution/provider_call_outcome.rb +0 -106
- data/lib/phronomy/agent/handoff/handoff_execution_coordinator.rb +0 -15
- data/lib/phronomy/agent/handoff/handoff_outcome_committer.rb +0 -131
- data/lib/phronomy/agent/handoff/handoff_request.rb +0 -45
- data/lib/phronomy/agent/lifecycle_contract/handoff_error.rb +0 -7
- data/lib/phronomy/agent/persistence/handoff_state_repository.rb +0 -58
- data/lib/phronomy/agent/persistence/queries.rb +0 -61
- data/lib/phronomy/agent/selection/candidate.rb +0 -53
- data/lib/phronomy/agent/selection/constraint.rb +0 -49
- data/lib/phronomy/agent/tool_execution/tool_call_intercepted.rb +0 -29
- data/lib/phronomy/agent/tool_execution/tool_invocation_session_builder.rb +0 -276
- data/lib/phronomy/configuration/configuration.rb +0 -68
- data/lib/phronomy/configuration/global_configuration.rb +0 -26
- data/lib/phronomy/engine/concurrency/cancellation_scope.rb +0 -124
- data/lib/phronomy/engine/concurrency/operation_binding.rb +0 -43
- data/lib/phronomy/engine/execution_receiver.rb +0 -65
- data/lib/phronomy/engine/runnable.rb +0 -54
- data/lib/phronomy/llm_adapter/ruby_llm.rb +0 -47
- data/lib/phronomy/llm_contract/token_usage.rb +0 -85
- data/lib/phronomy/multi_agent/persistence/queries.rb +0 -30
- data/lib/phronomy/multi_agent/storage_contract/team_storage_schema.rb +0 -15
- data/lib/phronomy/output_parser/contract/parse_error.rb +0 -7
- data/lib/phronomy/persistence/api/persistence.rb +0 -140
- data/lib/phronomy/persistence_composition/repositories.rb +0 -77
- data/lib/phronomy/recovery/recovery.rb +0 -186
- data/lib/phronomy/tool/contract/tool_error.rb +0 -7
- 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/storage_contract/workflow_storage_schema.rb +0 -9
- data/sig/phronomy/execution_receiver.rbs +0 -34
- data/sig/phronomy/llm_adapter.rbs +0 -11
- data/sig/phronomy/runtime.rbs +0 -76
- /data/lib/phronomy/agent/{context_assembly/context_importer.rb → context_importer.rb} +0 -0
- /data/lib/phronomy/{engine → execution}/backpressure_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/cancellation_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/concurrency/worker_input_restricted.rb +0 -0
- /data/lib/phronomy/{engine → execution}/event_loop_reentrancy_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/invalid_async_entry_action_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/invalid_async_transition_action_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/invalid_async_workflow_action_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/pool_shutdown_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/recursion_limit_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/runtime_shutdown_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/runtime_shutdown_reentrancy_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/scheduler_reentrancy_error.rb +0 -0
- /data/lib/phronomy/{engine → execution}/timeout_error.rb +0 -0
|
@@ -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.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# r8 unit 3: Persistence ownership and Team/Agent operations
|
|
2
|
+
|
|
3
|
+
This is a candidate based on core `a82974a7fd2360a13af71831a0c3ddc75942fae3`
|
|
4
|
+
and examples `70b7244c9f6542062849869a7106c5a627868a80`. It implements P01 and
|
|
5
|
+
removes concrete adapter selection from the unit 2 admission framework. P04 is
|
|
6
|
+
partially implemented for Team authorization and scheduling. It is not completion
|
|
7
|
+
of the full contract architecture.
|
|
8
|
+
|
|
9
|
+
## Ownership and public application construction
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
stores = Phronomy::PersistenceComposition.in_memory
|
|
13
|
+
# Or: PersistenceComposition.build(backend: configured_storage_backend)
|
|
14
|
+
|
|
15
|
+
Phronomy.configure do |config|
|
|
16
|
+
config.agent_store = stores.agent
|
|
17
|
+
config.team_store = stores.team
|
|
18
|
+
config.workflow_store = stores.workflow
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
agent = MyAgent.create(persistence: stores.agent)
|
|
22
|
+
team = MyTeam.create(persistence: stores.team)
|
|
23
|
+
workflow = Phronomy::Workflow.define(MyContext, persistence: stores.workflow) do
|
|
24
|
+
# Workflow definition
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
agent_result = stores.agent.result(agent_execution_id)
|
|
28
|
+
team_result = stores.team.result(team_execution_id)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
For an isolated Agent, `PersistenceComposition.agent(backend: optional_backend)`
|
|
32
|
+
constructs only the Agent/content components. Ordinary Agent defaults use this
|
|
33
|
+
factory. A composition result is a construction bundle, not a query or execution
|
|
34
|
+
service; pass only the relevant component to each consumer.
|
|
35
|
+
|
|
36
|
+
| Owner | Operation / responsibility |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `Persistence` | `atomic`, scope validity, participation and outer commit |
|
|
39
|
+
| `Agent::Store` | Agent result/list/presence/authorization operations, injected Agent record protocol |
|
|
40
|
+
| `MultiAgent::Store` | Team result/list operations, injected Team record protocol and Agent public operations |
|
|
41
|
+
| Workflow checkpoint port | `load`, `save`, `delete` with instance ID and expected revision |
|
|
42
|
+
| Domain `persistence/` implementations | physical resource schema, records, codecs and guards |
|
|
43
|
+
| `PersistenceComposition` | selects backend and adapters, validates schemas and binds components |
|
|
44
|
+
|
|
45
|
+
The stores are roles inside the existing domain framework, not new independent
|
|
46
|
+
contracts. Logical acceptance and state-transition decisions remain in Admission,
|
|
47
|
+
TeamCoordinator, and the owning domain operations. Record accessors on stores are
|
|
48
|
+
internal protocols for their own domain, not cross-domain application APIs.
|
|
49
|
+
Common Persistence neither knows these types nor imports composition.
|
|
50
|
+
|
|
51
|
+
## Atomic participation remains unchanged
|
|
52
|
+
|
|
53
|
+
The parent reservation is committed first. At child acceptance, the parent guard
|
|
54
|
+
is acquired before reading the current reservation, then Agent input/execution
|
|
55
|
+
and root revision are written in that same scope. The parent's domain owns its
|
|
56
|
+
reservation/cancellation/identity checks. Agent does not interpret parent schemas.
|
|
57
|
+
Only after the outer commit does Agent expose its accepted state and start work.
|
|
58
|
+
|
|
59
|
+
Domain adapters are injected at construction and receive the exact scope's view.
|
|
60
|
+
They never select another connection or commit independently. The coordinator
|
|
61
|
+
identity, same-thread lifetime, savepoint behavior, conflict classification,
|
|
62
|
+
rollback, and uncertain-commit behavior remain in force. LLM/Tool work and async
|
|
63
|
+
waiting remain outside these short transactions. Wrapping ordinary async invoke
|
|
64
|
+
in an application transaction is not a newly supported API.
|
|
65
|
+
|
|
66
|
+
## Team uses Agent authorization, not execution metadata
|
|
67
|
+
|
|
68
|
+
`Agent::Store#authorized_operations(scope, agent_id:, execution_id:,
|
|
69
|
+
invocation_id:, name:, arguments:, names:)` validates the exact requested call
|
|
70
|
+
against one persisted execution snapshot in the caller's scope. It checks the
|
|
71
|
+
Agent owner, invocation identity, authorization state, name, arguments and
|
|
72
|
+
requested operation family. It returns immutable `AuthorizedOperation` values
|
|
73
|
+
with only `invocation_id`, `name`, and `arguments`, in Provider order.
|
|
74
|
+
|
|
75
|
+
Team applies these operations and owns its durable operation-result ledger.
|
|
76
|
+
A committed replay returns that ledger result without reapplying the batch.
|
|
77
|
+
`finalize` cannot overtake earlier authorized `enqueue_task` calls. A mismatch
|
|
78
|
+
raises `Persistence::StateConflictError` before Team's changes commit.
|
|
79
|
+
`Agent::Store#exist?` reports authoritative absence; failed reads still raise.
|
|
80
|
+
|
|
81
|
+
Team scheduling now uses its own retained assignment count. The default chooses
|
|
82
|
+
the worker with the fewest assignments, breaking ties in worker order. Custom
|
|
83
|
+
schedulers receive `WorkerState#assignment_count` instead of `transcript_size`.
|
|
84
|
+
The count is derived from existing assignments, including failures; there is no
|
|
85
|
+
extra mutable counter and no Agent journal read. This deliberately changes the
|
|
86
|
+
default balancing metric. It does not estimate tokens, duration or resource load.
|
|
87
|
+
|
|
88
|
+
## Removed APIs and directories
|
|
89
|
+
|
|
90
|
+
- `Persistence.in_memory`, common `transaction`, `capabilities`, repository
|
|
91
|
+
accessors, result/list queries and Agent watermark facade methods are removed.
|
|
92
|
+
`Persistence.new(backend:)` constructs only the neutral coordinator.
|
|
93
|
+
- Domain result queries are `stores.agent.result` / `.runs` and
|
|
94
|
+
`stores.team.result` / `.runs`; Handoff observation remains on the Agent store
|
|
95
|
+
pending the ownership work below.
|
|
96
|
+
- `Configuration#persistence` is replaced by `agent_store`, `team_store`, and
|
|
97
|
+
`workflow_store`; explicit `persistence:` arguments accept the relevant port.
|
|
98
|
+
- The all-domain `PersistenceComposition::Repositories` and the fixed admission
|
|
99
|
+
adapter classes are deleted. There are no legacy API aliases.
|
|
100
|
+
- `persistence/api/` and the six-file `persistence/contract/` error subdivision
|
|
101
|
+
are removed. Shared failures are in `persistence/errors.rb`.
|
|
102
|
+
- Team/Workflow schema declarations are consolidated into their existing domain
|
|
103
|
+
`persistence/` directories; their separate `storage_contract/` directories and
|
|
104
|
+
root schema constants are removed.
|
|
105
|
+
|
|
106
|
+
Storage SPI 2 and physical SQL tables/indexes are unchanged. Existing Agent,
|
|
107
|
+
Handoff and Workflow record codecs are unchanged. New Team worker entries omit
|
|
108
|
+
`transcript_size`; older entries can still be decoded and the unused field is
|
|
109
|
+
ignored by scheduling. Assignment history remains the authority. This does not
|
|
110
|
+
add an API compatibility wrapper or change saved operation results.
|
|
111
|
+
|
|
112
|
+
## Remaining work (explicitly not claimed complete)
|
|
113
|
+
|
|
114
|
+
1. Subagent and Handoff still interpret Agent execution/routing records and
|
|
115
|
+
coordination data. Storage adapter class selection has been removed, but
|
|
116
|
+
renaming raw record access does not make it a proper public domain operation.
|
|
117
|
+
Resolve logical ownership, cancellation, responsibility transfer and restart
|
|
118
|
+
together before changing these paths; existing atomic transfer is preserved.
|
|
119
|
+
2. Orchestrator's preparation/resume integration still accesses Agent-owned
|
|
120
|
+
execution and context details. Team's new operation projection is not a
|
|
121
|
+
general solution to those ownership questions.
|
|
122
|
+
3. Domain-to-FSM connections, durable Workflow child protocols, multi-record
|
|
123
|
+
uncertain-commit evidence and the remaining semantic dependency review are
|
|
124
|
+
outside this implementation unit. Workflow FINISH translation already exists.
|
|
125
|
+
4. PostgreSQL concurrency verification for this candidate requires the matching
|
|
126
|
+
core/examples branch or local PostgreSQL setup. Unit 2 CI evidence is not
|
|
127
|
+
evidence that this candidate has passed PostgreSQL.
|
|
128
|
+
|
|
129
|
+
The source SVG and full Ruby/RBS evidence report remaining dependencies. Visual
|
|
130
|
+
suppression of shared common-value arrows does not remove graph evidence.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# r8 unit 4: Agent execution and MultiAgent responsibility
|
|
2
|
+
|
|
3
|
+
Core baseline: `3c5fddcae31cc98f8e081feae9b955cf536e5834`.
|
|
4
|
+
Examples baseline: `0370d09fb1608b9596e1803275f713b1a204af26`.
|
|
5
|
+
The foundation mapping dated 2026-09-30 and its target/concept diagrams remain the
|
|
6
|
+
refactoring goal. This change implements the C01/C04 boundary; it does not claim
|
|
7
|
+
that the whole existing implementation already matches the target DAG.
|
|
8
|
+
|
|
9
|
+
| Responsibility | Owner and current entry point |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Exact execution identity, admission and observation | Agent `ReservedExecution`, `start_reserved_async`, `resume_async`, `cancel_async`, `Store#observe_execution` |
|
|
12
|
+
| Finalized input, groups and provenance | Agent `ControlRequest`, `TransferContext`, `TransferProjection` with Context assembly |
|
|
13
|
+
| Selection policy, Source/Target mapping and routing | MultiAgent `HandoffPolicy`, capability binding, `HandoffRunner`, `HandoffParticipant` |
|
|
14
|
+
| Static subagent slot, definition, input, inherited knowledge and import progress | MultiAgent `DurableSubagentCoordinator`; immutable content snapshot |
|
|
15
|
+
| Execution/Root/journal mutation and publication authority | Agent `ExecutionChange` and `ExecutionOutcomeCommitter` |
|
|
16
|
+
| Whole-Agent retention and durable cancellation intent | Agent public operations; Agent-owned record resources |
|
|
17
|
+
| History removal and release of its own holds | MultiAgent `Store#forget_subagents`, `Store#forget_handoff` |
|
|
18
|
+
| Physical record adapters and schema | Each domain's Persistence implementation; composition assembles them |
|
|
19
|
+
| Offline old-format conversion | `PersistenceComposition::Unit4Migration`; examples SQL runner |
|
|
20
|
+
|
|
21
|
+
Agent interprets neither child states nor routing phases. MultiAgent uses public
|
|
22
|
+
Agent values and operations; it does not read AgentExecution, raw metadata,
|
|
23
|
+
journals, ContextImporter values or a private event-listener getter. Child results
|
|
24
|
+
are observed from their authoritative execution, never mirrored as mutable child
|
|
25
|
+
statuses in the parent snapshot. IDs for new slots are derived from canonical
|
|
26
|
+
parent Agent/execution/slot identity. Migration preserves existing IDs.
|
|
27
|
+
|
|
28
|
+
## Commit participant contract
|
|
29
|
+
|
|
30
|
+
A current, synchronous participant declares a `binding` key/version and implements
|
|
31
|
+
`commit`, `guard_change`, and `change_evidence`. `ExecutionChange` exposes semantic
|
|
32
|
+
inputs only. In one outer `Persistence#atomic` scope the participant:
|
|
33
|
+
|
|
34
|
+
1. Locks routing/Team guards where needed, then Agent roots in lexical ID order.
|
|
35
|
+
2. Calls `change.prepare_in(scope)` before its own writes. This captures complete
|
|
36
|
+
pre-state, including cancellation intent, under those guards.
|
|
37
|
+
3. Changes its own records and calls `change.commit_in(scope, state:, transfer_receipt:, pending:)` once.
|
|
38
|
+
4. Returns after the outer commit. Agent publishes the captured result only then.
|
|
39
|
+
|
|
40
|
+
The change is bound to the original thread, coordinator and prepared scope. It
|
|
41
|
+
checks its Agent watermark and expected execution revision. A nested savepoint
|
|
42
|
+
cannot authorize publication. Reconciliation compares Root, execution payload,
|
|
43
|
+
appended journal, extension content, cancellation intent, and participant evidence
|
|
44
|
+
in a consistent scope. Exact post-state proves commit; exact pre-state proves no
|
|
45
|
+
commit; different state or failed reads require recovery. There is no write retry.
|
|
46
|
+
An updated record at the expected revision alone is insufficient evidence.
|
|
47
|
+
|
|
48
|
+
Subagent cancellation retains unresolved active work. Known business errors may
|
|
49
|
+
follow `on_error: :skip`; unknown external outcomes cannot be skipped into success.
|
|
50
|
+
Handoff Source transfer and Target terminal stabilization join the same Agent
|
|
51
|
+
change. A suspended or recovery-required Target does not stabilize routing.
|
|
52
|
+
Current participant key/version and Target definition must match before resuming.
|
|
53
|
+
Terminal results can still be read without re-creating application wiring.
|
|
54
|
+
|
|
55
|
+
## Retention and cancellation
|
|
56
|
+
|
|
57
|
+
`agent.retentions` prevents purge independently of MultiAgent schema. C01 records
|
|
58
|
+
its parent/child or conversation holds when reserving/creating work. History
|
|
59
|
+
removal checks unfinished work, removes its references and releases only its own
|
|
60
|
+
owner key in the same transaction. Other holds remain authoritative.
|
|
61
|
+
`agent.cancellations` stores monotonic intent separately from execution revision,
|
|
62
|
+
so an external cancel does not invalidate an in-flight worker's captured revision.
|
|
63
|
+
Signal delivery follows the durable write; restored executions read that intent.
|
|
64
|
+
|
|
65
|
+
`Agent::Admission` remains the same-scope acceptance boundary. A participant never
|
|
66
|
+
starts a child inside a transaction or waits for its lifetime on a worker thread.
|
|
67
|
+
Ordinary Agent composition does not load MultiAgent routing repositories.
|
|
68
|
+
Standalone `dispatch_parallel` keeps its existing Runtime-scoped behavior.
|
|
69
|
+
|
|
70
|
+
## Remaining boundaries
|
|
71
|
+
|
|
72
|
+
`MultiAgent::AdmissionRegistry` still uses Runtime shutdown coordination. Agent,
|
|
73
|
+
Tool and Workflow execution internals still depend on existing Engine mechanisms.
|
|
74
|
+
These are later r8 work, not erased by constructor injection or diagram grouping.
|
|
75
|
+
The measured source diagram includes those edges and cycles. PostgreSQL lock
|
|
76
|
+
ordering needs its actual database gate; SQLite/InMemory results do not establish
|
|
77
|
+
PostgreSQL behavior. The application package records executed and unexecuted gates.
|
|
78
|
+
|
|
79
|
+
See [API and saved-data migration](../migrations/r8-unit4.md).
|