phronomy 0.25.0 → 0.27.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/CHANGELOG.md +71 -0
- data/CONTRIBUTING.md +4 -4
- data/README.md +14 -7
- data/VERIFY.sh +27 -27
- data/benchmark/bench_agent_invoke.rb +26 -22
- data/benchmark/bench_context_assembler.rb +4 -5
- data/benchmark/bench_regression.rb +1 -1
- data/docs/architecture/agent-chat-and-state-ownership.md +147 -0
- data/docs/architecture/agent-configuration-and-tool-binding.md +139 -0
- data/docs/architecture/agent-context.md +5 -3
- data/docs/architecture/agent-transition-ownership.md +89 -0
- data/docs/architecture/before-llm-input.md +6 -0
- data/docs/architecture/context-management.md +30 -0
- data/docs/architecture/context-preparation-steps.md +90 -0
- data/docs/architecture/entry-action-and-team-wording.md +72 -0
- data/docs/architecture/execution-metadata-and-values.md +80 -0
- data/docs/architecture/generator-verifier-ownership.md +111 -0
- data/docs/architecture/multi-agent-handoff.md +8 -2
- data/docs/architecture/persistence-refactoring-plan.md +50 -0
- data/docs/architecture/persistence.md +29 -6
- data/docs/architecture/refactoring-closure.md +334 -0
- data/docs/architecture/remaining-refactoring-plan.md +374 -0
- data/docs/architecture/rubyllm-2-token-ownership.md +82 -0
- data/docs/architecture/tool-schema-recording-gap.md +50 -0
- data/docs/architecture/tracing.md +4 -4
- data/docs/architecture/workflow-terminal-ownership-design.md +104 -0
- data/docs/architecture.md +209 -0
- data/docs/async-composition.md +205 -0
- data/docs/decisions/010-cooperative-first-concurrency.md +23 -23
- data/docs/decisions/014-unified-persistence-durable-state.md +11 -0
- 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/030-agent-handoff-domain-and-durable-responsibility.md +5 -0
- data/docs/decisions/031-durable-multi-agent-coordination.md +5 -0
- data/docs/decisions/032-storage-backend-composition.md +80 -0
- data/docs/decisions/033-domain-persistence-ownership.md +79 -0
- data/docs/decisions/034-handoff-runner-coordination-ownership.md +76 -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 +131 -0
- data/docs/decisions/039-runtime-configuration-lifecycle-ownership.md +74 -0
- data/docs/decisions/040-configuration-default-composition.md +94 -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 +100 -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 +151 -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 +78 -0
- data/docs/decisions/README.md +35 -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/features.md +21 -12
- data/docs/getting-started.md +10 -10
- data/docs/migrations/0.15.md +5 -0
- data/docs/migrations/durable-semantic-coordination-v2.md +7 -1
- data/docs/migrations/handoff-runner-multi-agent.md +35 -0
- data/docs/migrations/neutral-storage-spi.md +43 -0
- data/docs/migrations/parallel-tool-chat-removal.md +49 -0
- data/docs/migrations/shared-state-multi-agent.md +44 -0
- data/docs/migrations/storage-backend-composition.md +117 -0
- data/docs/migrations/storage-transaction-boundaries.md +74 -0
- data/docs/persistence-backends.md +162 -204
- data/docs/runtime-and-concurrency.md +205 -60
- data/lib/phronomy/agent/api/agent.rb +17 -0
- data/lib/phronomy/agent/async_event_api.rb +2 -2
- data/lib/phronomy/agent/base.rb +55 -251
- data/lib/phronomy/{agent.rb → agent/composition/run_once.rb} +4 -13
- data/lib/phronomy/agent/context/capability/base.rb +67 -26
- data/lib/phronomy/agent/context/capability/tool_executor.rb +62 -0
- data/lib/phronomy/agent/{context_assembler.rb → context_assembly/context_assembler.rb} +143 -88
- data/lib/phronomy/agent/{context_importer.rb → context_assembly/context_importer.rb} +2 -2
- data/lib/phronomy/agent/{ruby_llm_materializer.rb → context_assembly/ruby_llm_materializer.rb} +4 -7
- data/lib/phronomy/agent/context_assembly/runtime_chat_builder.rb +36 -0
- data/lib/phronomy/agent/context_assembly/saved_context_reader.rb +53 -0
- data/lib/phronomy/agent/context_assembly/state_writer.rb +165 -0
- data/lib/phronomy/agent/context_assembly/token_budget_resolver.rb +22 -0
- data/lib/phronomy/agent/{context_plan.rb → context_contract/context_plan.rb} +1 -1
- data/lib/phronomy/agent/{context_policy_input.rb → context_contract/context_policy_input.rb} +6 -6
- data/lib/phronomy/agent/{llm_input_build_context.rb → context_contract/llm_input_build_context.rb} +1 -1
- data/lib/phronomy/agent/{llm_input_manifest.rb → context_contract/llm_input_manifest.rb} +20 -20
- data/lib/phronomy/agent/{llm_input_patch.rb → context_contract/llm_input_patch.rb} +2 -2
- data/lib/phronomy/agent/{agent_execution.rb → execution/agent_execution.rb} +8 -4
- data/lib/phronomy/agent/{agent_invocation.rb → execution/agent_invocation.rb} +8 -13
- data/lib/phronomy/agent/{agent_invocation_session_builder.rb → execution/agent_invocation_session_builder.rb} +20 -96
- data/lib/phronomy/agent/execution/approval_resume_commit.rb +108 -0
- data/lib/phronomy/agent/execution/dispatch_preparation.rb +305 -0
- data/lib/phronomy/agent/{exact_execution.rb → execution/exact_execution.rb} +12 -13
- data/lib/phronomy/agent/{execution_cancellation.rb → execution/execution_cancellation.rb} +2 -3
- data/lib/phronomy/agent/execution/execution_coordinator.rb +1925 -0
- data/lib/phronomy/agent/execution/execution_failure.rb +30 -0
- data/lib/phronomy/agent/execution/execution_metadata.rb +53 -0
- data/lib/phronomy/agent/execution/execution_outcome_committer.rb +344 -0
- data/lib/phronomy/agent/execution/execution_registry.rb +459 -0
- data/lib/phronomy/agent/execution/execution_session_runner.rb +118 -0
- data/lib/phronomy/agent/execution/initial_preparation.rb +421 -0
- data/lib/phronomy/agent/execution/invocation_transitions.rb +86 -0
- data/lib/phronomy/agent/{phase_machine_builder.rb → execution/phase_machine_builder.rb} +22 -73
- data/lib/phronomy/agent/{provider_call_outcome.rb → execution/provider_call_outcome.rb} +9 -9
- data/lib/phronomy/agent/execution/runtime_record_encoder.rb +210 -0
- data/lib/phronomy/agent/{handoff_context.rb → handoff/handoff_context.rb} +2 -2
- data/lib/phronomy/agent/handoff/handoff_execution_coordinator.rb +15 -0
- data/lib/phronomy/agent/handoff/handoff_outcome_committer.rb +131 -0
- data/lib/phronomy/agent/{handoff_state.rb → handoff/handoff_state.rb} +1 -1
- 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/{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 -10
- data/lib/phronomy/{agent_already_exists_error.rb → agent/lifecycle_contract/agent_already_exists_error.rb} +2 -0
- data/lib/phronomy/{agent_busy_error.rb → agent/lifecycle_contract/agent_busy_error.rb} +2 -0
- data/lib/phronomy/{agent_purged_error.rb → agent/lifecycle_contract/agent_purged_error.rb} +2 -0
- data/lib/phronomy/agent/lifecycle_contract/handoff_error.rb +7 -0
- data/lib/phronomy/{stream_callback_error.rb → agent/lifecycle_contract/stream_callback_error.rb} +2 -0
- data/lib/phronomy/agent/persistence/agent_repository.rb +61 -0
- data/lib/phronomy/agent/persistence/codec.rb +358 -0
- data/lib/phronomy/agent/persistence/execution_repository.rb +108 -0
- data/lib/phronomy/agent/persistence/handoff_state_repository.rb +58 -0
- data/lib/phronomy/agent/persistence/journal_repository.rb +54 -0
- data/lib/phronomy/agent/persistence/queries.rb +61 -0
- data/lib/phronomy/agent/persistence/storage_schema.rb +24 -0
- data/lib/phronomy/agent/persistence/watermark.rb +27 -0
- data/lib/phronomy/agent/recovery/invocation_restorer.rb +132 -0
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/continuation.rb +21 -45
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/installation.rb +36 -41
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/resolution.rb +37 -40
- data/lib/phronomy/agent/{recovery_coordinator.rb → recovery/recovery_coordinator.rb} +9 -13
- data/lib/phronomy/agent/recovery/recovery_support.rb +227 -0
- data/lib/phronomy/agent/selection/candidate.rb +1 -1
- 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 +90 -0
- data/lib/phronomy/agent/{tool_call_intercepted.rb → tool_execution/tool_call_intercepted.rb} +2 -2
- data/lib/phronomy/agent/{tool_definition_set.rb → tool_execution/tool_definition_set.rb} +9 -4
- data/lib/phronomy/agent/{tool_invocation.rb → tool_execution/tool_invocation.rb} +69 -34
- data/lib/phronomy/agent/{tool_invocation_session_builder.rb → tool_execution/tool_invocation_session_builder.rb} +2 -2
- 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.rb → configuration/configuration.rb} +14 -5
- data/lib/phronomy/configuration/global_configuration.rb +26 -0
- data/lib/phronomy/content_store/storage_schema.rb +11 -0
- data/lib/phronomy/content_store/stored_contents.rb +43 -0
- data/lib/phronomy/engine/backpressure_error.rb +7 -0
- data/lib/phronomy/{blocking.rb → engine/blocking.rb} +15 -8
- data/lib/phronomy/engine/cancellation_error.rb +7 -0
- data/lib/phronomy/engine/concurrency/cancellation_token.rb +4 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +29 -16
- data/lib/phronomy/engine/concurrency/operation_binding.rb +43 -0
- data/lib/phronomy/engine/concurrency/physical_completion_task.rb +4 -62
- data/lib/phronomy/engine/concurrency/result_collector.rb +99 -0
- data/lib/phronomy/engine/concurrency/result_composition.rb +145 -0
- data/lib/phronomy/engine/concurrency/subscriptions.rb +68 -0
- data/lib/phronomy/engine/concurrency/worker_input_restricted.rb +14 -0
- data/lib/phronomy/engine/event_loop.rb +160 -626
- data/lib/phronomy/engine/event_loop_reentrancy_error.rb +8 -0
- data/lib/phronomy/engine/execution.rb +229 -0
- data/lib/phronomy/engine/execution_cancellation_error.rb +14 -0
- data/lib/phronomy/engine/execution_receiver.rb +65 -0
- data/lib/phronomy/engine/execution_timeout_error.rb +14 -0
- data/lib/phronomy/engine/fsm_protocol.rb +14 -0
- data/lib/phronomy/engine/fsm_session.rb +38 -31
- data/lib/phronomy/{invalid_async_entry_action_error.rb → engine/invalid_async_entry_action_error.rb} +3 -1
- data/lib/phronomy/{invalid_async_transition_action_error.rb → engine/invalid_async_transition_action_error.rb} +3 -1
- data/lib/phronomy/{invalid_async_workflow_action_error.rb → engine/invalid_async_workflow_action_error.rb} +3 -1
- data/lib/phronomy/{invocation_context.rb → engine/invocation_context.rb} +13 -1
- data/lib/phronomy/engine/pool_shutdown_error.rb +7 -0
- data/lib/phronomy/engine/recursion_limit_error.rb +7 -0
- data/lib/phronomy/engine/runtime/timer_queue.rb +11 -0
- data/lib/phronomy/engine/runtime.rb +80 -84
- data/lib/phronomy/engine/runtime_shutdown_error.rb +7 -0
- data/lib/phronomy/engine/runtime_shutdown_reentrancy_error.rb +7 -0
- data/lib/phronomy/engine/scheduler_reentrancy_error.rb +9 -0
- data/lib/phronomy/engine/{task.rb → task_result.rb} +101 -42
- data/lib/phronomy/engine/timeout_error.rb +7 -0
- data/lib/phronomy/filter/contract/filter_block_error.rb +14 -0
- data/lib/phronomy/generation/generator_verifier/agent_result_receiver.rb +89 -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/base.rb +2 -2
- data/lib/phronomy/llm_context_window/token_budget.rb +6 -7
- data/lib/phronomy/llm_contract/authentication_error.rb +7 -0
- data/lib/phronomy/{context_budget_exceeded_error.rb → llm_contract/context_budget_exceeded_error.rb} +2 -0
- data/lib/phronomy/llm_contract/context_length_error.rb +7 -0
- data/lib/phronomy/llm_contract/rate_limit_error.rb +7 -0
- data/lib/phronomy/{token_usage.rb → llm_contract/token_usage.rb} +2 -2
- data/lib/phronomy/llm_contract/transport_error.rb +7 -0
- data/lib/phronomy/multi_agent/admission_registry.rb +22 -2
- data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +8 -8
- data/lib/phronomy/{agent → multi_agent}/handoff_runner.rb +18 -17
- data/lib/phronomy/multi_agent/orchestrator.rb +36 -68
- data/lib/phronomy/multi_agent/persistence/codec.rb +55 -0
- data/lib/phronomy/multi_agent/persistence/queries.rb +30 -0
- data/lib/phronomy/multi_agent/persistence/team_execution_repository.rb +108 -0
- data/lib/phronomy/multi_agent/persistence/team_repository.rb +61 -0
- data/lib/phronomy/{agent → multi_agent}/shared_state.rb +56 -39
- data/lib/phronomy/multi_agent/storage_contract/team_storage_schema.rb +15 -0
- data/lib/phronomy/multi_agent/team_coordinator.rb +21 -18
- data/lib/phronomy/multi_agent/team_execution.rb +1 -1
- data/lib/phronomy/{engine/runtime → multi_agent}/team_ownership_registry.rb +14 -4
- data/lib/phronomy/multi_agent/team_root.rb +1 -1
- data/lib/phronomy/output_parser/contract/parse_error.rb +7 -0
- data/lib/phronomy/persistence/api/persistence.rb +140 -0
- data/lib/phronomy/persistence/migration/initial_format_migration.rb +19 -19
- data/lib/phronomy/persistence_composition/repositories.rb +77 -0
- data/lib/phronomy/persistence_composition/storage_schema.rb +24 -0
- data/lib/phronomy/{execution_rehydration_required_error.rb → recovery/execution_rehydration_required_error.rb} +2 -0
- data/lib/phronomy/{recovery.rb → recovery/recovery.rb} +1 -1
- data/lib/phronomy/runtime_composition/agent_defaults.rb +7 -0
- data/lib/phronomy/runtime_composition/configuration_defaults.rb +9 -0
- data/lib/phronomy/runtime_composition/global_runtime.rb +19 -0
- data/lib/phronomy/storage/backend.rb +101 -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/scorer/llm_judge.rb +5 -3
- data/lib/phronomy/testing/fake_clock.rb +13 -9
- data/lib/phronomy/testing/persistence_contract/a_content_store.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +4 -4
- data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +10 -7
- data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +2 -2
- data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +6 -6
- data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +6 -6
- data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +8 -8
- data/lib/phronomy/testing/persistence_contract/neutral_storage_primitives.rb +263 -0
- data/lib/phronomy/testing/persistence_contract/storage_transaction_boundaries.rb +123 -0
- data/lib/phronomy/testing/persistence_contract.rb +4 -0
- data/lib/phronomy/tool/contract/tool_error.rb +7 -0
- data/lib/phronomy/tools/agent.rb +6 -6
- data/lib/phronomy/vector_store/async_backend.rb +5 -5
- data/lib/phronomy/vector_store/embeddings/base.rb +2 -2
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/{workflow.rb → workflow/execution/workflow.rb} +10 -8
- data/lib/phronomy/{workflow_context.rb → workflow/execution/workflow_context.rb} +4 -0
- data/lib/phronomy/workflow/execution/workflow_context_ownership_error.rb +7 -0
- data/lib/phronomy/workflow/execution/workflow_execution_registry.rb +188 -0
- data/lib/phronomy/{workflow_runner.rb → workflow/execution/workflow_runner.rb} +126 -75
- data/lib/phronomy/workflow/execution/workflow_terminal_policy.rb +40 -0
- data/lib/phronomy/workflow/persistence/codec.rb +153 -0
- data/lib/phronomy/workflow/persistence/state_repository.rb +57 -0
- data/lib/phronomy/workflow/phase_machine_builder.rb +8 -8
- data/lib/phronomy/workflow/storage_contract/workflow_storage_schema.rb +9 -0
- data/lib/phronomy.rb +52 -94
- data/scripts/api_snapshot.rb +4 -2
- data/scripts/storage_spi_snapshot.rb +36 -0
- data/sig/phronomy/agent.rbs +4 -5
- data/sig/phronomy/execution_receiver.rbs +34 -0
- data/sig/phronomy/extensions.rbs +5 -5
- data/sig/phronomy/handoff.rbs +4 -2
- data/sig/phronomy/multi_agent.rbs +19 -3
- data/sig/phronomy/persistence.rbs +7 -91
- data/sig/phronomy/runtime.rbs +34 -7
- data/sig/phronomy/storage.rbs +174 -0
- data/sig/phronomy/tool.rbs +11 -2
- data/sig/phronomy/workflow.rbs +1 -1
- metadata +236 -99
- data/lib/phronomy/agent/execution_coordinator.rb +0 -3138
- data/lib/phronomy/agent/handoff_execution_coordinator.rb +0 -143
- data/lib/phronomy/agent/recovery_support.rb +0 -504
- data/lib/phronomy/agent/token_budget_resolver.rb +0 -70
- data/lib/phronomy/agent/tool_executor.rb +0 -55
- data/lib/phronomy/generator_verifier.rb +0 -369
- data/lib/phronomy/invalid_context_budget_configuration_error.rb +0 -8
- data/lib/phronomy/multi_agent/fan_out_invocation.rb +0 -137
- data/lib/phronomy/multi_agent/fan_out_session_builder.rb +0 -118
- 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/ruby_llm_patches.rb +0 -24
- data/lib/phronomy/workflow_recovery.rb +0 -123
- /data/lib/phronomy/agent/{context_candidate_resolver.rb → context_assembly/context_candidate_resolver.rb} +0 -0
- /data/lib/phronomy/agent/{context_policy_input_builder.rb → context_assembly/context_policy_input_builder.rb} +0 -0
- /data/lib/phronomy/agent/{context_plan_validator.rb → context_contract/context_plan_validator.rb} +0 -0
- /data/lib/phronomy/agent/{context_policy.rb → context_contract/context_policy.rb} +0 -0
- /data/lib/phronomy/agent/{llm_operation_result.rb → execution/llm_operation_result.rb} +0 -0
- /data/lib/phronomy/agent/{handoff.rb → handoff/handoff.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_capability_factory.rb → handoff/handoff_capability_factory.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_policy.rb → handoff/handoff_policy.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_projection.rb → handoff/handoff_projection.rb} +0 -0
- /data/lib/phronomy/agent/{handoff_request.rb → handoff/handoff_request.rb} +0 -0
- /data/lib/phronomy/{canonical_json.rb → common/canonical_json.rb} +0 -0
- /data/lib/phronomy/{diagnostics.rb → engine/diagnostics.rb} +0 -0
- /data/lib/phronomy/{event.rb → engine/event.rb} +0 -0
- /data/lib/phronomy/{metrics.rb → engine/metrics.rb} +0 -0
- /data/lib/phronomy/{runnable.rb → engine/runnable.rb} +0 -0
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
Accepted. V2 revision 2, 2026-09-06.
|
|
6
6
|
|
|
7
|
+
The HandoffRunner namespace and ownership are amended by
|
|
8
|
+
[034-handoff-runner-coordination-ownership](034-handoff-runner-coordination-ownership.md).
|
|
9
|
+
The public Runner is now `Phronomy::MultiAgent::HandoffRunner`. Other Handoff
|
|
10
|
+
types and the durable semantics below remain unchanged in this first step.
|
|
11
|
+
|
|
7
12
|
User approval covers the V2 boundary and the five recovery-contract clarifications.
|
|
8
13
|
Acceptance is design authority; it is not a claim of repository integration or test success.
|
|
9
14
|
|
|
@@ -4,6 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
Accepted. V2 revision 2, 2026-09-06.
|
|
6
6
|
|
|
7
|
+
The HandoffRunner namespace and ownership are amended by
|
|
8
|
+
[034-handoff-runner-coordination-ownership](034-handoff-runner-coordination-ownership.md).
|
|
9
|
+
The public Runner is now `Phronomy::MultiAgent::HandoffRunner`. Other Handoff
|
|
10
|
+
types and the durable semantics below remain unchanged in this first step.
|
|
11
|
+
|
|
7
12
|
User approval covers the V2 boundary and the five recovery-contract clarifications.
|
|
8
13
|
Acceptance is design authority; it is not a claim of repository integration or test success.
|
|
9
14
|
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# 032: Compose domain persistence over a storage backend
|
|
2
|
+
|
|
3
|
+
- Status: Accepted
|
|
4
|
+
- Domain ownership refined by: [033-domain-persistence-ownership](033-domain-persistence-ownership.md)
|
|
5
|
+
- Date: 2026-09-17
|
|
6
|
+
- Refines: [014-unified-persistence-durable-state](014-unified-persistence-durable-state.md)
|
|
7
|
+
|
|
8
|
+
The raw fixed-repository/error portions are amended by
|
|
9
|
+
[ADR-058](058-neutral-storage-primitives.md). Domain ownership and applicable
|
|
10
|
+
transaction/uncertainty decisions below remain in force.
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
The previous `Persistence` class combined raw storage contracts with domain
|
|
15
|
+
repository construction, codecs, and result queries. Physical backends inherited
|
|
16
|
+
that class, and SQL implementations called `build_transaction_view` to construct
|
|
17
|
+
upper domain facades. This made the common storage boundary depend on the
|
|
18
|
+
entities whose records it stored.
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
|
|
22
|
+
1. `Storage::Backend` and `Storage::Repositories` define synchronous raw storage
|
|
23
|
+
and transaction-view protocols. `Storage::DurableRecord` and portable storage
|
|
24
|
+
errors belong to this common contract. These files do not depend on Agent,
|
|
25
|
+
MultiAgent, Runtime, or the domain-facing Persistence implementation.
|
|
26
|
+
2. Concrete backends depend on that contract and their physical storage tools.
|
|
27
|
+
The in-memory implementation lives in `storage/backends/in_memory.rb` and
|
|
28
|
+
retains its single Monitor and single all-repository transaction snapshot.
|
|
29
|
+
3. `Persistence.new(backend:)` composes the domain service over a selected backend.
|
|
30
|
+
The existing domain codecs and facades remain in `persistence/`. They validate
|
|
31
|
+
and convert records using the actual domain record definitions.
|
|
32
|
+
4. The same facade builder wraps the root backend and the raw view yielded by
|
|
33
|
+
`backend.transaction`. Transaction conversion stays inside the backend block;
|
|
34
|
+
conversion failures therefore participate in its normal rollback semantics.
|
|
35
|
+
5. `Persistence.in_memory` is the explicit convenience assembly. Backend selection
|
|
36
|
+
belongs to construction, not to the common storage contract.
|
|
37
|
+
6. Replace the old Persistence subclass SPI, raw-repository constructor,
|
|
38
|
+
`build_transaction_view`, `Persistence::InMemory`, and old record/error owners.
|
|
39
|
+
No compatibility aliases or second implementation of that SPI are retained.
|
|
40
|
+
See the [migration guide](../migrations/storage-backend-composition.md).
|
|
41
|
+
|
|
42
|
+
Both concrete backends and domain persistence depend on the common storage
|
|
43
|
+
contract. These are sibling responsibility groups, not a requirement for one
|
|
44
|
+
strict vertical ordering of the entire system. Runtime calls to a selected
|
|
45
|
+
backend do not establish a source dependency on that backend's concrete class.
|
|
46
|
+
|
|
47
|
+
## Preserved contracts
|
|
48
|
+
|
|
49
|
+
All eight repositories remain one atomic transaction domain. Their IDs,
|
|
50
|
+
revision/position checks, active execution constraints, record types, format
|
|
51
|
+
versions, and payload schemas are unchanged. ContentStore retains its separate
|
|
52
|
+
canonicalization API. The shared `AgentBusyError` remains the existing admission
|
|
53
|
+
failure contract; its standalone definition does not load Agent implementation.
|
|
54
|
+
|
|
55
|
+
Atomic durable-state transitions remain CONDITIONAL on a conforming backend for
|
|
56
|
+
F0 operations; commit-outcome certainty under F1 remains NO as a general promise.
|
|
57
|
+
F4 restart readability remains CONDITIONAL on retained confirmed durable data;
|
|
58
|
+
InMemory does not provide disk retention. X0 external effects remain outside the
|
|
59
|
+
storage transaction. This change adds no asynchronous SPI or execution ownership.
|
|
60
|
+
|
|
61
|
+
## Consequences and validation
|
|
62
|
+
|
|
63
|
+
Custom SQL backends migrate their superclass, record/error references, and raw
|
|
64
|
+
transaction view construction. They keep all transaction repositories and the
|
|
65
|
+
watermark bound to the same connection. Applications wrap a raw backend once.
|
|
66
|
+
|
|
67
|
+
An isolated-load architecture test checks that storage can use opaque records and
|
|
68
|
+
admission without loading domain or execution code. Public contract tests cover
|
|
69
|
+
root/transaction view separation and removal of the replaced SPI. Existing
|
|
70
|
+
repository conformance, commit/rollback/CAS, codec, recovery, and integration tests
|
|
71
|
+
remain required. Codec rejection after a physical write must roll back the whole
|
|
72
|
+
transaction, not leave a committed partial operation.
|
|
73
|
+
|
|
74
|
+
Shared Immutable ownership has already moved to `Values::Immutable`; this change
|
|
75
|
+
preserves that boundary. Domain model placement and unrelated module cycles
|
|
76
|
+
remain separate subsequent changes. In particular, DurableCodec retains its
|
|
77
|
+
TeamRoot / TeamExecution references to validate and reconstruct Team records.
|
|
78
|
+
Those belong to domain persistence, not to the common storage contract.
|
|
79
|
+
Moving a type or hiding a constant reference alone is not evidence that this
|
|
80
|
+
storage boundary has been separated.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# 033: Own persistence rules within each domain
|
|
2
|
+
|
|
3
|
+
- Status: Amended
|
|
4
|
+
- Date: 2026-09-18
|
|
5
|
+
- Error boundary refined by: [043-storage-execution-constraint-notifications](043-storage-execution-constraint-notifications.md)
|
|
6
|
+
- Refines: [032-storage-backend-composition](032-storage-backend-composition.md)
|
|
7
|
+
|
|
8
|
+
The raw fixed-repository/error portions are amended by
|
|
9
|
+
[ADR-058](058-neutral-storage-primitives.md). Domain ownership and applicable
|
|
10
|
+
transaction/uncertainty decisions below remain in force.
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
ADR-032 separated raw storage from domain persistence, but the common-looking
|
|
15
|
+
`persistence/` directory still collected Agent, Team, and Workflow schemas and
|
|
16
|
+
repository facades. Moving that directory to an upper band in a dependency
|
|
17
|
+
diagram described its contents; it did not establish suitable domain ownership.
|
|
18
|
+
The public Persistence entry point also contained domain-specific result queries.
|
|
19
|
+
|
|
20
|
+
## Decision
|
|
21
|
+
|
|
22
|
+
1. `agent/persistence/` owns AgentRoot, Journal, AgentExecution, and Handoff
|
|
23
|
+
codecs/repositories and Agent/Handoff result queries.
|
|
24
|
+
2. `multi_agent/persistence/` owns TeamRoot and TeamExecution codecs/repositories
|
|
25
|
+
and Team result queries. Team persistence can be used over a raw backend
|
|
26
|
+
without loading Agent implementation or the combined Persistence service.
|
|
27
|
+
3. `workflow/persistence/` owns the Workflow record schema, normalization rules,
|
|
28
|
+
and state repository. Workflow symbol normalization remains specific to that
|
|
29
|
+
domain; other codecs do not adopt it implicitly.
|
|
30
|
+
4. `Storage::RecordCodec` contains shared record-envelope and scalar validation.
|
|
31
|
+
Domain codecs extend it; it neither selects nor imports a domain codec.
|
|
32
|
+
These helpers and domain components are private implementation, not new SPI.
|
|
33
|
+
5. `PersistenceComposition::Repositories` explicitly assembles the seven domain
|
|
34
|
+
repository wrappers and the existing ContentStore from one raw storage view.
|
|
35
|
+
The public `Phronomy::Persistence` service remains the compatible entry point.
|
|
36
|
+
It delegates queries and retains the Runtime observation-thread guard.
|
|
37
|
+
Each view creates and caches domain wrappers on first use, under one lock,
|
|
38
|
+
so Agent-only use does not load Team or Workflow implementations.
|
|
39
|
+
6. Conversion remains inside `backend.transaction`. Root and transaction paths
|
|
40
|
+
use the same builder. Reusing the root view when the backend yields itself
|
|
41
|
+
retains the existing repository identity and fault-injection behavior.
|
|
42
|
+
7. Delete the private combined `Persistence::DurableCodec` and
|
|
43
|
+
`Persistence::RepositoryFacades`; do not preserve a second owner through
|
|
44
|
+
compatibility aliases. Explicit historical migration keeps its public API
|
|
45
|
+
and calls the new domain codecs.
|
|
46
|
+
|
|
47
|
+
InMemory, SQLite, and PostgreSQL are all concrete implementations of the common
|
|
48
|
+
Backend contract. Domain repository wrappers are consumers of that contract;
|
|
49
|
+
they do not introduce a second physical transaction boundary.
|
|
50
|
+
|
|
51
|
+
## Preserved contracts and limits
|
|
52
|
+
|
|
53
|
+
Public Persistence methods, Backend SPI, eight repository accessors, IDs,
|
|
54
|
+
revisions/positions, active constraints, physical SQL schemas, record types,
|
|
55
|
+
format versions, and payload schemas are unchanged. Existing SQL backends need
|
|
56
|
+
no source migration for this ownership change. The public result-reader dispatch
|
|
57
|
+
and observation guard remain in the public entry point.
|
|
58
|
+
|
|
59
|
+
Atomic durable-state transitions and rollback remain CONDITIONAL on a conforming
|
|
60
|
+
backend for F0. Commit-outcome certainty under F1 is not added. F4 restart
|
|
61
|
+
readability depends on retained confirmed data; InMemory is not disk retention.
|
|
62
|
+
X0 effects remain outside storage transactions.
|
|
63
|
+
|
|
64
|
+
The raw `Storage::Repositories` still names eight Phronomy record repositories and
|
|
65
|
+
an Agent watermark operation. This is an explicit intermediate state, not a claim
|
|
66
|
+
that the framework contract is domain-neutral. Contract generalization and naming
|
|
67
|
+
of the final common persistence framework are deferred to the staged plan below.
|
|
68
|
+
|
|
69
|
+
## Validation
|
|
70
|
+
|
|
71
|
+
Existing record-schema, backend conformance, optimistic conflict, recovery,
|
|
72
|
+
Handoff, Team, Workflow, and public compatibility tests remain required. A
|
|
73
|
+
separate-process boundary test uses Team persistence without Agent, Workflow,
|
|
74
|
+
Runtime, or combined-Persistence loading. Another process uses the public Agent
|
|
75
|
+
repositories without loading Team or Workflow implementations. A failure-injection test rejects the
|
|
76
|
+
Team response after writes and verifies rollback across Agent, Team, and content.
|
|
77
|
+
Dependency analysis must not introduce a new nontrivial file cycle.
|
|
78
|
+
|
|
79
|
+
See [the staged implementation plan](../architecture/persistence-refactoring-plan.md).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# ADR-034: Handoff Runner Coordination Ownership
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted for the H1 step on `refactor/architecture`, 2026-09-18.
|
|
6
|
+
The subsequent Handoff contract and persistence separation is deferred.
|
|
7
|
+
|
|
8
|
+
## Scope of supersession
|
|
9
|
+
|
|
10
|
+
This amends the Runner placement/public namespace in
|
|
11
|
+
[030-agent-handoff-domain-and-durable-responsibility](030-agent-handoff-domain-and-durable-responsibility.md)
|
|
12
|
+
and the domain map in
|
|
13
|
+
[031-durable-multi-agent-coordination](031-durable-multi-agent-coordination.md).
|
|
14
|
+
All other durable Handoff semantics remain in force.
|
|
15
|
+
|
|
16
|
+
## Context
|
|
17
|
+
|
|
18
|
+
HandoffRunner validates a graph of concrete Agents, selects the active Agent,
|
|
19
|
+
invokes or resumes exact executions, follows multiple transfers, and scopes
|
|
20
|
+
cancellation/result lookup to a specified chain. Those responsibilities span
|
|
21
|
+
Agents. They differ from an individual Agent's execution, Journal and Context.
|
|
22
|
+
|
|
23
|
+
Calling Handoff from an Agent does not make that whole coordination lifetime an
|
|
24
|
+
Agent implementation detail. Updating the Source and routing state in one
|
|
25
|
+
transaction also does not require them to occupy one module.
|
|
26
|
+
|
|
27
|
+
The Runner and TeamCoordinator share the Runtime-local AdmissionRegistry. Keeping
|
|
28
|
+
the Runner inside Agent creates an Agent-to-MultiAgent concrete dependency.
|
|
29
|
+
Moving only the Runner aligns ownership without generalizing the registry or
|
|
30
|
+
changing the existing shutdown participant contract.
|
|
31
|
+
|
|
32
|
+
## Decision
|
|
33
|
+
|
|
34
|
+
1. Move the public Runner implementation from `agent/handoff_runner.rb` to
|
|
35
|
+
`multi_agent/handoff_runner.rb` and expose
|
|
36
|
+
`Phronomy::MultiAgent::HandoffRunner`.
|
|
37
|
+
2. Remove `Phronomy::Agent::HandoffRunner` without a compatibility alias on the
|
|
38
|
+
refactoring branch. Migrate API documentation, RBS, snapshot and consumers
|
|
39
|
+
together. See the [migration guide](../migrations/handoff-runner-multi-agent.md).
|
|
40
|
+
3. Retain `Agent::Handoff`, `HandoffPolicy`, Context/Request/State and Agent
|
|
41
|
+
terminal/persistence integration during H1. Qualify the Runner's dependencies
|
|
42
|
+
explicitly. This mixed placement is an intermediate state.
|
|
43
|
+
4. Keep AdmissionRegistry in MultiAgent. The admission key, exception classes,
|
|
44
|
+
successful-call release and Runtime shutdown participation are unchanged.
|
|
45
|
+
5. Preserve method parameters/results, record formats, main-Agent anchor,
|
|
46
|
+
deterministic Target IDs, transaction boundaries, exact recovery and scoped
|
|
47
|
+
cancellation. H1 introduces no new execution or shutdown manager.
|
|
48
|
+
|
|
49
|
+
## Consequences and limits
|
|
50
|
+
|
|
51
|
+
Agent no longer directly names a MultiAgent implementation in production source.
|
|
52
|
+
The Runner's existing Tracing dependency now belongs to the MultiAgent directory.
|
|
53
|
+
Module-edge totals and large strongly connected components need not decrease:
|
|
54
|
+
this step changes responsibility placement, not the underlying algorithm.
|
|
55
|
+
|
|
56
|
+
Agent still interprets Handoff/Team coordination metadata. This logical coupling
|
|
57
|
+
is not removed merely because a directory edge disappears.
|
|
58
|
+
|
|
59
|
+
Later work must separate Request construction, Coordinator selection, Context
|
|
60
|
+
conversion, transaction participation and purge/recovery constraints before
|
|
61
|
+
moving the remaining Handoff-specific types and persistence rules. That work must
|
|
62
|
+
preserve one transaction for Source termination plus responsibility transfer and
|
|
63
|
+
for Target termination plus routing stabilization. It must not promote transferred
|
|
64
|
+
Context into permanent Target Journal/Knowledge or depend on post-commit callbacks
|
|
65
|
+
for coordination correctness.
|
|
66
|
+
|
|
67
|
+
## Verification obligations
|
|
68
|
+
|
|
69
|
+
The new public constant must load with Zeitwerk and match its RBS/API snapshot;
|
|
70
|
+
the old constant must not remain as an alias. Existing Handoff, multi-hop,
|
|
71
|
+
cancellation/recovery, shutdown and SQLite reconstruction scenarios must pass.
|
|
72
|
+
API guards must distinguish `MultiAgent::HandoffRunner` from the removed exact
|
|
73
|
+
constant `MultiAgent::Handoff`.
|
|
74
|
+
|
|
75
|
+
The implementation delivery records test results separately; this ADR does not
|
|
76
|
+
assert that unexecuted live-LLM or database-server tests passed.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# ADR-035: Default Tool Executor Ownership
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted on the architecture refactoring branch as T1.
|
|
6
|
+
|
|
7
|
+
This decision assigns the default Tool execution helper to the existing
|
|
8
|
+
Capability implementation. The public Tool facade defined by ADR-015 remains
|
|
9
|
+
the same Class object with the same canonical implementation name.
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
`Agent::Context::Capability::Base#call_async` delegates default asynchronous
|
|
14
|
+
dispatch to `Agent::ToolExecutor`. The helper selects inline cooperative work
|
|
15
|
+
or OffloadPool submission and returns a TaskResult. It has no responsibility
|
|
16
|
+
for Agent state, approval, persistence, recovery, or multi-Agent coordination.
|
|
17
|
+
|
|
18
|
+
Placing this helper directly under Agent makes the Capability directory depend
|
|
19
|
+
on Agent execution while Agent execution also depends on Capability. The
|
|
20
|
+
underlying helper is part of the Tool calling contract and its standard
|
|
21
|
+
implementation, so its ownership should reflect that role.
|
|
22
|
+
|
|
23
|
+
Moving only the helper to `tool/` would introduce another directory cycle:
|
|
24
|
+
`tool/base.rb` currently aliases `Agent::Context::Capability::Base`. Moving the
|
|
25
|
+
canonical Tool class and changing its runtime name would require a separate
|
|
26
|
+
public compatibility decision.
|
|
27
|
+
|
|
28
|
+
## Decision
|
|
29
|
+
|
|
30
|
+
1. Move the helper to
|
|
31
|
+
`Phronomy::Agent::Context::Capability::ToolExecutor`, in
|
|
32
|
+
`agent/context/capability/tool_executor.rb`. Classify this helper as private
|
|
33
|
+
API and remove the old internal constant without a compatibility alias.
|
|
34
|
+
2. Use the new helper from Capability Base and Agent ToolInvocation. Preserve
|
|
35
|
+
the existing dispatch implementation and error messages.
|
|
36
|
+
3. Keep `Tool::Base` and `Agent::Context::Capability::Base` as the same Class
|
|
37
|
+
object. Preserve their canonical name, DSL state, method-owner checks, and
|
|
38
|
+
the public `call_async(args, cancellation_token:, config:)` protocol.
|
|
39
|
+
4. Keep Runtime selection, authorization and logical result ownership in Agent
|
|
40
|
+
ToolInvocation. Its standard path passes Runtime and `on_full: :raise` to
|
|
41
|
+
the private helper; custom Tool implementations receive the public protocol.
|
|
42
|
+
Agent-as-Tool continues through its own asynchronous Agent lifecycle.
|
|
43
|
+
5. Keep the existing TaskResult and OffloadPool mechanisms in Engine. This
|
|
44
|
+
step adds no execution manager or application registration requirement.
|
|
45
|
+
|
|
46
|
+
## Consequences and limits
|
|
47
|
+
|
|
48
|
+
The Capability directory now directly names its existing Engine dependencies
|
|
49
|
+
instead of an Agent-owned wrapper. The code-level algorithm and file-level
|
|
50
|
+
dependency graph are preserved when the moved file is matched to its source.
|
|
51
|
+
Directory placement changes do not imply that all larger dependency cycles
|
|
52
|
+
have been resolved.
|
|
53
|
+
|
|
54
|
+
Applications should use the public Tool authoring and invocation contracts.
|
|
55
|
+
Code or tests that directly reference the removed private Agent::ToolExecutor
|
|
56
|
+
constant need to follow its new internal name. The public Tool API and durable
|
|
57
|
+
formats require no migration, and the Context contract regrouping remains a
|
|
58
|
+
separate change.
|
|
59
|
+
|
|
60
|
+
## Verification obligations
|
|
61
|
+
|
|
62
|
+
Verify cooperative execution, OffloadPool dispatch, cancellation propagation,
|
|
63
|
+
Runtime injection, custom `call_async`, and Agent-as-Tool. Keep the existing
|
|
64
|
+
offload-boundary observations aligned with the moved source path. The public
|
|
65
|
+
API snapshot, RBS and Tool class identity must remain unchanged; Zeitwerk must
|
|
66
|
+
load the new helper and leave the old internal constant absent.
|
|
67
|
+
|
|
68
|
+
The implementation delivery records its actual test results separately.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# ADR-036: Context Contract Ownership
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted on the architecture refactoring branch as C1.
|
|
6
|
+
|
|
7
|
+
This decision clarifies the ownership of existing Context contracts. The
|
|
8
|
+
Journal/Manifest authority model in ADR-012 and the Knowledge model in ADR-013
|
|
9
|
+
remain in force. It does not change either model or introduce a new public API.
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
`ContextPolicies::Default` depends on `ContextPolicy` and `ContextPolicyInput`.
|
|
14
|
+
Agent execution also consumes these contracts and selects a concrete policy.
|
|
15
|
+
Keeping the contracts beside execution classes directly under `agent/` makes
|
|
16
|
+
the policy directory appear to depend back on Agent execution.
|
|
17
|
+
|
|
18
|
+
The shared vocabulary is broader than a policy base class. Policy inputs refer
|
|
19
|
+
to the previous `LLMInputManifest`; plans and generated items have common
|
|
20
|
+
validation rules; `before_llm_input` hooks exchange typed input and result
|
|
21
|
+
values. Moving only a base class would leave those shared contracts split
|
|
22
|
+
across responsibility groups.
|
|
23
|
+
|
|
24
|
+
The Manifest constructs, validates, and converts record values. It does not
|
|
25
|
+
open transactions or write records to a backend. Its representation therefore
|
|
26
|
+
belongs with the Context contracts used by both producers and consumers.
|
|
27
|
+
|
|
28
|
+
## Decision
|
|
29
|
+
|
|
30
|
+
1. Move these seven unchanged files into `lib/phronomy/agent/context_contract/`:
|
|
31
|
+
- `context_policy.rb`
|
|
32
|
+
- `context_policy_input.rb`
|
|
33
|
+
- `context_plan.rb`
|
|
34
|
+
- `context_plan_validator.rb`
|
|
35
|
+
- `llm_input_manifest.rb`
|
|
36
|
+
- `llm_input_build_context.rb`
|
|
37
|
+
- `llm_input_patch.rb`
|
|
38
|
+
2. Collapse the directory with Zeitwerk, following the existing Engine layout
|
|
39
|
+
mechanism. Keep the existing `Phronomy::Agent::*` definitions and canonical
|
|
40
|
+
names, including nested input and Manifest value types. Add no aliases or
|
|
41
|
+
`Phronomy::Agent::ContextContract` namespace.
|
|
42
|
+
3. Keep `ContextPolicies::Default` with the concrete policy implementations.
|
|
43
|
+
Keep Context assembly, input building, candidate resolution, Runtime
|
|
44
|
+
integration, hook invocation, and persistence transactions with their
|
|
45
|
+
existing execution-side owners.
|
|
46
|
+
4. Preserve policy instance binding, the `call(input)` protocol, hook input and
|
|
47
|
+
result types, and the Manifest version and encoded representation. Add no
|
|
48
|
+
descriptor, registry, application registration step, or data migration.
|
|
49
|
+
5. Treat the contracts and concrete policies as separate responsibility groups.
|
|
50
|
+
They may share a horizontal band in a dependency view. Directory nesting and
|
|
51
|
+
Ruby namespace nesting do not determine architectural dependency direction.
|
|
52
|
+
|
|
53
|
+
## Consequences and limits
|
|
54
|
+
|
|
55
|
+
Policies and hooks reference the contract definitions in their shared group,
|
|
56
|
+
while Agent execution composes and consumes them. The contract files have no
|
|
57
|
+
static dependency on Agent execution or MultiAgent implementation classes.
|
|
58
|
+
Their dependencies on immutable values, token estimation, canonical JSON,
|
|
59
|
+
shared errors, and Storage serialization errors remain unchanged.
|
|
60
|
+
|
|
61
|
+
The source bodies and mapped file-level dependency graph are preserved. A new
|
|
62
|
+
directory group exposes edges previously internal to `agent/`, so aggregate
|
|
63
|
+
directory edge counts and strongly connected component sizes can increase.
|
|
64
|
+
This is not evidence that the existing file-level cycles were resolved.
|
|
65
|
+
|
|
66
|
+
The contracts still contain Handoff-related categories and metadata vocabulary.
|
|
67
|
+
That semantic coupling belongs to the subsequent Handoff responsibility review.
|
|
68
|
+
The mixed root directory and execution cycles also require separate work.
|
|
69
|
+
|
|
70
|
+
Applications continue to `require "phronomy"` and use the same documented
|
|
71
|
+
constants. Individual implementation paths that previously lived directly
|
|
72
|
+
under `agent/` have moved; no forwarding files are retained at those paths.
|
|
73
|
+
|
|
74
|
+
## Verification obligations
|
|
75
|
+
|
|
76
|
+
Verify ordinary lazy loading and eager loading, canonical constant names,
|
|
77
|
+
independently accessing each contract, custom Policy binding, Plan validation,
|
|
78
|
+
hook input/result handling, Manifest serialization and restoration, Context
|
|
79
|
+
assembly, and existing migration/persistence integration.
|
|
80
|
+
|
|
81
|
+
Keep the public API snapshot and RBS unchanged. Match each moved file to its
|
|
82
|
+
source when comparing dependencies. Record the removal of direct policy/hook
|
|
83
|
+
references to the execution directory without presenting aggregate graph
|
|
84
|
+
changes as the elimination of all cycles.
|
|
85
|
+
|
|
86
|
+
The implementation delivery records its test results separately.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# ADR-037: Common Definition Ownership
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted on the architecture refactoring branch.
|
|
6
|
+
|
|
7
|
+
The initial extraction scope is amended by
|
|
8
|
+
[038-responsibility-based-source-layout](038-responsibility-based-source-layout.md),
|
|
9
|
+
which adds reviewed general definitions and relocates feature-owned definitions.
|
|
10
|
+
The common-ownership rule and public Error contract below remain in force.
|
|
11
|
+
|
|
12
|
+
## Context
|
|
13
|
+
|
|
14
|
+
`lib/phronomy.rb` combines the application loading entry point with shared
|
|
15
|
+
exception definitions and global configuration. Internal consumers of the
|
|
16
|
+
base `Phronomy::Error` therefore refer back to the entry point even though
|
|
17
|
+
they do not explicitly require it.
|
|
18
|
+
|
|
19
|
+
The shared base exception has no dependency on feature implementations. It
|
|
20
|
+
belongs to a common definition group. An `errors/` group would not convey the
|
|
21
|
+
distinction between general definitions and feature-owned exception contracts.
|
|
22
|
+
The same distinction applies to definitions other than exceptions.
|
|
23
|
+
|
|
24
|
+
## Decision
|
|
25
|
+
|
|
26
|
+
1. Use `lib/phronomy/common/` for general definitions shared across the
|
|
27
|
+
framework that do not belong to a particular feature. These definitions
|
|
28
|
+
must not depend on concrete Agent, Workflow, Runtime, or other feature
|
|
29
|
+
implementations. Multiple consumers alone do not establish common ownership.
|
|
30
|
+
2. Move only the base `Phronomy::Error < StandardError` definition from the
|
|
31
|
+
entry point to `common/error.rb`. Name files after their responsibility;
|
|
32
|
+
do not introduce an unbounded `common/common.rb` collection.
|
|
33
|
+
3. Collapse `common/` with Zeitwerk to retain `Phronomy::Error` as its canonical
|
|
34
|
+
name. Do not introduce a second class, alias, or `Phronomy::Common` namespace.
|
|
35
|
+
Ordinary application loading remains `require "phronomy"`.
|
|
36
|
+
4. Keep existing subclass definitions, inheritance, constructors, and rescue
|
|
37
|
+
behavior unchanged. Inheriting from `Phronomy::Error` does not require a
|
|
38
|
+
feature-owned exception to live in `common/`.
|
|
39
|
+
5. Keep the common base independent of entry-point loading. Reading its
|
|
40
|
+
implementation file in isolation must not initialize the full framework.
|
|
41
|
+
This is an internal architecture check, not a new public partial-loading API.
|
|
42
|
+
|
|
43
|
+
## Consequences and limits
|
|
44
|
+
|
|
45
|
+
Internal references to the shared base resolve to its common definition rather
|
|
46
|
+
than to the loading entry point. The application-facing constant and signatures
|
|
47
|
+
remain unchanged. No new explicit require of the application entry point is
|
|
48
|
+
introduced.
|
|
49
|
+
|
|
50
|
+
Other exceptions still defined in the entry point, global configuration, and
|
|
51
|
+
the mixed root implementation group need separate ownership reviews. This
|
|
52
|
+
single extraction does not establish that all file or directory cycles have
|
|
53
|
+
been eliminated.
|
|
54
|
+
|
|
55
|
+
## Verification obligations
|
|
56
|
+
|
|
57
|
+
Verify isolated base-definition loading, ordinary application loading, and eager
|
|
58
|
+
loading. Check ordinary and preloaded-base initialization orders, canonical
|
|
59
|
+
constant identity, representative subclass hierarchies, and catching a domain
|
|
60
|
+
exception with `rescue Phronomy::Error`. Preserve the public API snapshot and
|
|
61
|
+
RBS signatures. Compare dependency targets against the applied baseline and
|
|
62
|
+
report remaining entry-point references separately.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# ADR-038: Responsibility-Based Source Layout
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted on the architecture refactoring branch; configuration/runtime lifecycle
|
|
6
|
+
ownership amended by
|
|
7
|
+
[039-runtime-configuration-lifecycle-ownership](039-runtime-configuration-lifecycle-ownership.md).
|
|
8
|
+
Concrete-default ownership is subsequently amended by
|
|
9
|
+
[040-configuration-default-composition](040-configuration-default-composition.md).
|
|
10
|
+
Agent default selection and one-shot placement are subsequently refined by
|
|
11
|
+
[044-agent-default-and-one-shot-composition](044-agent-default-and-one-shot-composition.md).
|
|
12
|
+
The Workflow recovery prepend requirement is subsequently replaced by direct
|
|
13
|
+
Runner ownership in
|
|
14
|
+
[054-workflow-terminal-save-single-owner](054-workflow-terminal-save-single-owner.md).
|
|
15
|
+
|
|
16
|
+
Amends the extraction scope of
|
|
17
|
+
[037-common-definition-ownership](037-common-definition-ownership.md).
|
|
18
|
+
Its common-ownership rule and public Error contract remain unchanged.
|
|
19
|
+
|
|
20
|
+
## Context
|
|
21
|
+
|
|
22
|
+
The application loading entry point and the direct `lib/phronomy/` directory
|
|
23
|
+
were distinct sources of mixed ownership. After the base Error extraction,
|
|
24
|
+
the entry point still defined twenty feature/shared exceptions and global
|
|
25
|
+
configuration operations. Thirty-nine direct Ruby files still included
|
|
26
|
+
Workflow implementation, execution contracts, recovery, configuration, and
|
|
27
|
+
general values alongside namespace declarations.
|
|
28
|
+
|
|
29
|
+
A directory's location must describe its responsibility. A public constant
|
|
30
|
+
under `Phronomy` does not require its implementation file to remain directly
|
|
31
|
+
under `lib/phronomy/`. Conversely, a shared consumer list does not make a
|
|
32
|
+
feature contract a general common definition.
|
|
33
|
+
|
|
34
|
+
## Decision
|
|
35
|
+
|
|
36
|
+
1. Reserve `lib/phronomy.rb` for application loading and explicit initialization
|
|
37
|
+
wiring. Production implementation files under `lib/phronomy/` must not require that entry
|
|
38
|
+
point. Use Zeitwerk for canonical constant loading and precise requires for
|
|
39
|
+
dependencies and initialization side effects.
|
|
40
|
+
The existing `testing/persistence_contract.rb` is a separately documented
|
|
41
|
+
public entry point for external backend authors. It remains allowed to load
|
|
42
|
+
Phronomy and RSpec, and remains excluded from production automatic loading.
|
|
43
|
+
This single named exception does not exempt other files under `testing/`.
|
|
44
|
+
2. Allow only these direct Ruby files under `lib/phronomy/`:
|
|
45
|
+
|
|
46
|
+
| File | Reason |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `version.rb` | Bundler/gem metadata convention and Zeitwerk GemInflector's version-file convention |
|
|
49
|
+
| `llm_adapter.rb` | Explicit namespace and extension-SPI documentation |
|
|
50
|
+
| `tool.rb` | Explicit public Tool authoring namespace and documentation |
|
|
51
|
+
| `vector_store.rb` | Explicit namespace and backend-SPI documentation |
|
|
52
|
+
| `output_parser.rb` | Explicit parser namespace declaration |
|
|
53
|
+
| `testing.rb` | Explicit test-support namespace declaration |
|
|
54
|
+
| `filter.rb` | Existing Filter convenience loading entry, without feature implementation |
|
|
55
|
+
| `tracing.rb` | Existing Tracing convenience loading entry, without feature implementation |
|
|
56
|
+
|
|
57
|
+
Namespace files must not accumulate method bodies or concrete classes.
|
|
58
|
+
RubyGems does not mandate this entire allowlist. Keeping these small files
|
|
59
|
+
is an explicit Phronomy design/compatibility choice. New exceptions to the
|
|
60
|
+
allowlist require an ownership reason and an amendment to this decision.
|
|
61
|
+
3. Extend `common/` with `CanonicalJSON`, `ConfigurationError`, and
|
|
62
|
+
`Values::Immutable`. Preserve their canonical names, JSON representation,
|
|
63
|
+
copy/freeze behavior, and exception hierarchy. The three equivalent private
|
|
64
|
+
Agent copy helpers delegate to `Values::Immutable.copy`; domain-specific
|
|
65
|
+
command copying and Workflow copying keep their different contracts.
|
|
66
|
+
4. Move the remaining implementation and exception definitions to their owners:
|
|
67
|
+
|
|
68
|
+
| Directory | Responsibility |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `engine/` | EventLoop/FSM communication, synchronous callback constraints, execution composition, cancellation/deadlines, runtime diagnostics, invocation and runnable execution contracts |
|
|
71
|
+
| `recovery/` | Shared recovery vocabulary and execution rehydration requirement; no concrete Agent/Workflow orchestration |
|
|
72
|
+
| `workflow/execution/` | Workflow DSL, context ownership, runner, and terminal persistence recovery |
|
|
73
|
+
| `agent/api/` | Agent namespace/event loading and lifecycle extension installation |
|
|
74
|
+
| `agent/composition/` | One-shot Agent/Persistence composition; method definition loaded by the application entry (ADR-044) |
|
|
75
|
+
| `agent/lifecycle_contract/` | Agent ownership, handoff, and application stream-delivery exceptions |
|
|
76
|
+
| `configuration/` | Global configuration values, defaults, accessors, replacement, and scoped overrides |
|
|
77
|
+
| `runtime_composition/` | Application Runtime/configuration lifecycle coordination and concrete default bindings (ADR-039/040/044) |
|
|
78
|
+
| `llm_contract/` | Token usage, context-budget failures, and LLM call-boundary failures |
|
|
79
|
+
| `llm_adapter/ruby_llm_patches.rb` | RubyLLM version-guarded compatibility patch |
|
|
80
|
+
| `persistence/api/` | Public Persistence facade and repository composition |
|
|
81
|
+
| `generation/` | GeneratorVerifier pipeline and its confidence failure |
|
|
82
|
+
| `tool/contract/`, `filter/contract/`, `output_parser/contract/` | Feature-owned shared exceptions |
|
|
83
|
+
|
|
84
|
+
5. Preserve all existing Ruby constant names, class/module kinds, inheritance,
|
|
85
|
+
constructors, method visibility, public signatures, and persisted formats.
|
|
86
|
+
Do not add constant aliases or compatibility files at retired implementation
|
|
87
|
+
paths. Ordinary application loading remains `require "phronomy"`; arbitrary
|
|
88
|
+
internal file paths are not a new public partial-loading API.
|
|
89
|
+
6. Use existing Zeitwerk `collapse` and `push_dir(namespace: Phronomy)` facilities.
|
|
90
|
+
The named nested roots are independent of their enclosing namespace. This
|
|
91
|
+
retains top-level `Phronomy::WorkflowContext` beside existing nested
|
|
92
|
+
`Phronomy::Workflow::Persistence` without collapsing the entire Workflow
|
|
93
|
+
namespace. Load `version.rb` first to establish the non-reloadable Phronomy
|
|
94
|
+
root namespace. Do not depend on facilities introduced after Zeitwerk 2.6.
|
|
95
|
+
7. Preserve explicit lifecycle initialization. Workflow recovery must be
|
|
96
|
+
prepended during ordinary application loading. Agent event/recovery
|
|
97
|
+
extensions must be installed when Agent is loaded. Keep external patching
|
|
98
|
+
and global namespace reopening files outside automatic name inference.
|
|
99
|
+
Production eager loading must continue to exclude RSpec conformance support.
|
|
100
|
+
|
|
101
|
+
## Dependency interpretation and limits
|
|
102
|
+
|
|
103
|
+
`Event` is an Engine communication contract, not a general-purpose common
|
|
104
|
+
value. The `InvalidAsync*` family belongs to synchronous FSM callback rules:
|
|
105
|
+
Engine and Agent use the entry-action failure as well as Workflow. Moving that
|
|
106
|
+
contract into Workflow implementation would introduce the wrong dependency.
|
|
107
|
+
|
|
108
|
+
`ExecutionRehydrationRequiredError` belongs to recovery even though its name
|
|
109
|
+
starts with Execution. It is not the timeout/cancellation outcome of fan-out
|
|
110
|
+
composition. `ConfigurationError` is common; `Configuration` is not. Default
|
|
111
|
+
configuration still constructs a concrete LLM adapter and tracer. This change
|
|
112
|
+
groups that existing composition but does not make it implementation-neutral.
|
|
113
|
+
|
|
114
|
+
Directory relocation does not establish that every remaining dependency is
|
|
115
|
+
downward or that all cycles disappear. Preserve and report actual references.
|
|
116
|
+
An analyzer must resolve namespace operations to their defining implementation
|
|
117
|
+
instead of treating the shortest namespace reopening as the owner of every
|
|
118
|
+
method. Do not mistake a loading entry point for the implementation it loads.
|
|
119
|
+
|
|
120
|
+
## Verification obligations
|
|
121
|
+
|
|
122
|
+
- Check the direct-root allowlist and forbid internal entry-point requires.
|
|
123
|
+
- Verify normal and eager loading, independent common/exception loading,
|
|
124
|
+
preloaded common definitions, nested-namespace access orders, and preserved
|
|
125
|
+
lifecycle extension installation.
|
|
126
|
+
- Exercise the supported Zeitwerk lower bound and the current locked version.
|
|
127
|
+
- Preserve the API snapshot and RBS without regenerating away a difference.
|
|
128
|
+
- Run existing execution, Workflow, Agent, persistence/recovery, integration,
|
|
129
|
+
configuration, and serialization tests; run the repository style/type gates.
|
|
130
|
+
- Compare dependencies against the applied baseline with the same analyzer.
|
|
131
|
+
Mark candidate results as unapplied and identify the exact source tree.
|