phronomy 0.26.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 +40 -0
- data/README.md +4 -0
- data/VERIFY.sh +27 -27
- data/benchmark/bench_agent_invoke.rb +26 -22
- data/benchmark/bench_context_assembler.rb +4 -5
- 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 +4 -2
- 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 +27 -4
- 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 +1 -1
- data/docs/architecture/workflow-terminal-ownership-design.md +104 -0
- data/docs/architecture.md +209 -0
- 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 +9 -3
- data/docs/getting-started.md +4 -4
- data/docs/migrations/0.15.md +5 -0
- data/docs/migrations/durable-semantic-coordination-v2.md +6 -0
- 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 +117 -32
- 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 +51 -241
- 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} +19 -95
- 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} +9 -10
- 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} +20 -71
- 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 +32 -37
- data/lib/phronomy/agent/{recovery_coordinator → recovery/recovery_coordinator}/resolution.rb +37 -40
- data/lib/phronomy/agent/{recovery_coordinator.rb → recovery/recovery_coordinator.rb} +6 -10
- 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/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} +1 -1
- 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 +4 -0
- data/lib/phronomy/engine/concurrency/operation_binding.rb +1 -1
- data/lib/phronomy/engine/concurrency/worker_input_restricted.rb +14 -0
- data/lib/phronomy/engine/event_loop.rb +158 -624
- data/lib/phronomy/engine/event_loop_reentrancy_error.rb +8 -0
- data/lib/phronomy/{execution.rb → engine/execution.rb} +0 -7
- data/lib/phronomy/{execution_cancellation_error.rb → engine/execution_cancellation_error.rb} +2 -0
- data/lib/phronomy/engine/execution_receiver.rb +65 -0
- data/lib/phronomy/{execution_timeout_error.rb → engine/execution_timeout_error.rb} +2 -0
- data/lib/phronomy/engine/fsm_protocol.rb +14 -0
- data/lib/phronomy/engine/fsm_session.rb +35 -28
- data/lib/phronomy/{invalid_async_entry_action_error.rb → engine/invalid_async_entry_action_error.rb} +2 -0
- data/lib/phronomy/{invalid_async_transition_action_error.rb → engine/invalid_async_transition_action_error.rb} +2 -0
- data/lib/phronomy/{invalid_async_workflow_action_error.rb → engine/invalid_async_workflow_action_error.rb} +2 -0
- 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.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_result.rb +4 -0
- 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_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 +5 -5
- data/lib/phronomy/{agent → multi_agent}/handoff_runner.rb +18 -17
- data/lib/phronomy/multi_agent/orchestrator.rb +2 -2
- 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/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 +1 -1
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/{workflow.rb → workflow/execution/workflow.rb} +8 -6
- 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} +122 -71
- 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 +2 -2
- data/lib/phronomy/workflow/storage_contract/workflow_storage_schema.rb +9 -0
- data/lib/phronomy.rb +52 -94
- data/scripts/api_snapshot.rb +1 -1
- data/scripts/storage_spi_snapshot.rb +36 -0
- data/sig/phronomy/agent.rbs +0 -1
- data/sig/phronomy/execution_receiver.rbs +34 -0
- data/sig/phronomy/handoff.rbs +4 -2
- data/sig/phronomy/multi_agent.rbs +18 -0
- data/sig/phronomy/persistence.rbs +7 -91
- data/sig/phronomy/storage.rbs +174 -0
- data/sig/phronomy/tool.rbs +10 -1
- metadata +230 -99
- data/lib/phronomy/agent/execution_coordinator.rb +0 -3151
- 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/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/agent/{tool_invocation_session_builder.rb → tool_execution/tool_invocation_session_builder.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/{invocation_context.rb → engine/invocation_context.rb} +0 -0
- /data/lib/phronomy/{metrics.rb → engine/metrics.rb} +0 -0
- /data/lib/phronomy/{runnable.rb → engine/runnable.rb} +0 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# Remaining responsibility refactoring
|
|
2
|
+
|
|
3
|
+
This tracks responsibility work, remaining proposals and acceptance gates; it does
|
|
4
|
+
not define a new Storage SPI or Workflow lifecycle contract. The historical
|
|
5
|
+
inventory baseline was core `e4ad9948798a4f165d052bd8ab5ac3574cf48e24`
|
|
6
|
+
and examples `2f8b467f1268dd21de4c02b1c90c8bdd211d1feb` on `refactor/architecture`.
|
|
7
|
+
|
|
8
|
+
W1 is now verified at core `42f61514929645662e16b571afff9f4060d867d1`.
|
|
9
|
+
W2a is applied and verified at core `01cd2f57549f6d1e60825254f4520d0f123e651c`.
|
|
10
|
+
W2b is applied and verified at core `fcd434c45ad98e5c93953cbce1ffef3c12246894`. See the
|
|
11
|
+
[W2 design review](workflow-terminal-ownership-design.md) and
|
|
12
|
+
[ADR-056](../decisions/056-workflow-terminal-policy-ownership.md).
|
|
13
|
+
|
|
14
|
+
The current applied baseline is core
|
|
15
|
+
`5c4c039273eb2324fcc9e9943ccf40bd1ffb3abd` and examples
|
|
16
|
+
`68a0bbd0e354b9e00bbfed728ad2b769b389ed8a` (Refactor 43; examples unchanged).
|
|
17
|
+
S2b/S2c were verified on Refactor 35, including PostgreSQL CI against its
|
|
18
|
+
core ebd99623 / examples 68a0bbd0 pair.
|
|
19
|
+
Refactor 36's S3, Refactor 37's D02, Refactor 38's R03/R11, Refactor 39's R06
|
|
20
|
+
and Refactor 40's R07 are applied and verified, as is Refactor 41's R08/D08.
|
|
21
|
+
The diagram is on applied43-01. Refactor 42 Tool binding and current DSL
|
|
22
|
+
contracts and Refactor 43 Chat/state ownership are applied and verified; R09
|
|
23
|
+
is closed. Refactor 44 implements R10, pending application verification. The
|
|
24
|
+
new Tool schema recording finding remains open. See the
|
|
25
|
+
[closure review](refactoring-closure.md) for retained names, evidence and limits.
|
|
26
|
+
|
|
27
|
+
## Completed boundaries
|
|
28
|
+
|
|
29
|
+
ExecutionCoordinator's staged split, ToolInvocation restoration ownership and
|
|
30
|
+
SharedState's MultiAgent ownership are complete. Domain codecs/repositories
|
|
31
|
+
already belong to Agent, MultiAgent and Workflow (ADR-033). Raw storage conflicts
|
|
32
|
+
already use Storage-owned exceptions (ADR-043). `FSMProtocol::FINISH` already
|
|
33
|
+
owns the common terminal marker; that earlier constant dependency is not the
|
|
34
|
+
remaining Workflow problem.
|
|
35
|
+
|
|
36
|
+
## Execution order and completion gates
|
|
37
|
+
|
|
38
|
+
| Step | Remaining concern | Scope and completion gate |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| W1: Refactor 31 | Two terminal-save implementations, selected by prepend | Applied and verified. The active F1-aware implementation belongs to Runner and the override is removed. See [ADR-054](../decisions/054-workflow-terminal-save-single-owner.md). |
|
|
41
|
+
| W2a: Refactor 32 | Terminal observer exceptions leave stream and admission pending | Keep the error path open through notification, preserve the original exception and any confirmed save, and verify application before ownership extraction. See [ADR-055](../decisions/055-terminal-observer-failure-settlement.md). Applied and verified at 01cd2f57. |
|
|
42
|
+
| W2b: Workflow terminal ownership | FSMSession interprets `workflow_terminal_persistence_result` and success/known-failure/unknown outcomes | Applied and verified in Refactor 33 at fcd434c4; WorkflowTerminalPolicy and FSMProtocol::TerminalDecision own the boundary. Preserve session identity, event acceptance, stream barriers, admission retention/release and Task ordering. Do not simply hide the same Workflow policy behind renamed Engine methods. |
|
|
43
|
+
| S1: Storage contract design | Eight fixed repository slots and Agent watermark are in the shared contract | Design completed: Records/Streams/Blobs with conditions and guarded checks. The existing 37 raw methods have been inventoried; S2b now implements that design. |
|
|
44
|
+
| S2a: Refactor 34 | Existing update, batch validation and nested transaction differences | Applied and verified at core ac07b6d4 / examples ae538996, including PostgreSQL 17.11 on Ruby 3.2/3.3/3.4. See ADR-057. |
|
|
45
|
+
| S2b: Neutral Storage SPI | Common/domain contracts and all backends must agree | Applied and verified at ebd99623 / 68a0bbd0: Records/Streams/Blobs, feature schemas/adapters, failed-view lifecycle and non-local-exit rollback. See ADR-058. |
|
|
46
|
+
| S2c: Integration and migration | Physical backends must satisfy the same contract | Completed for Refactor 35. PostgreSQL 17.11 on Ruby 3.2/3.3/3.4: 119 examples per version; SQLite: 116. All 13 CI jobs checked out the verified core/examples pair. API/RBS, gem, round-trip data compatibility and applied trees were verified. |
|
|
47
|
+
| S3: Naming and closure | Common framework naming and public Persistence facade can be conflated | Reviewed and implemented in Refactor 36: retain public Persistence, neutral Storage, feature schemas and separate composition; move resource-reference normalization from generic Validation to Resource. Update stale status documents. Applied and verified at d98822b3; do not rename merely to simplify a diagram. |
|
|
48
|
+
|
|
49
|
+
W1 precedes W2 so the active terminal save is explicit before its session-facing
|
|
50
|
+
ownership changes. W2 can be completed without redesigning Storage's raw SPI.
|
|
51
|
+
Storage follows because its common contract affects all domain repositories and
|
|
52
|
+
both SQL reference implementations. Verify the applied commit before producing
|
|
53
|
+
the next dependent source package.
|
|
54
|
+
|
|
55
|
+
## W2 implemented boundary
|
|
56
|
+
|
|
57
|
+
Runner retains snapshot capture, Offload submission, one save and F1 readback.
|
|
58
|
+
WorkflowTerminalPolicy recognizes the Workflow result event and interprets its
|
|
59
|
+
outcomes. FSMSession receives only complete/fail/retire decisions and owns its
|
|
60
|
+
pending state; Registry remains the sole Workflow admission owner.
|
|
61
|
+
|
|
62
|
+
The private terminal_policy injection replaces terminal_barrier, without a
|
|
63
|
+
public plugin API or alias. Agent/Tool and ephemeral Workflow keep immediate
|
|
64
|
+
completion. Unknown outcomes retain admission and an unresolved caller until
|
|
65
|
+
normal shutdown clears admission; shutdown does not synthesize a caller result.
|
|
66
|
+
Refactor 32's observer-error ordering and committed snapshot are preserved.
|
|
67
|
+
|
|
68
|
+
The candidate tests delayed success, known failures, F1 reconciliation,
|
|
69
|
+
uncertainty/shutdown, early/duplicate/late events, ordinary events during the
|
|
70
|
+
barrier, observer errors, rejected submission/delivery and shared Agent/Tool
|
|
71
|
+
behavior. Its application verification is complete; Storage S1 design followed.
|
|
72
|
+
|
|
73
|
+
## S1 baseline operation inventory (before SPI 2)
|
|
74
|
+
|
|
75
|
+
Removing Agent/Workflow constant references did not make the SPI domain-neutral.
|
|
76
|
+
`Storage::Backend < Storage::Repositories` constructed eight required slots;
|
|
77
|
+
`assert_agent_watermark!` checks Agent revision and Journal position together.
|
|
78
|
+
|
|
79
|
+
| Current area | Existing constraint to preserve | Ownership/design question |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| Contents | Canonical content identity and reads/writes join the same transaction | Keep the content contract without coupling it to an execution owner. |
|
|
82
|
+
| Agents / Teams | Key identity and expected/next revision CAS | Separate physical compare-and-write from domain record validation. |
|
|
83
|
+
| Journals | Expected head position, append order and record identity | Preserve atomic append; a generic key/value write alone is insufficient. |
|
|
84
|
+
| Agent / Team executions | Atomic active-owner exclusion, immutable owner identity, revision checks and indexed queries | Decide a neutral constraint/index primitive or explicit domain-owned extension; never replace atomic admission with an unlocked preflight. |
|
|
85
|
+
| Workflow / Handoff states | Create/update/delete CAS and stored identity | Preserve nil pre-revision creation and conditional deletion, with domain interpretation above the raw contract. |
|
|
86
|
+
| Agent watermark | Revision and Journal head observed consistently with subsequent writes | Express a multi-record precondition or domain-owned transaction operation, not independent reads above the backend. |
|
|
87
|
+
| Transaction view | All eight repositories, content and watermark share one view | Keep InMemory's one Monitor/snapshot and each SQL view's one checked-out connection; splitting classes must not split commits. |
|
|
88
|
+
| Errors / capability declarations | Dedicated active constraint errors, ordinary conflicts and uncertainty remain distinct | Revisit domain terms in capabilities without adding stronger concurrency or commit-certainty promises. |
|
|
89
|
+
|
|
90
|
+
Reference implementations live in `storage/backends/in_memory.rb` and examples
|
|
91
|
+
`30_sqlite_persistence` / `31_postgresql_persistence`. Inspect SQL indexes, lock
|
|
92
|
+
order, connection binding and rollback as well as Ruby signatures. Storage's
|
|
93
|
+
existing Agent/Team implementations have different details; do not assume they
|
|
94
|
+
are interchangeable just because their method names resemble each other.
|
|
95
|
+
|
|
96
|
+
S1 must produce a mapping from every current operation to its owner and atomic
|
|
97
|
+
primitive, plus API/RBS migration and backend conformance gates. Do not adopt a
|
|
98
|
+
generic key/value API, callbacks inside transactions or a registry of arbitrary
|
|
99
|
+
operations merely to erase domain names. Keep record type/version/payload,
|
|
100
|
+
existing F0/F1/F4 limits and the X0 external-effect boundary explicit.
|
|
101
|
+
|
|
102
|
+
See the existing [persistence staged plan](persistence-refactoring-plan.md),
|
|
103
|
+
[ADR-033](../decisions/033-domain-persistence-ownership.md) and
|
|
104
|
+
[ADR-043](../decisions/043-storage-execution-constraint-notifications.md).
|
|
105
|
+
|
|
106
|
+
## S2a and S2b applied boundaries
|
|
107
|
+
|
|
108
|
+
[ADR-057](../decisions/057-storage-transaction-boundaries.md) records the three
|
|
109
|
+
behavioral changes. The [migration guide](../migrations/storage-transaction-boundaries.md)
|
|
110
|
+
explains nested savepoints and propagated ActiveRecord::Rollback. Complete batch
|
|
111
|
+
validation prevents invalid input from leaving partial Journal rows; it does not
|
|
112
|
+
make arbitrary database failures safe to catch inside the failed scope.
|
|
113
|
+
|
|
114
|
+
S2a alone did not complete Storage. Refactor 35 subsequently implemented the
|
|
115
|
+
neutral SPI, failed-view rules and non-local exits, then passed live PostgreSQL
|
|
116
|
+
acceptance against the applied core/examples pair. Reference SQL code parity
|
|
117
|
+
alone was not used as PostgreSQL execution evidence.
|
|
118
|
+
|
|
119
|
+
## Refactor 35 verification history
|
|
120
|
+
|
|
121
|
+
Core baseline: ac07b6d4b47167ae404c8ecad8450e80a0087754.
|
|
122
|
+
Examples baseline: ae538996fd276faa3dac0990839e9cf115e6dff6.
|
|
123
|
+
S2b changes the raw SPI and both SQL implementations together. Domain APIs and
|
|
124
|
+
stored formats remain. Candidate checks include InMemory, real SQLite, generic
|
|
125
|
+
resource declarations, scope failures and old/new/old SQLite data compatibility.
|
|
126
|
+
The applied pair above passed all three examples workflows, including
|
|
127
|
+
[PostgreSQL](https://github.com/Raizo-TCS/phronomy-examples/actions/runs/35827495677),
|
|
128
|
+
[SQLite](https://github.com/Raizo-TCS/phronomy-examples/actions/runs/35827495667) and
|
|
129
|
+
[current API](https://github.com/Raizo-TCS/phronomy-examples/actions/runs/35827495646).
|
|
130
|
+
Each job's checkout SHA was verified, not just its green status. Core remote
|
|
131
|
+
workflows had no runs; local core suites supplied that evidence.
|
|
132
|
+
|
|
133
|
+
## Closure boundary
|
|
134
|
+
|
|
135
|
+
W1, W2a, W2b, S1, S2a, S2b and S2c are applied and verified. S3's bounded Storage
|
|
136
|
+
cleanup and audit are applied and verified in Refactor 36.
|
|
137
|
+
The original review is not fully implemented: the W/S-only inventory omitted
|
|
138
|
+
D02, R03's metadata boundary, R06, R07, R08/D08, parts of R09, R10 and R11.
|
|
139
|
+
See the reconciled inventory below; do not count those proposals as completed.
|
|
140
|
+
Keep the published dependency SVG tied to applied41-01 until Refactor 42 application verification. Performance benchmarking, live-LLM behavior,
|
|
141
|
+
distributed ownership and unknown-outcome recovery policy are separate scopes,
|
|
142
|
+
not silently added requirements for this responsibility refactoring.
|
|
143
|
+
|
|
144
|
+
## Initial review proposals and current disposition
|
|
145
|
+
|
|
146
|
+
| Initial item | Current assessment and follow-up |
|
|
147
|
+
|---|---|
|
|
148
|
+
| D02 | Applied and verified in Refactor 37: callers construct OperationBinding directly and retain ordering and cancellation contracts. |
|
|
149
|
+
| R03 | Applied and verified in Refactor 38: ExecutionMetadata owns shared durable keys and snapshots; ToolInvocation owns stable identity. Earlier restoration behavior is preserved. |
|
|
150
|
+
| R06 | Applied and verified in Refactor 39: InvocationTransitions owns Tool events, ordered external transitions and state declarations for both builders and Invocation. |
|
|
151
|
+
| R07 | Applied and verified in Refactor 40: ContextAssembler describes preparation through private instruction, record-candidate, candidate-merge and current-input operations. |
|
|
152
|
+
| R08 / D08 | Applied and verified in Refactor 41, one overlapping item: GeneratorVerifier keeps its facade and Result; private WorkflowBuilder, AgentResultReceiver and the moved PipelineState separate graph construction, reception and state. |
|
|
153
|
+
| R09 | Applied and verified in Refactors 42 and 43: Tool binding, declaration rules, Chat construction and explicit state ownership. Existing DSL behavior is retained. |
|
|
154
|
+
| R10 | Implemented in Refactor 44: private actions describe prepared-input installation and runtime Chat construction; Team-generated text describes business tasks. Application verification is pending. |
|
|
155
|
+
| R11 | Applied and verified in Refactor 38: Values::Serializable owns recursive conversion. Caller-specific diagnostics and distinct immutable/canonical/codec contracts remain. |
|
|
156
|
+
|
|
157
|
+
R08/D08 is one work item. R03's Tool restoration and shared metadata ownership
|
|
158
|
+
are complete; do not reopen those contracts. R09's configuration inheritance can
|
|
159
|
+
change public behavior and needs its own explicit decision. These are existing
|
|
160
|
+
proposals rediscovered by the S3 audit, not new performance or distributed-runtime
|
|
161
|
+
requirements. D02, R03/R11, R06, R07 and R08/D08 are applied and verified.
|
|
162
|
+
Refactor 43 application is verified and R09 is closed. Refactor 44 implements
|
|
163
|
+
R10; verify its application before closure. Track the new Tool schema finding
|
|
164
|
+
separately from the original R/D inventory.
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
## D02: direct operation binding (Refactor 37, applied)
|
|
168
|
+
|
|
169
|
+
OperationBinding already owns invocation context validation, its private linked
|
|
170
|
+
cancellation token, deadline subscriptions and result-scoped cleanup. Its three
|
|
171
|
+
clients now construct it directly. Execution's pass-through factory has no
|
|
172
|
+
additional behavior and is removed without an alias or replacement factory.
|
|
173
|
+
|
|
174
|
+
Construction remains at the same points: Agent before command admission,
|
|
175
|
+
Blocking only with an explicit context and before Offload submission, and
|
|
176
|
+
Orchestrator for each child before invoke_async. Keep bind/track/close ordering,
|
|
177
|
+
error handling, context selection and cancellation ownership unchanged.
|
|
178
|
+
Orchestrator still uses Execution for fan-out/fan-in; that dependency is intended.
|
|
179
|
+
The internal OperationBinding signature and body, except its ownership comment,
|
|
180
|
+
are unchanged. No class, production file, public API or examples change is added.
|
|
181
|
+
|
|
182
|
+
The distribution is applied and verified at e7e66184. D02 is closed.
|
|
183
|
+
Seven initial-proposal groups remained at that point; R03/R11 are now applied below.
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
## R03/R11: shared execution metadata and conversion (Refactor 38, applied)
|
|
187
|
+
|
|
188
|
+
See [the ownership and compatibility design](execution-metadata-and-values.md).
|
|
189
|
+
ExecutionMetadata owns the shared keys, version, snapshot and merge.
|
|
190
|
+
ToolInvocation.semantic_id owns the stable Tool identity, while
|
|
191
|
+
Values::Serializable owns recursive Ruby-to-JSON-tree conversion.
|
|
192
|
+
RecoverySupport retains recovery interpretation; the existing conversion entry
|
|
193
|
+
points retain their distinct diagnostics. No new restoration, transaction or
|
|
194
|
+
external-operation behavior is introduced.
|
|
195
|
+
|
|
196
|
+
Refactor 38 is applied and independently verified at core 690b2823, tree
|
|
197
|
+
67ea6df833254341043c3fb1e99729d66f9598f6. All 30 full files and the tree match.
|
|
198
|
+
Core 2,970 (61 pending), integration 367 (28 pending), common examples 42 and
|
|
199
|
+
SQLite 116 passed with zero failures, as did API/RBS, style and gem checks.
|
|
200
|
+
R03/R11 are closed. Five groups remained at that point; R06 is now applied below.
|
|
201
|
+
The diagram was synchronized to applied38-01 then and is now applied42-01.
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
## R06: Agent transition ownership (Refactor 39, applied)
|
|
205
|
+
|
|
206
|
+
See [the transition ownership design](agent-transition-ownership.md).
|
|
207
|
+
InvocationTransitions owns the six Tool event names, thirteen external event
|
|
208
|
+
families and their ordered transitions, initial phase and state classifications.
|
|
209
|
+
PhaseMachineBuilder compiles the external transitions into state_machines;
|
|
210
|
+
AgentInvocationSessionBuilder passes the same definition to FSMSession.
|
|
211
|
+
AgentInvocation uses the Tool vocabulary to identify payloads it handles.
|
|
212
|
+
|
|
213
|
+
FSMSession still uses only source-state declarations to decide whether an
|
|
214
|
+
external event is accepted or a phase must wait. The machine evaluates guards
|
|
215
|
+
against the current context, after payload application. Engine does not acquire
|
|
216
|
+
Agent policy, and automatic transitions and entry actions keep their owners.
|
|
217
|
+
No new generic DSL, compatibility alias, public API or persistence format is added.
|
|
218
|
+
R10's entry-action names and R09's DSL inheritance semantics are separate work.
|
|
219
|
+
|
|
220
|
+
The implementation preserves callback-failure, Handoff-failure, Handoff-request,
|
|
221
|
+
Tool-request and output-fallback priority, nil-context fallback, guard exceptions,
|
|
222
|
+
approval suspension and resume. Independent behavioral expectations pass on both
|
|
223
|
+
baseline and candidate; full-suite results are in the distribution evidence.
|
|
224
|
+
Refactor 39 is applied and independently verified at core 4d57614a, tree
|
|
225
|
+
654241da4b2b7f32d988602d28127bc1fa155641. All 10 full files and the tree match.
|
|
226
|
+
Core 2,993 (61 pending), integration 367 (28 pending), common examples 42 and
|
|
227
|
+
SQLite 116 passed with zero failures, as did API/RBS, style and gem checks.
|
|
228
|
+
R06 is closed. Four groups remained then; R07 is now applied below.
|
|
229
|
+
The diagram was synchronized to applied39-01 then and is now applied42-01.
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
## R07: Context preparation steps (Refactor 40, applied)
|
|
233
|
+
|
|
234
|
+
See [the preparation design and compatibility boundaries](context-preparation-steps.md).
|
|
235
|
+
ContextAssembler retains its public preparation/finalization boundary and its
|
|
236
|
+
existing collaborators. Seven private operations separate initial/base/Handoff
|
|
237
|
+
instructions, retained instructions, record candidates, Hook/Handoff merging
|
|
238
|
+
and the current-input item. No production class or file is added.
|
|
239
|
+
|
|
240
|
+
The public prepare methods now describe the preparation steps; item IDs,
|
|
241
|
+
provenance and metadata live in the corresponding item-building operation.
|
|
242
|
+
Initial and follow-up paths share generation filtering and candidate merging,
|
|
243
|
+
while preserving their distinct instruction sources, exclusion rules, call
|
|
244
|
+
sequence and ask/complete delivery. Evaluation and content-store effects retain
|
|
245
|
+
their order. Application Policy remains outside the caller's commit transaction;
|
|
246
|
+
finalize remains validation and persistence, without a Policy call.
|
|
247
|
+
|
|
248
|
+
Ten additional contract examples pass against both Refactor 39 and the candidate.
|
|
249
|
+
Four paired initial/follow-up scenarios compare complete Policy input, Prepared,
|
|
250
|
+
Manifest references/bytes and content operations across separate processes.
|
|
251
|
+
Full core/integration/examples/API/type/package gates are in the distribution.
|
|
252
|
+
|
|
253
|
+
Refactor 40 is applied and independently verified at core b3dfbc5a, tree
|
|
254
|
+
dcd9d1bf8efb1b488f9c2b3b1c4e99bdeda6096c. All six files and the tree match.
|
|
255
|
+
Core 3,003 (61 pending), integration 367 (28 pending), common examples 42 and
|
|
256
|
+
SQLite 116 passed with zero failures, as did API/RBS, style, gem and four paired
|
|
257
|
+
preparation scenarios. R07 is closed. Three groups remained at that point; R08/D08 is now applied below.
|
|
258
|
+
The published diagram is applied42-01; keep it until Refactor 43 application checks.
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
## R08/D08: GeneratorVerifier ownership (Refactor 41, applied)
|
|
262
|
+
|
|
263
|
+
See [the ownership and event-contract design](generator-verifier-ownership.md).
|
|
264
|
+
The public facade retains configuration, lazy Workflow caching, default parsers
|
|
265
|
+
and Result construction. Private WorkflowBuilder owns graph assembly, request
|
|
266
|
+
startup and convergence. Private AgentResultReceiver converts Agent terminal
|
|
267
|
+
events into correlated Workflow events. PipelineState moves without changing its
|
|
268
|
+
canonical name, fields, correlation checks or mutation behavior.
|
|
269
|
+
|
|
270
|
+
The three implementation files live below generation/generator_verifier. No
|
|
271
|
+
loader change or alias is needed. This updates the original D08 location sketch:
|
|
272
|
+
the pattern already has generation ownership, so it does not move to MultiAgent.
|
|
273
|
+
Draft/review payload meanings remain separate. Only their identical terminal
|
|
274
|
+
classification, completion-notification rescue and failure notification are shared.
|
|
275
|
+
The receiver holds no request-specific mutable state and never mutates Workflow
|
|
276
|
+
context; PipelineState still applies accepted results on the EventLoop.
|
|
277
|
+
|
|
278
|
+
Thirty-nine additional event-contract examples pass on both baseline and candidate,
|
|
279
|
+
including inline completion, failures, parser/notification exceptions, old and
|
|
280
|
+
duplicate results, normalization, convergence, caching and config forwarding.
|
|
281
|
+
The public signature/Result/state contract also matches. Full gates are recorded
|
|
282
|
+
in the distribution. Existing semantics remain: final trust is score-based, even
|
|
283
|
+
if an unapproved high-score draft is finalized at the iteration limit.
|
|
284
|
+
|
|
285
|
+
Refactor 41 is applied and independently verified at core e87eb77f, tree
|
|
286
|
+
14dc8a546a4fd96e19e0713f7480ca2efa3c331a. All nine files and the full tree match.
|
|
287
|
+
Core 3,042 (61 pending), integration 367 (28 pending), common examples 42 and
|
|
288
|
+
SQLite 116 passed with zero failures, as did API/RBS, style, gem and explicit
|
|
289
|
+
public/Result/state comparisons. R08/D08 is closed; R09 and R10 remain.
|
|
290
|
+
The diagram is applied41-01.
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
## R09: Tool binding and declaration rules (Refactor 42, applied)
|
|
294
|
+
|
|
295
|
+
See [the boundary design and inheritance matrix](agent-configuration-and-tool-binding.md).
|
|
296
|
+
Base retains its preparation hook, non-Class passthrough and setting selection.
|
|
297
|
+
Agent::ToolBinding creates alias/filter decorators and forwards custom async
|
|
298
|
+
logical/physical completion. The default async path stays inherited to avoid
|
|
299
|
+
applying filters twice. ToolInvocation and Orchestrator retain their owners.
|
|
300
|
+
No Agent reference or private callback into Base is passed to ToolBinding.
|
|
301
|
+
|
|
302
|
+
Thirty-five new examples pass on both baseline and candidate. Current DSL rules
|
|
303
|
+
are explicit, including non-inherited model/budgets/filters, live parent lookups,
|
|
304
|
+
shared instructions/policy/Tool-list values and inherited aliases that nil does
|
|
305
|
+
not remove. This package does not unify public configuration behavior.
|
|
306
|
+
|
|
307
|
+
Refactor 42 is applied and verified at core 4a57a3c2, tree
|
|
308
|
+
1a43ec3fecd5457e4314afa3807eb862bbd16b52. All nine files and the tree match.
|
|
309
|
+
Core 3,077 (61 pending), integration 367 (28 pending), examples 42, SQLite 116
|
|
310
|
+
and the packaged persistence contract 41 pass with zero failures. Public
|
|
311
|
+
contracts, API/SPI, types, style and gem loading also pass. This closes the
|
|
312
|
+
first slice; the original R09 Chat/state scope is addressed below.
|
|
313
|
+
|
|
314
|
+
## R09: Chat construction and explicit state ownership (Refactor 43, applied)
|
|
315
|
+
|
|
316
|
+
See [the Chat/state ownership design](agent-chat-and-state-ownership.md).
|
|
317
|
+
RuntimeChatBuilder owns provider Chat creation, settings and cached instructions.
|
|
318
|
+
StateWriter owns initial root/context/knowledge writes and explicit idle-Agent
|
|
319
|
+
mutations, using the captured root and one transaction. Both live in the existing
|
|
320
|
+
context_assembly directory. They hold no Agent reference or private callbacks.
|
|
321
|
+
|
|
322
|
+
Base keeps the facade, live-owner checks, root proposals and publication. Its
|
|
323
|
+
projection hook preserves instruction/Tool/message order and existing overrides.
|
|
324
|
+
The writer returns root and records only after the transaction returns; Base
|
|
325
|
+
publishes Journal records before replacing the live root. Initial input order,
|
|
326
|
+
idle checks, CAS, revisions, exception identity and rollback behavior are retained.
|
|
327
|
+
Unknown commits, local publication failure and application-owned outer
|
|
328
|
+
transactions retain their existing limitations; no new reconciliation is added.
|
|
329
|
+
|
|
330
|
+
Thirty-seven new behavioral examples pass against both Refactor 42 and the
|
|
331
|
+
candidate. Full core/integration/examples/SQLite and API/SPI/type/style/package
|
|
332
|
+
gates are recorded in the distribution. Static dependency analysis preserves
|
|
333
|
+
all existing cycle memberships, with one new context_assembly -> lifecycle pair.
|
|
334
|
+
This improves responsibility boundaries; it does not remove existing cycles.
|
|
335
|
+
|
|
336
|
+
Refactor 43 is applied and verified at 5c4c0392, tree
|
|
337
|
+
841bc7b5b28c2d31380ee4a12ffdc22a85ee3c37. All ten files and the full tree match.
|
|
338
|
+
Core 3,114 (61 pending), integration 367 (28 pending), examples 42, SQLite 116
|
|
339
|
+
and gem contract 41 pass with zero failures. R09 is closed; SVG is applied43-01.
|
|
340
|
+
No live-LLM, live PostgreSQL, remote-CI success or performance claim follows
|
|
341
|
+
from that local validation.
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
## R10: Entry actions and Team wording (Refactor 44 candidate)
|
|
345
|
+
|
|
346
|
+
See [the naming and compatibility boundary](entry-action-and-team-wording.md).
|
|
347
|
+
Only two private action names and two generated Team strings change in production.
|
|
348
|
+
State/event vocabulary and action bodies stay unchanged. Legacy saved operation
|
|
349
|
+
results are returned as stored; new operations use business-task wording.
|
|
350
|
+
The original R/D inventory has no other unimplemented item, but R10 remains
|
|
351
|
+
pending application verification.
|
|
352
|
+
|
|
353
|
+
## New open finding: Tool parameter schema recording
|
|
354
|
+
|
|
355
|
+
The [Tool schema recording gap](tool-schema-recording-gap.md) was reproduced on
|
|
356
|
+
Refactor 43 and Refactor 44 with RubyLLM 1.16.0. The actual schema reader is
|
|
357
|
+
`params_schema`, whereas ToolDefinitionSet records `{}` when its expected
|
|
358
|
+
`parameters_schema` reader is absent. A required/type change can evade the saved
|
|
359
|
+
comparison. This is the next correctness issue to design, with explicit handling
|
|
360
|
+
of historical manifests. It is not fixed by R10 or by passing its recovery tests.
|
|
361
|
+
|
|
362
|
+
## Refactor 44 applied; Refactor 45 migration candidate
|
|
363
|
+
|
|
364
|
+
R10 was applied at 99ee43cd7b48174d825d20876fc38bbe47e6da11, tree
|
|
365
|
+
34de332df150ff28ac93b2d04e099197f4a214d1, and verified. The original R/D inventory
|
|
366
|
+
is closed. Earlier candidate wording above is historical.
|
|
367
|
+
|
|
368
|
+
RubyLLM 2.0.0 now supplies the awaited provider-neutral output cap.
|
|
369
|
+
[Refactor 45](rubyllm-2-token-ownership.md) implements the dependency/API migration,
|
|
370
|
+
input-only registry budgeting, output-cap forwarding, schema recording/comparison
|
|
371
|
+
and coordinated examples migration. The schema issue is addressed in this candidate;
|
|
372
|
+
old empty-schema manifests require completion on the original version before upgrade.
|
|
373
|
+
Local verification and the exact package trees are recorded in the distribution.
|
|
374
|
+
User application verification remains outstanding; this is not a published release.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# RubyLLM 2.0 and token ownership (Refactor 45)
|
|
2
|
+
|
|
3
|
+
This candidate targets RubyLLM 2.0.x (`~> 2.0.0`), verified with 2.0.0.
|
|
4
|
+
It implements the previously deferred token-ownership plan against the current
|
|
5
|
+
0.26.0 refactoring branch. It does not publish or renumber the Phronomy gem.
|
|
6
|
+
|
|
7
|
+
## Ownership
|
|
8
|
+
|
|
9
|
+
| Concern | Owner and behavior |
|
|
10
|
+
|---|---|
|
|
11
|
+
| Input capability | RubyLLM model registry `context_window`, defined by RubyLLM 2 as maximum input tokens |
|
|
12
|
+
| Model lookup | `RubyLLM.models.find(model, provider: provider)` |
|
|
13
|
+
| Input budget | Phronomy `TokenBudget(max_input_tokens:)`, using that limit directly |
|
|
14
|
+
| Unknown/invalid input limit | No hard token budget; no invented limit or reserve |
|
|
15
|
+
| Requested output cap | Agent `max_output_tokens`, positive Integer; stored in model_config |
|
|
16
|
+
| Output request rendering | RubyLLM `Chat#with_max_output_tokens`; all wire names remain upstream |
|
|
17
|
+
| Context selection | Phronomy ContextPolicy and final Manifest validation |
|
|
18
|
+
| Replay | Recorded Manifest segments and request intent; no current-budget reselection |
|
|
19
|
+
|
|
20
|
+
Remove application calls to `Agent.context_window` and
|
|
21
|
+
`configuration.default_output_reserve`. They no longer exist.
|
|
22
|
+
`before_llm_input` patches containing `context_window` raise ConfigurationError;
|
|
23
|
+
register custom/local model metadata through RubyLLM's public registry loader.
|
|
24
|
+
`max_output_tokens` does not reduce the input budget and is not inferred from
|
|
25
|
+
registry output capacity. Omit it to use RubyLLM/provider defaults.
|
|
26
|
+
The obsolete InvalidContextBudgetConfigurationError has also been removed.
|
|
27
|
+
New manifests have assembly policy version 9. Historical model_config keys are
|
|
28
|
+
not rewritten during materialization, and the runtime builder forwards only
|
|
29
|
+
supported request settings.
|
|
30
|
+
|
|
31
|
+
## RubyLLM 2 compatibility
|
|
32
|
+
|
|
33
|
+
The adapter uses `with_tools`, keyword Tool execution, `parameters_schema`,
|
|
34
|
+
`provider_options`, `Message#model`, and `Tokens#cache_read/#cache_write`.
|
|
35
|
+
Phronomy's `param`, `params`, `with_params`, `params_schema`, and `provider_params`
|
|
36
|
+
remain available as its own Tool contract. RubyLLM 2's derived class tool name
|
|
37
|
+
is used when no explicit name is supplied. Structured historical content is
|
|
38
|
+
encoded as JSON text when materialized into RubyLLM 2 Messages. Stored canonical
|
|
39
|
+
content is unchanged. Phronomy TokenUsage retains its cached/cache_creation names;
|
|
40
|
+
recovery reads both the historical and new RubyLLM counter keys.
|
|
41
|
+
|
|
42
|
+
Cached instructions use `with_instructions(..., cache_until_here:)`.
|
|
43
|
+
No RubyLLM 1.x guard, monkeypatch, or provider-specific output mapping remains.
|
|
44
|
+
Applications choose protocol settings in RubyLLM. Its OpenAI default is Responses;
|
|
45
|
+
local Chat Completions endpoints must configure `openai_protocol = :chat_completions`.
|
|
46
|
+
|
|
47
|
+
Tool batches are intercepted through `after_message`, after RubyLLM has appended
|
|
48
|
+
the complete assistant Message and before RubyLLM's approval/Tool execution loop.
|
|
49
|
+
Phronomy's existing authorization, suspension and batch execution paths therefore
|
|
50
|
+
remain authoritative. Tool classes and their approval declarations are not
|
|
51
|
+
rewritten to bypass RubyLLM's gate.
|
|
52
|
+
|
|
53
|
+
## Saved Tool definitions and deployment
|
|
54
|
+
|
|
55
|
+
The previous empty-schema fallback concealed argument changes. New definitions
|
|
56
|
+
record the actual schema and provider options and compare them canonically.
|
|
57
|
+
Changes to argument type, requiredness, enum or provider options are rejected.
|
|
58
|
+
|
|
59
|
+
An old `{}` schema cannot establish which parameters were originally authorized.
|
|
60
|
+
The migration fails closed with an explicit diagnostic when such a saved
|
|
61
|
+
Manifest is materialized; it does not synthesize or weaken historical definitions.
|
|
62
|
+
Before updating, finish outstanding Agent, Workflow and Team operations that may
|
|
63
|
+
need old Tool-bearing manifests on the old core/RubyLLM combination, and retain
|
|
64
|
+
backups of durable storage. Do not perform a rolling upgrade with mixed versions
|
|
65
|
+
sharing those in-flight executions. Completed history is not rewritten; starting
|
|
66
|
+
a new invocation creates a current schema-bearing manifest. This is a deployment
|
|
67
|
+
boundary, not an automatic historical-data repair.
|
|
68
|
+
|
|
69
|
+
## Examples and verification
|
|
70
|
+
|
|
71
|
+
The shared examples configuration registers explicit PHRONOMY_CONTEXT_WINDOW or
|
|
72
|
+
observed local metadata via `RubyLLM.models.load_from_json`, retaining other model
|
|
73
|
+
entries. An unavailable local limit remains nil, including when the local server
|
|
74
|
+
uses a cloud model's name. Code-review chunking requires known metadata explicitly.
|
|
75
|
+
Request output caps are independent constants. Rails examples use the same setup.
|
|
76
|
+
|
|
77
|
+
Tests cover provider-qualified input budgets, missing metadata, output forwarding,
|
|
78
|
+
forbidden hook overrides, saved intent without reselection, actual Tool schema
|
|
79
|
+
comparison, old/new usage counters, Responses Tool/approval/streaming execution,
|
|
80
|
+
and existing Chat Completions and durability behavior. Protocol rendering remains
|
|
81
|
+
RubyLLM's responsibility. Distribution evidence distinguishes HTTP stubs and local
|
|
82
|
+
SQLite from live providers, PostgreSQL and the remote Ruby-version CI matrix.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Historical finding: Tool parameter schema is absent from saved definitions
|
|
2
|
+
|
|
3
|
+
## Observed mismatch
|
|
4
|
+
|
|
5
|
+
During Refactor 44 verification, Ruby 3.3.6 with RubyLLM 1.16.0 reproduced the
|
|
6
|
+
following on both applied Refactor 43 and the Refactor 44 candidate:
|
|
7
|
+
|
|
8
|
+
1. The prepared Tool exposes its actual argument schema through `params_schema`.
|
|
9
|
+
2. `Agent::ToolDefinitionSet.build` asks for `parameters_schema`, which this Tool
|
|
10
|
+
does not respond to, and stores an empty Hash for that field.
|
|
11
|
+
3. `select_definitions` compares the stored definitions exactly, but a change
|
|
12
|
+
from optional string `summary` to required integer `summary` is accepted
|
|
13
|
+
because neither definition contains its actual argument schema.
|
|
14
|
+
|
|
15
|
+
The LLM request still includes the actual schema. The missing information is in
|
|
16
|
+
Phronomy's recorded definition and therefore in the comparison boundary. Tool
|
|
17
|
+
names and top-level descriptions are still compared; this finding does not mean
|
|
18
|
+
all Tool identity checks are absent. The source of ToolDefinitionSet is unchanged
|
|
19
|
+
by R10, and no claim is made about untested RubyLLM versions.
|
|
20
|
+
|
|
21
|
+
## Consequence
|
|
22
|
+
|
|
23
|
+
Recovery/context materialization cannot reject that incompatible argument change
|
|
24
|
+
through the saved definition comparison. The R10 parameter-description change
|
|
25
|
+
also does not cause a mismatch on this tested version. Passing old/new recovery
|
|
26
|
+
checks must not be presented as evidence that parameter compatibility is guarded.
|
|
27
|
+
|
|
28
|
+
## Required follow-up
|
|
29
|
+
|
|
30
|
+
This is an open correctness issue, separate from the R10 naming cleanup.
|
|
31
|
+
A follow-up should obtain the schema actually used by the supported adapter,
|
|
32
|
+
record it in canonical form and compare it during context selection/recovery.
|
|
33
|
+
It must also specify how to treat old saved definitions whose schema is `{}`.
|
|
34
|
+
Blindly switching the reader would make new definitions conflict with historical
|
|
35
|
+
manifests; blindly ignoring mismatches would erase the intended guard.
|
|
36
|
+
|
|
37
|
+
Acceptance requires meaningful parameter-change rejection, matching-schema
|
|
38
|
+
continuation, explicit treatment of missing historical schema, adapter-version
|
|
39
|
+
coverage and old/new recovery validation. Until that work is accepted, retain
|
|
40
|
+
this issue in the current work list. Refactor 44 does not silently migrate records
|
|
41
|
+
or change the general Tool comparison contract.
|
|
42
|
+
|
|
43
|
+
## Refactor 45 resolution candidate
|
|
44
|
+
|
|
45
|
+
[The RubyLLM 2 migration](rubyllm-2-token-ownership.md) removes the empty fallback,
|
|
46
|
+
records the actual schema/provider options and rejects incompatible definitions.
|
|
47
|
+
It explicitly rejects historical empty schemas when materializing in-flight
|
|
48
|
+
manifests. Matching current definitions continue normally. The original observation
|
|
49
|
+
above is retained as evidence; it is not a description of the new implementation.
|
|
50
|
+
Application verification of Refactor 45 remains pending.
|
|
@@ -100,7 +100,7 @@ span.
|
|
|
100
100
|
|
|
101
101
|
### `multi_agent.turn`
|
|
102
102
|
|
|
103
|
-
One coarse `MultiAgent::
|
|
103
|
+
One coarse `MultiAgent::HandoffRunner` user turn. Handoff does not create a mandatory
|
|
104
104
|
long-lived span type.
|
|
105
105
|
|
|
106
106
|
## 6. Correlation and identity
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Workflow terminal ownership: design and validation
|
|
2
|
+
|
|
3
|
+
Implementation baseline: core `01cd2f57549f6d1e60825254f4520d0f123e651c`
|
|
4
|
+
(Refactor 32 applied) and examples `2f8b467f1268dd21de4c02b1c90c8bdd211d1feb`,
|
|
5
|
+
2026-09-23. W2a and W2b are applied and verified; W2b is core
|
|
6
|
+
`fcd434c45ad98e5c93953cbce1ffef3c12246894` (Refactor 33). The adopted private contract is
|
|
7
|
+
[ADR-056](../decisions/056-workflow-terminal-policy-ownership.md).
|
|
8
|
+
|
|
9
|
+
## Role and consumers
|
|
10
|
+
|
|
11
|
+
FSMSession drives one live state machine on EventLoop. WorkflowRunner assembles
|
|
12
|
+
Workflow transitions, stream observation and any durable terminal save.
|
|
13
|
+
AgentInvocationSessionBuilder uses the same engine for input, LLM and Tool
|
|
14
|
+
progression; ToolInvocationSessionBuilder uses it for authorization, approval
|
|
15
|
+
and Tool execution. Therefore the session stays in Engine.
|
|
16
|
+
|
|
17
|
+
The former leak was narrower: Engine recognized the Workflow persistence event
|
|
18
|
+
and interpreted its save outcomes. WorkflowTerminalPolicy now owns that rule.
|
|
19
|
+
|
|
20
|
+
## Ownership and concrete boundary
|
|
21
|
+
|
|
22
|
+
| Owner | Responsibility |
|
|
23
|
+
|---|---|
|
|
24
|
+
| FSMSession | Identity/sink, transitions, live context, pending terminal kind/notification flag, event acceptance and final notification/event ordering. |
|
|
25
|
+
| WorkflowTerminalPolicy | Start the injected save callback; recognize the Workflow result event; map its outcome to a generic terminal decision. |
|
|
26
|
+
| FSMProtocol::TerminalDecision | Immutable `action` and `error` value shared by a domain policy and the session. No live session authority. |
|
|
27
|
+
| WorkflowRunner | Construct a policy for durable execution; retain snapshot capture, one save, F1 readback and caller completion. |
|
|
28
|
+
| WorkflowExecutionRegistry | Admission, owner tokens, session routing binding and recovery-required ownership. |
|
|
29
|
+
| EventLoop | Event routing, management events, retirement, source completion and shutdown. |
|
|
30
|
+
|
|
31
|
+
Runner builds a policy only when both repository and persist are enabled.
|
|
32
|
+
Agent, Tool and ephemeral Workflow need no dummy policy or delayed completion.
|
|
33
|
+
The policy retains only its persistence callback, with no lifecycle flags.
|
|
34
|
+
|
|
35
|
+
The three private operations are `start(terminal_type:, context:, event_sink:)`,
|
|
36
|
+
`handles?(event)` and `decision_for(event)`. Start does not return completion
|
|
37
|
+
permission. The decision value maps Workflow success to `complete`, known
|
|
38
|
+
failure to `fail`, and unresolved uncertainty to `retire`. Failure preserves the
|
|
39
|
+
original exception or the existing missing-error fallback. Invalid outcomes
|
|
40
|
+
remain errors. Engine no longer branches on Workflow's event or outcome values.
|
|
41
|
+
|
|
42
|
+
FSMSession alone tracks `running`, `awaiting_terminal`, and its final lifecycle
|
|
43
|
+
state. Matching early events are discarded before invoking decision_for;
|
|
44
|
+
ordinary events cannot advance while awaiting; events after done are ignored.
|
|
45
|
+
The retirement action reuses the existing recovery-required management route.
|
|
46
|
+
|
|
47
|
+
## Preserved durable ordering
|
|
48
|
+
|
|
49
|
+
1. Session reaches a logical wait/completion boundary and captures metadata.
|
|
50
|
+
2. Session marks itself awaiting a decision before invoking the policy.
|
|
51
|
+
3. Runner marks admission persisting_terminal and captures an immutable command.
|
|
52
|
+
4. Offload saves once and reconciles an uncertain result when possible.
|
|
53
|
+
5. The bound EventSink returns the result to that session on EventLoop.
|
|
54
|
+
6. The policy interprets the result only while the session accepts it.
|
|
55
|
+
7. A complete decision permits the deferred observer, then the terminal event.
|
|
56
|
+
8. EventLoop retires the session; Runner releases admission before settling the caller.
|
|
57
|
+
|
|
58
|
+
An observer exception still uses Refactor 32's ordinary error path, with the
|
|
59
|
+
already confirmed snapshot retained. No observer retry or extra save is added.
|
|
60
|
+
|
|
61
|
+
Unresolved uncertainty instead retires the session and retains recovery-required
|
|
62
|
+
admission without falsely settling the caller. Normal shutdown clears that
|
|
63
|
+
ownership and ends the dispatcher, while the caller remains pending; unexpected
|
|
64
|
+
dispatcher failure retains its separate existing waiter-cleanup behavior. This
|
|
65
|
+
change does not promise that normal shutdown resolves an unknown commit.
|
|
66
|
+
|
|
67
|
+
## Alternatives and compatibility
|
|
68
|
+
|
|
69
|
+
Moving the full session would introduce Workflow dependencies into Agent/Tool.
|
|
70
|
+
Renaming event strings in Engine would leave semantic ownership unchanged.
|
|
71
|
+
Subclass/prepend overrides would recreate the hidden execution path removed by
|
|
72
|
+
W1. Saving after retirement or settling on a worker would break the barrier.
|
|
73
|
+
The injected policy keeps each rule at its existing execution authority.
|
|
74
|
+
|
|
75
|
+
The internal constructor changes from terminal_barrier to terminal_policy;
|
|
76
|
+
there is no compatibility alias or new public plugin API. Without a policy,
|
|
77
|
+
Engine does not reserve a Workflow-specific event name. Production Workflow
|
|
78
|
+
emits the result event only when it has injected its durable policy.
|
|
79
|
+
Public signatures, Workflow command/result identities, data records and Storage
|
|
80
|
+
SPI stay unchanged. One policy class and one decision value type are added;
|
|
81
|
+
this is responsibility separation, not a total-line-count reduction.
|
|
82
|
+
|
|
83
|
+
## Acceptance evidence
|
|
84
|
+
|
|
85
|
+
| Scenario | Test boundary |
|
|
86
|
+
|---|---|
|
|
87
|
+
| Immediate completion/halt and Agent/Tool | Existing Workflow/Agent/Tool suites and generic no-policy completion. |
|
|
88
|
+
| Delayed save and halted stream | Real Runtime admission tests prove no early result/notification. |
|
|
89
|
+
| Portable failures and F1 post/pre/conflict/unreadable | Existing save tests plus real Runtime pre-state and uncertainty tests. |
|
|
90
|
+
| Unknown result and normal shutdown | Admission retained until shutdown, session unbound, caller remains pending. |
|
|
91
|
+
| Early/ordinary/duplicate decisions | Non-Workflow policy/session contract and Workflow policy wiring tests. |
|
|
92
|
+
| Late sink and new incarnation | Real Runtime rejects an old sink for the same logical Workflow ID. |
|
|
93
|
+
| Terminal observer failure | Refactor 32's four public stream regressions. |
|
|
94
|
+
| Submission rejection and delivery rejection | Existing error path releases admission; rejected delivery logs without retry. |
|
|
95
|
+
| Invalid outcomes and missing error | Workflow policy through the real Runner/session assembly. |
|
|
96
|
+
| Load, types, API, gem and source boundary | Full validation and private ownership regression assertions. |
|
|
97
|
+
|
|
98
|
+
The pre-state, uncertainty/shutdown, stale-sink and rejected-delivery scenarios
|
|
99
|
+
also pass on the Refactor 32 baseline; they characterize preserved behavior.
|
|
100
|
+
New protocol tests establish the extracted ownership contract. Refactor 33
|
|
101
|
+
application verification completed W2b. Storage S1/S2 followed and passed on
|
|
102
|
+
Refactor 35; see the [closure review](refactoring-closure.md) for S3 and the
|
|
103
|
+
current applied/candidate boundary. The earlier Refactor 32 baseline remains
|
|
104
|
+
historical evidence for preserved behavior.
|