phronomy 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.mutant.yml +3 -4
- data/CHANGELOG.md +200 -10
- data/CONTRIBUTING.md +81 -9
- data/README.md +15 -6
- data/VERIFY.sh +587 -0
- data/benchmark/bench_agent_invoke.rb +2 -2
- data/benchmark/bench_context_assembler.rb +39 -68
- data/benchmark/bench_regression.rb +2 -2
- data/docs/architecture/agent-context.md +174 -0
- data/docs/architecture/before-llm-input.md +78 -0
- data/docs/architecture/context-management.md +232 -0
- data/docs/architecture/knowledge-and-rag.md +130 -0
- data/docs/architecture/multi-agent-handoff.md +152 -0
- data/docs/architecture/persistence.md +175 -0
- data/docs/architecture/removed/agent-context.md +72 -0
- data/docs/architecture/security-boundaries.md +173 -0
- data/docs/architecture/tracing.md +194 -0
- data/docs/architecture.md +82 -0
- data/docs/archive/design/archived/04_api_design.md +507 -0
- data/docs/archive/design/archived/09_guardrails.md +186 -0
- data/docs/archive/design/archived/17_rails_integration.md +175 -0
- data/docs/archive/design/historical/00_design_philosophy.md +122 -0
- data/docs/archive/design/historical/01_rubyllm_evaluation.md +178 -0
- data/docs/archive/design/historical/06_design_decisions.md +143 -0
- data/docs/changelog/0.14-and-earlier.md +1 -1
- data/docs/decisions/001-rubyllm-as-provider-layer.md +6 -1
- data/docs/decisions/002-workflow-context-immutability.md +26 -1
- data/docs/decisions/006-no-built-in-guardrails.md +2 -1
- data/docs/decisions/012-canonical-execution-log-and-context-policy.md +120 -38
- data/docs/decisions/014-unified-persistence-durable-state.md +9 -2
- data/docs/decisions/016-semantic-multi-agent-handoff.md +112 -0
- data/docs/decisions/017-design-authority-and-adr-governance.md +200 -0
- data/docs/decisions/018-durability-guarantees-and-failure-model.md +488 -0
- data/docs/decisions/019-filter-contract-and-security-boundaries.md +229 -0
- data/docs/decisions/020-canonical-workflow-instance-identity.md +177 -0
- data/docs/decisions/021-generic-agent-invocation-identity-removal.md +119 -0
- data/docs/decisions/022-agent-execution-parent-identity-and-runtime-routing-boundary.md +193 -0
- data/docs/decisions/023-fsm-session-incarnation-identity-and-routing.md +139 -0
- data/docs/decisions/024-event-loop-single-writer-agent-runtime.md +188 -0
- data/docs/decisions/025-process-local-agent-ownership-and-runtime-admission.md +249 -0
- data/docs/decisions/026-workflow-runtime-admission-and-durable-terminal-barrier.md +257 -0
- data/docs/decisions/027-llm-adapter-provider-boundary.md +93 -0
- data/docs/decisions/README.md +172 -0
- data/docs/features.md +31 -11
- data/docs/getting-started.md +77 -45
- data/docs/migrations/0.19.md +14 -7
- data/docs/migrations/0.22.md +390 -0
- data/docs/persistence-backends.md +88 -38
- data/docs/runtime-and-concurrency.md +227 -33
- data/examples/README.md +13 -0
- data/lib/phronomy/agent/agent_execution.rb +19 -15
- data/lib/phronomy/agent/agent_invocation.rb +288 -93
- data/lib/phronomy/agent/agent_invocation_session_builder.rb +236 -202
- data/lib/phronomy/agent/agent_root.rb +3 -3
- data/lib/phronomy/agent/approval_evaluation_request.rb +37 -19
- data/lib/phronomy/agent/async_event_api.rb +145 -72
- data/lib/phronomy/agent/base.rb +388 -181
- data/lib/phronomy/agent/concerns/before_llm_input.rb +1 -1
- data/lib/phronomy/agent/context_assembler.rb +437 -178
- data/lib/phronomy/agent/context_candidate_resolver.rb +2 -2
- data/lib/phronomy/agent/context_plan.rb +18 -13
- data/lib/phronomy/agent/context_plan_validator.rb +246 -88
- data/lib/phronomy/agent/context_policies/default.rb +123 -34
- data/lib/phronomy/agent/context_policy.rb +109 -3
- data/lib/phronomy/agent/context_policy_input.rb +244 -0
- data/lib/phronomy/agent/context_policy_input_builder.rb +241 -0
- data/lib/phronomy/agent/execution_coordinator.rb +1975 -587
- data/lib/phronomy/agent/journal_record.rb +17 -4
- data/lib/phronomy/agent/llm_input_build_context.rb +1 -1
- data/lib/phronomy/agent/llm_input_manifest.rb +277 -2
- data/lib/phronomy/agent/llm_operation_result.rb +12 -7
- data/lib/phronomy/agent/phase_machine_builder.rb +19 -7
- data/lib/phronomy/agent/provider_call_outcome.rb +23 -7
- data/lib/phronomy/agent/recovery_coordinator/continuation.rb +271 -0
- data/lib/phronomy/agent/recovery_coordinator/installation.rb +427 -0
- data/lib/phronomy/agent/recovery_coordinator/resolution.rb +635 -0
- data/lib/phronomy/agent/recovery_coordinator.rb +211 -0
- data/lib/phronomy/agent/recovery_support.rb +512 -0
- data/lib/phronomy/agent/ruby_llm_materializer.rb +22 -13
- data/lib/phronomy/agent/selection/candidate.rb +53 -0
- data/lib/phronomy/agent/selection/constraint.rb +49 -0
- data/lib/phronomy/agent/shared_state.rb +38 -1
- data/lib/phronomy/agent/tool_approval_request.rb +33 -5
- data/lib/phronomy/agent/tool_definition_set.rb +49 -3
- data/lib/phronomy/agent/tool_invocation.rb +336 -102
- data/lib/phronomy/agent/tool_invocation_session_builder.rb +49 -45
- data/lib/phronomy/agent.rb +20 -2
- data/lib/phronomy/agent_already_exists_error.rb +5 -0
- data/lib/phronomy/agent_purged_error.rb +5 -0
- data/lib/phronomy/engine/concurrency/offload_pool.rb +17 -3
- data/lib/phronomy/engine/concurrency/physical_completion_task.rb +135 -0
- data/lib/phronomy/engine/event_loop.rb +622 -63
- data/lib/phronomy/engine/fsm_session.rb +194 -21
- data/lib/phronomy/engine/runtime/agent_ownership_registry.rb +352 -0
- data/lib/phronomy/engine/runtime.rb +77 -20
- data/lib/phronomy/generator_verifier.rb +12 -14
- data/lib/phronomy/invocation_context.rb +9 -29
- data/lib/phronomy/multi_agent/admission_registry.rb +51 -0
- data/lib/phronomy/multi_agent/coordination_state.rb +18 -0
- data/lib/phronomy/multi_agent/coordinator.rb +154 -0
- data/lib/phronomy/multi_agent/execution_coordinator.rb +116 -0
- data/lib/phronomy/multi_agent/fan_out_invocation.rb +24 -33
- data/lib/phronomy/multi_agent/fan_out_session_builder.rb +12 -19
- data/lib/phronomy/multi_agent/handoff.rb +24 -45
- data/lib/phronomy/multi_agent/handoff_capability_factory.rb +87 -0
- data/lib/phronomy/multi_agent/handoff_context.rb +95 -0
- data/lib/phronomy/multi_agent/handoff_policy.rb +137 -0
- data/lib/phronomy/multi_agent/handoff_projection.rb +191 -0
- data/lib/phronomy/multi_agent/handoff_request.rb +45 -0
- data/lib/phronomy/multi_agent/orchestrator.rb +12 -15
- data/lib/phronomy/multi_agent/runner.rb +98 -0
- data/lib/phronomy/persistence/durable_codec.rb +646 -0
- data/lib/phronomy/persistence/durable_record.rb +117 -0
- data/lib/phronomy/persistence/in_memory.rb +210 -134
- data/lib/phronomy/persistence/migration/initial_format_migration.rb +226 -0
- data/lib/phronomy/persistence/repository_facades.rb +316 -0
- data/lib/phronomy/persistence.rb +81 -41
- data/lib/phronomy/recovery.rb +186 -0
- data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +2 -2
- data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +1 -1
- data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +19 -19
- data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +3 -3
- data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +5 -5
- data/lib/phronomy/tracing/automatic.rb +176 -0
- data/lib/phronomy/tracing/base.rb +11 -2
- data/lib/phronomy/tracing/langfuse_tracer.rb +20 -12
- data/lib/phronomy/version.rb +1 -1
- data/lib/phronomy/workflow.rb +3 -6
- data/lib/phronomy/workflow_context.rb +14 -5
- data/lib/phronomy/workflow_recovery.rb +123 -0
- data/lib/phronomy/workflow_runner.rb +468 -256
- data/lib/phronomy.rb +6 -0
- data/scripts/api_snapshot.rb +12 -0
- data/sig/phronomy/agent.rbs +209 -7
- data/sig/phronomy/multi_agent.rbs +39 -0
- data/sig/phronomy/persistence.rbs +62 -4
- data/sig/phronomy/runtime.rbs +1 -4
- data/sig/phronomy/workflow.rbs +2 -2
- data/sig/phronomy.rbs +10 -0
- metadata +65 -17
- data/examples/workflows/agent_event_mapping.rb +0 -101
- data/examples/workflows/generic_task_event_mapping.rb +0 -66
- data/lib/phronomy/agent/activation_registry.rb +0 -28
- data/lib/phronomy/agent/agent_execution_activation.rb +0 -172
- data/lib/phronomy/agent/context_candidate.rb +0 -47
- data/lib/phronomy/agent/context_parts/budget/token_budget_packer.rb +0 -53
- data/lib/phronomy/agent/context_parts/requirements/required_context_resolver.rb +0 -56
- data/lib/phronomy/agent/context_parts/selectors/recent_first_selector.rb +0 -30
- data/lib/phronomy/agent/context_parts/unit_builders/dependency_aware_unit_builder.rb +0 -118
- data/lib/phronomy/agent/context_policy_descriptor.rb +0 -49
- data/lib/phronomy/agent/context_policy_registry.rb +0 -46
- data/lib/phronomy/agent/context_request.rb +0 -35
- data/lib/phronomy/agent/context_selection_unit.rb +0 -38
- data/lib/phronomy/agent/derived_content_spec.rb +0 -34
- data/lib/phronomy/agent/runner.rb +0 -97
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ffed6b796d049192f4f782aea75353504c166b23c5b6e1f336ab73eb90bbeb54
|
|
4
|
+
data.tar.gz: 5655635e8ef6331496d0bb057dad602b2154cabae97ec87f4906123824b8c45d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 242dcb66e87b5beaaa55e19541fc852821adccf971cad68c06d65bcf705352a670b67012fa8c706ea0263f69eb03793a9b67d0bc3d61df422d201b3e3b6aa1c2
|
|
7
|
+
data.tar.gz: 0b889a029056ad0a458a7318eacf0d3813072adf0f6b7ef8a448a02dd0a476b9146fcbdf90d4170ea3823058ba51a82aa4a0b7fb31e24f7e031404d9b7b27924
|
data/.mutant.yml
CHANGED
|
@@ -15,9 +15,8 @@ matcher:
|
|
|
15
15
|
- Phronomy::LlmContextWindow::TokenBudget
|
|
16
16
|
- Phronomy::Agent::ContextAssembler
|
|
17
17
|
- Phronomy::Agent::ContextPolicies::Default
|
|
18
|
-
- Phronomy::Agent::
|
|
19
|
-
- Phronomy::Agent::ContextParts::Requirements::RequiredContextResolver
|
|
20
|
-
- Phronomy::Agent::ContextParts::Selectors::RecentFirstSelector
|
|
21
|
-
- Phronomy::Agent::ContextParts::Budget::TokenBudgetPacker
|
|
18
|
+
- Phronomy::Agent::ContextPolicyInputBuilder
|
|
22
19
|
- Phronomy::Agent::ContextPlanValidator
|
|
20
|
+
- Phronomy::MultiAgent::HandoffPolicy
|
|
21
|
+
- Phronomy::MultiAgent::HandoffProjection
|
|
23
22
|
- Phronomy::VectorStore::InMemory
|
data/CHANGELOG.md
CHANGED
|
@@ -12,29 +12,200 @@ Release history for 0.14.0 and earlier is archived in
|
|
|
12
12
|
|
|
13
13
|
## [Unreleased]
|
|
14
14
|
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## [0.23.0] - 2026-08-29
|
|
18
|
+
|
|
19
|
+
### Four-category Context Policy SPI and transaction boundary (ACS-04)
|
|
20
|
+
|
|
21
|
+
#### Added
|
|
22
|
+
|
|
23
|
+
- Public immutable `ContextPolicyInput` typed values for `instruction`,
|
|
24
|
+
`knowledge`, `tools`, and indivisibly grouped `conversation`.
|
|
25
|
+
- Agent-class `context_policy <instance>` binding for reusable Application
|
|
26
|
+
Context strategies, with built-in Default fallback.
|
|
27
|
+
- Small ContextPolicy helpers for current-call generated instruction, Knowledge,
|
|
28
|
+
and conversation items.
|
|
29
|
+
- Framework trace boundary around ContextPolicy invocation without standard-trace
|
|
30
|
+
inclusion of full Policy input/Plan content.
|
|
31
|
+
|
|
32
|
+
#### Changed
|
|
33
|
+
|
|
34
|
+
- `ContextPlan` now directly carries ordered output material in the same four
|
|
35
|
+
semantic categories.
|
|
36
|
+
- Default Policy uses deterministic recent-conversation / stable-fit Knowledge
|
|
37
|
+
selection with an approximately 60/40 variable budget split and preserves the
|
|
38
|
+
effective Tool set.
|
|
39
|
+
- Custom Policy may select/reorder a subset of effective Tools; arbitrary
|
|
40
|
+
schema-only runtime Tool creation remains outside ACS-04 because durable
|
|
41
|
+
runtime Tool identity/wiring is not defined.
|
|
42
|
+
- ContextPolicy executes outside Phronomy Persistence transactions. The durable
|
|
43
|
+
base/revision is revalidated before the short Manifest/execution commit.
|
|
44
|
+
- Context assembly policy version is `8`.
|
|
45
|
+
|
|
46
|
+
#### Removed
|
|
47
|
+
|
|
48
|
+
- `ContextRequest`, `ContextPolicyDescriptor`, `ContextPolicyRegistry`, and
|
|
49
|
+
`DerivedContentSpec`.
|
|
50
|
+
- Intermediate selection-unit/policy-parts machinery superseded by the typed
|
|
51
|
+
four-category SPI: `Selection::Unit`, `Selection::Validator`,
|
|
52
|
+
`DependencyAwareUnitBuilder`, `RequiredContextResolver`,
|
|
53
|
+
`RecentFirstSelector`, and `TokenBudgetPacker`.
|
|
54
|
+
- Descriptor persistence/reconstruction and old `ContextPlan` fields
|
|
55
|
+
`selected_unit_ids`, `derived_contents`, `ordering_hints`, and
|
|
56
|
+
`policy_descriptor`.
|
|
57
|
+
|
|
58
|
+
### Workflow Runtime admission and durable terminal barrier (ACS-13)
|
|
59
|
+
|
|
60
|
+
#### Added
|
|
61
|
+
|
|
62
|
+
- ADR-026 defining opaque process-local Workflow admission ownership,
|
|
63
|
+
admission-before-hydration ordering, and FSMSession-integrated terminal
|
|
64
|
+
persistence.
|
|
65
|
+
- Explicit Workflow terminal persistence outcomes: known success, known failure,
|
|
66
|
+
and fail-closed outcome uncertainty.
|
|
67
|
+
|
|
68
|
+
#### Changed
|
|
69
|
+
|
|
70
|
+
- Workflow admission ownership no longer reuses the future `fsm_session_id`.
|
|
71
|
+
EventLoop acquires a separate opaque owner token before durable load and binds
|
|
72
|
+
the concrete FSMSession routing ID only after hydration.
|
|
73
|
+
- Durable Workflow halt/completion now remains nonterminal while the final
|
|
74
|
+
snapshot is saved. The save result returns to the same FSMSession, and only a
|
|
75
|
+
known-successful result permits `HALTED` / `COMPLETED`, admission release, and
|
|
76
|
+
caller Task settlement.
|
|
77
|
+
- Portable known Persistence failures follow the Workflow error path. An
|
|
78
|
+
arbitrary storage/transport error whose commit outcome is not established is
|
|
79
|
+
treated as outcome-unknown: the success barrier stays closed and the
|
|
80
|
+
`workflow_instance_id` admission remains fail-closed/recovery-required.
|
|
81
|
+
- Workflow persistence result handling is backend-topology neutral; the FSM does
|
|
82
|
+
not depend on local/network/database transport details.
|
|
83
|
+
|
|
84
|
+
### Process-local Agent ownership and Runtime admission (ACS-12)
|
|
85
|
+
|
|
86
|
+
#### Added
|
|
87
|
+
|
|
88
|
+
- ADR-025 defining one mutable live Agent owner per `agent_id` per Runtime and
|
|
89
|
+
EventLoop-owned same-process top-level execution admission.
|
|
90
|
+
- `Agent::Base.get(agent_id)` for process-local live-owner lookup without
|
|
91
|
+
Persistence I/O.
|
|
92
|
+
- `AgentAlreadyExistsError` for create/new identity conflicts and
|
|
93
|
+
`AgentPurgedError` for stale references after successful purge.
|
|
94
|
+
|
|
95
|
+
#### Changed
|
|
96
|
+
|
|
97
|
+
- Repeated `Agent.load(agent_id, persistence:)` returns the exact existing live
|
|
98
|
+
Agent object; a durable-only Agent is hydrated once, and a missing durable
|
|
99
|
+
Agent remains a strict `Persistence::NotFoundError`.
|
|
100
|
+
- `new` / `create` mean creation only and reject an identity that is already
|
|
101
|
+
live or already durable instead of materializing a second mutable owner.
|
|
102
|
+
- EventLoop acquires the same-Agent top-level execution slot before initial
|
|
103
|
+
Offload/Persistence work. Suspension retains that slot; known durable terminal
|
|
104
|
+
completion releases it; uncertain durable outcomes remain fail-closed.
|
|
105
|
+
- Persistence `executions.create_active` / atomic admission remains the durable
|
|
106
|
+
second line of integrity defense rather than the primary same-process lock.
|
|
107
|
+
- Runtime-lifetime Agent ownership is released on clean Runtime shutdown.
|
|
108
|
+
Successful `purge!` is the explicit earlier destruction boundary and makes
|
|
109
|
+
the stale Agent object permanently unusable before the identity can be reused.
|
|
110
|
+
|
|
111
|
+
### EventLoop single-writer Agent Runtime (ACS-11)
|
|
112
|
+
|
|
113
|
+
#### Added
|
|
114
|
+
|
|
115
|
+
- ADR-024 defining EventLoop as the single writer of Phronomy-managed live
|
|
116
|
+
Agent execution state and operation-specific Offload command/result apply.
|
|
117
|
+
- Runtime read-only Agent execution-owner lookup for approval/live-owner
|
|
118
|
+
routing without exposing mutable execution internals.
|
|
119
|
+
- Provider result authority using current FSMSession/FSM state plus semantic
|
|
120
|
+
`llm_call_id`; stale Provider results are consumed without advancing the FSM.
|
|
121
|
+
|
|
122
|
+
#### Changed
|
|
123
|
+
|
|
124
|
+
- Agent initial preparation, follow-up Manifest preparation, approval resume,
|
|
125
|
+
and terminal durable commits now return values from OffloadPool and apply
|
|
126
|
+
committed live-state advances only on EventLoop.
|
|
127
|
+
- AgentInvocation owns FSM-local uncommitted Provider/Tool/runtime facts.
|
|
128
|
+
- Tool authorization captures Agent identity and Tool description data before
|
|
129
|
+
worker execution; the authorization worker receives no live Agent, Tool, or
|
|
130
|
+
ToolInvocation reference. Application-owned approval/facts/requirement
|
|
131
|
+
callables remain explicit behavior handles.
|
|
132
|
+
- `ApprovalEvaluationRequest` is value-only: Agent identity is exposed as
|
|
133
|
+
`agent_id`, `agent_definition_id`, and `agent_definition_version`; Tool
|
|
134
|
+
identity/description is exposed through `tool_name` / `tool_schema`.
|
|
135
|
+
- Tool authorization/execution outcomes carry semantic `tool_invocation_id`
|
|
136
|
+
and are applied by the Tool FSMSession.
|
|
137
|
+
|
|
138
|
+
#### Removed
|
|
139
|
+
|
|
140
|
+
- `AgentExecutionActivation`, `Agent::ActivationRegistry`,
|
|
141
|
+
`Runtime#__agent_activations`, and the `phronomy_activation` config bridge.
|
|
142
|
+
- Live-object accessors `ApprovalEvaluationRequest#agent` and
|
|
143
|
+
`ApprovalEvaluationRequest#tool`; approval policies use value identity and
|
|
144
|
+
Tool-description fields instead.
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
### Semantic Multi-Agent Handoff and shared Selection
|
|
148
|
+
|
|
149
|
+
#### Added
|
|
150
|
+
|
|
151
|
+
- `Phronomy::MultiAgent::HandoffPolicy` with required, forbidden, and selectable
|
|
152
|
+
transfer rules for current request, history, Knowledge, and Tool exchanges.
|
|
153
|
+
- `Phronomy::MultiAgent::Runner.new(main_agent:, handoffs:)` as the public
|
|
154
|
+
semantic Handoff coordinator.
|
|
155
|
+
- Typed private Handoff request/context/provenance values, explicit
|
|
156
|
+
`AgentExecution` `:handed_off` terminal semantics, and Runtime/EventLoop-owned
|
|
157
|
+
active-Agent coordination.
|
|
158
|
+
- Shared `Phronomy::Agent::Selection::Candidate`, `Unit`, `Constraint`, and
|
|
159
|
+
validation machinery for Context and Handoff selection.
|
|
160
|
+
- ADR-016 and the 0.22 migration guide for the semantic Handoff clean break.
|
|
161
|
+
|
|
162
|
+
#### Changed
|
|
163
|
+
|
|
164
|
+
- Handoff is now an explicit Source-to-Target responsibility transfer rather
|
|
165
|
+
than sentinel Tool-result routing. Generated Handoff Tool names are private
|
|
166
|
+
transport details only.
|
|
167
|
+
- Handoff Context is projected from the effective Source Manifest, materialized
|
|
168
|
+
immutably with provenance, and may cross Agents backed by different Persistence
|
|
169
|
+
adapters without adopting Source material into Target Journal/Knowledge.
|
|
170
|
+
- Target Context Policy remains the final per-LLM-call selection authority;
|
|
171
|
+
transferred material enters Target assembly as selectable Context candidates.
|
|
172
|
+
- The active Target persists across user turns and Runner-facade recreation while
|
|
173
|
+
the same main Agent instance and Runtime remain alive. Runtime/process reset
|
|
174
|
+
intentionally does not restore active-Agent continuation.
|
|
175
|
+
- Context assembly policy version is now `7` for the shared Selection and
|
|
176
|
+
Handoff-Context contract.
|
|
177
|
+
|
|
178
|
+
#### Removed
|
|
179
|
+
|
|
180
|
+
- `Phronomy::Agent::Runner`, the `agents:` / `routes:` Runner API, sentinel-map
|
|
181
|
+
routing, and Agent-owned `_add_handoff_tool` / `_handoff_tools` mutation.
|
|
182
|
+
- `Phronomy::Agent::ContextCandidate` and
|
|
183
|
+
`Phronomy::Agent::ContextSelectionUnit`; internal callers use the shared
|
|
184
|
+
`Agent::Selection` model without compatibility aliases.
|
|
185
|
+
|
|
15
186
|
### Unified Persistence and durable-state ownership
|
|
16
187
|
|
|
17
188
|
#### Added
|
|
18
189
|
|
|
19
190
|
- `Persistence#workflow_states` with optimistic revision checks for durable Workflow snapshots.
|
|
20
|
-
- Runtime-local Agent
|
|
191
|
+
- Runtime-local Agent execution ownership outside Persistence; ACS-11 now places the mutable live-state authority on EventLoop.
|
|
21
192
|
- `Agent::Base.live_for_execution(execution_id)` for resolving the current process's live owner Agent without reloading Agent or Execution state from Persistence.
|
|
22
|
-
- Owner-aware Workflow admission keyed by durable `
|
|
193
|
+
- Owner-aware Workflow admission keyed by durable `workflow_instance_id`; ACS-13 now uses a Runtime-only opaque owner token that is separate from concrete `fsm_session_id` routing.
|
|
23
194
|
- ADR-014 and the 0.19 migration guide for the unified durable-state architecture.
|
|
24
195
|
|
|
25
196
|
#### Changed
|
|
26
197
|
|
|
27
|
-
- Live Agent instances
|
|
198
|
+
- Live Agent instances remain authoritative for AgentRoot/Journal state after hydration, while EventLoop owns active execution-state mutation. Context Policy and follow-up Manifest preparation use those local views instead of reloading mutable Agent state for freshness.
|
|
28
199
|
- `Phronomy.configuration.persistence` is the global durable backend for Workflows and for Agent `new`/`create` calls that do not explicitly inject another Persistence instance.
|
|
29
200
|
- Agent durable writes use optimistic revision/Journal-position guardrails; conflicting external writes fail instead of being silently reloaded or merged.
|
|
30
|
-
- Approval suspension/resume preserves the same
|
|
31
|
-
- Workflow durable I/O runs outside EventLoop through OffloadPool
|
|
32
|
-
- Workflow `
|
|
201
|
+
- Approval suspension/resume preserves the same process-local Agent/AgentInvocation owner. Approval remains an Agent-instance operation; callers with only an `execution_id` resolve the EventLoop-backed live owner with `Agent::Base.live_for_execution` (or the expected concrete Agent class) before calling `agent.approve` / `agent.approve_async`.
|
|
202
|
+
- Workflow durable I/O runs outside EventLoop through OffloadPool. Terminal/halted snapshot persistence now completes inside the owning FSMSession lifecycle; only a known-successful save permits normal terminalization and admission release. Workflow admission remains process-local; optimistic revisions detect stale commits across processes but do not prevent duplicate execution or undo already-performed external side effects.
|
|
203
|
+
- Workflow `workflow_instance_id` is distinct from one concrete Runtime FSMSession identity; generic application `session_id` is not a Phronomy core domain identity.
|
|
33
204
|
|
|
34
205
|
#### Removed
|
|
35
206
|
|
|
36
207
|
- `Phronomy::StateStore`, `StateStore::InMemory`, `Workflow.define(..., state_store:)`, `Configuration#state_store`, and per-invocation `config[:state_store]`.
|
|
37
|
-
- `Persistence#activations`; ActivationRegistry is
|
|
208
|
+
- `Persistence#activations`; live Agent execution state is Runtime-only. The transitional ActivationRegistry is subsequently removed by ACS-11.
|
|
38
209
|
- Class-level `Agent::Base.approve` / `Agent::Base.approve_async` routing APIs and their caller-supplied `persistence:` argument; approval execution now goes through the resolved live Agent instance.
|
|
39
210
|
|
|
40
211
|
### Public API façade and typed contracts
|
|
@@ -59,6 +230,25 @@ Release history for 0.14.0 and earlier is archived in
|
|
|
59
230
|
return `Task`.
|
|
60
231
|
- `InvocationContext` construction is classified consistently with its documented
|
|
61
232
|
Beta application API.
|
|
233
|
+
- Generic Agent invocation identity is removed: `InvocationContext` no longer
|
|
234
|
+
exposes `thread_id` / `session_id`, Agent invocation APIs no longer accept
|
|
235
|
+
`thread_id:`, and no replacement generic correlation identity is introduced.
|
|
236
|
+
- The canonical `JournalRecord` representation no longer contains
|
|
237
|
+
`correlation_id`; legacy durable Hashes containing the removed key remain
|
|
238
|
+
readable without an eager data rewrite.
|
|
239
|
+
- Tool approval notification/policy parent identity now uses canonical Agent
|
|
240
|
+
`execution_id` instead of `agent_invocation_id`; new suspended-execution
|
|
241
|
+
approval data uses the same parent identity.
|
|
242
|
+
- Legacy embedded suspended approval hashes remain readable by deriving the
|
|
243
|
+
logical parent from their enclosing Agent execution; historical
|
|
244
|
+
content-addressed audit bodies are not rewritten.
|
|
245
|
+
- Agent, Tool, and Multi-Agent concrete `FSMSession` instances no longer reuse
|
|
246
|
+
domain/context IDs as EventLoop routing targets. Async callbacks use
|
|
247
|
+
session-local event sinks, and Provider completion is routed to the owning
|
|
248
|
+
FSMSession before EventLoop validates/applies `llm_call_id`-bound result
|
|
249
|
+
state. Workflow retains its pre-load admission ordering through a private
|
|
250
|
+
single-use FSMSession identity reservation; opaque Workflow admission
|
|
251
|
+
ownership remains ACS-13 work.
|
|
62
252
|
- OutputParser `parse` is classified as the public subclass extension point that
|
|
63
253
|
concrete parsers implement.
|
|
64
254
|
|
|
@@ -133,8 +323,8 @@ Release history for 0.14.0 and earlier is archived in
|
|
|
133
323
|
returns a completion handle immediately.
|
|
134
324
|
- `Tool#call_async` for ordinary cooperative Tools no longer consumes a
|
|
135
325
|
OffloadPool worker. `:offloaded` remains the worker-pool route.
|
|
136
|
-
- Framework-owned short in-memory Tools (
|
|
137
|
-
|
|
326
|
+
- Framework-owned short in-memory Tools (TeamCoordinator queue controls and
|
|
327
|
+
SharedState store access) explicitly declare
|
|
138
328
|
`execution_mode :cooperative` instead of using the blocking-I/O default.
|
|
139
329
|
- MultiAgent fan-out uses a FanOut FSMSession rather than per-child OS Threads.
|
|
140
330
|
- `TimerQueue` is driven by EventLoop and owns no Thread.
|
|
@@ -172,7 +362,7 @@ Release history for 0.14.0 and earlier is archived in
|
|
|
172
362
|
transcript/Knowledge lifecycle semantics.
|
|
173
363
|
- Active Context tests, integration fixtures, benchmarks, mutation subjects,
|
|
174
364
|
design documents, and API snapshots now describe the canonical
|
|
175
|
-
Journal ->
|
|
365
|
+
Journal -> Selection::Candidate -> Context Policy -> Manifest architecture.
|
|
176
366
|
|
|
177
367
|
#### Removed
|
|
178
368
|
|
data/CONTRIBUTING.md
CHANGED
|
@@ -114,17 +114,85 @@ OffloadPool work is supplied through `CancellationToken`.
|
|
|
114
114
|
|
|
115
115
|
---
|
|
116
116
|
|
|
117
|
-
## Architecture Decision Records
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
117
|
+
## Architecture Authority and Decision Records
|
|
118
|
+
|
|
119
|
+
Phronomy has **no universal artifact priority**. Different artifacts answer
|
|
120
|
+
different questions. The normative repository rule is
|
|
121
|
+
[`017-design-authority-and-adr-governance`](docs/decisions/017-design-authority-and-adr-governance.md);
|
|
122
|
+
the complete ADR status/supersession index is
|
|
123
|
+
[`docs/decisions/README.md`](docs/decisions/README.md).
|
|
124
|
+
|
|
125
|
+
Use these authority boundaries:
|
|
126
|
+
|
|
127
|
+
- Accepted, non-superseded ADRs define architecture intent.
|
|
128
|
+
- Source/runtime behavior defines current implementation reality; it does not
|
|
129
|
+
silently amend an ADR.
|
|
130
|
+
- Public API and extension-SPI contracts are composite: runtime behavior,
|
|
131
|
+
`@api` classification, formal API documentation, and explicit
|
|
132
|
+
compatibility/contract tests all participate.
|
|
133
|
+
- RBS does not create a contract. It types a contract already established by
|
|
134
|
+
those sources.
|
|
135
|
+
- Ordinary implementation tests are regression evidence. Only tests explicitly
|
|
136
|
+
maintained as architecture guards or compatibility/contract tests have that
|
|
137
|
+
stronger role.
|
|
138
|
+
- Historical, Archived, and Superseded material is non-normative for current
|
|
139
|
+
architecture.
|
|
140
|
+
|
|
141
|
+
When architecture intent, public contract, and implementation reality disagree,
|
|
142
|
+
treat the discrepancy as an **architecture inconsistency**. Do not choose a
|
|
143
|
+
winner merely because one artifact is newer. Record the conflict and resolve it
|
|
144
|
+
explicitly according to the process in the ADR index.
|
|
145
|
+
|
|
146
|
+
ADR references should use a file link or the canonical filename key. This is
|
|
147
|
+
required for the two legacy `011` decisions because bare `ADR-011` is
|
|
148
|
+
ambiguous. Do not renumber historical ADRs to repair that legacy collision.
|
|
122
149
|
|
|
123
150
|
For Agent Context work, ADR-012 and ADR-013 define the current Journal,
|
|
124
151
|
Manifest, Context Policy and persistent Knowledge model. ADR-010 defines the
|
|
125
152
|
EventLoop/FSMSession, Task, and OffloadPool execution boundary. ADR-015 defines
|
|
126
153
|
the Tool public façade, extension-SPI boundary, and RBS ownership rules.
|
|
127
154
|
|
|
155
|
+
Current explanatory architecture starts at [`docs/architecture.md`](docs/architecture.md).
|
|
156
|
+
Non-current design snapshots live under `docs/archive/design/` and are
|
|
157
|
+
non-normative. Do not treat archived/historical material as a current contract
|
|
158
|
+
merely because it remains searchable in the repository.
|
|
159
|
+
|
|
160
|
+
### Durability, recovery, and failure vocabulary
|
|
161
|
+
|
|
162
|
+
Architecture-sensitive durability, concurrency, recovery, cancellation, and
|
|
163
|
+
external-effect changes must use
|
|
164
|
+
[`018-durability-guarantees-and-failure-model`](docs/decisions/018-durability-guarantees-and-failure-model.md).
|
|
165
|
+
|
|
166
|
+
Do not write a bare claim such as "durable", "recoverable", "safe", or
|
|
167
|
+
"exactly once". State:
|
|
168
|
+
|
|
169
|
+
1. the guarantee subject;
|
|
170
|
+
2. the exact guarantee property (for example durable-state restart
|
|
171
|
+
readability, execution resumption, stale durable-transition conflict
|
|
172
|
+
detection, or duplicate external-side-effect prevention);
|
|
173
|
+
3. the component/contract that provides it;
|
|
174
|
+
4. the applicable F0-F4 failure class(es);
|
|
175
|
+
5. whether X0 External Effect Boundary is crossed; and
|
|
176
|
+
6. whether the architecture result is YES, CONDITIONAL, or NO, including the
|
|
177
|
+
condition for every CONDITIONAL guarantee.
|
|
178
|
+
|
|
179
|
+
In particular:
|
|
180
|
+
|
|
181
|
+
- F0 operation failure and F1 outcome uncertainty are distinct dimensions and
|
|
182
|
+
may co-occur; an F0 result does not prove durable/external outcome certainty.
|
|
183
|
+
- durable-transition atomicity is not commit-outcome certainty.
|
|
184
|
+
- optimistic conflict detection is not cross-process execution exclusion.
|
|
185
|
+
- process/runtime loss (F4) does not imply confirmed durable state was lost.
|
|
186
|
+
- X0 external side effects are not automatically atomic with Persistence.
|
|
187
|
+
- semantic IDs do not by themselves provide duplicate prevention.
|
|
188
|
+
- arbitrary external exactly-once execution is not an unconditional Phronomy
|
|
189
|
+
guarantee.
|
|
190
|
+
|
|
191
|
+
Fault-injection and recovery tests should state which failure class/boundary
|
|
192
|
+
they exercise and must not imply stronger guarantees than the test proves.
|
|
193
|
+
F0-F4/X0 are architecture/test vocabulary, not a required public exception
|
|
194
|
+
hierarchy.
|
|
195
|
+
|
|
128
196
|
---
|
|
129
197
|
|
|
130
198
|
## Mutation Testing
|
|
@@ -155,13 +223,17 @@ The authoritative subject list is `.mutant.yml`. It currently includes:
|
|
|
155
223
|
- `Phronomy::LlmContextWindow::TokenBudget`
|
|
156
224
|
- `Phronomy::Agent::ContextAssembler`
|
|
157
225
|
- `Phronomy::Agent::ContextPolicies::Default`
|
|
158
|
-
- `Phronomy::Agent::
|
|
159
|
-
- `Phronomy::Agent::ContextParts::Requirements::RequiredContextResolver`
|
|
160
|
-
- `Phronomy::Agent::ContextParts::Selectors::RecentFirstSelector`
|
|
161
|
-
- `Phronomy::Agent::ContextParts::Budget::TokenBudgetPacker`
|
|
226
|
+
- `Phronomy::Agent::ContextPolicyInputBuilder`
|
|
162
227
|
- `Phronomy::Agent::ContextPlanValidator`
|
|
228
|
+
- `Phronomy::MultiAgent::HandoffPolicy`
|
|
229
|
+
- `Phronomy::MultiAgent::HandoffProjection`
|
|
163
230
|
- `Phronomy::VectorStore::InMemory`
|
|
164
231
|
|
|
232
|
+
The nightly mutation matrix mirrors this authoritative list so each subject can
|
|
233
|
+
run in an isolated job with its own timeout. The regular test suite includes a
|
|
234
|
+
configuration-consistency guard that fails if the nightly subject set diverges
|
|
235
|
+
from `.mutant.yml`.
|
|
236
|
+
|
|
165
237
|
The Tool mutation subject intentionally uses
|
|
166
238
|
`Phronomy::Agent::Context::Capability::Base`, which is the implementation
|
|
167
239
|
canonical name returned by the single Class object's runtime `Class#name`.
|
data/README.md
CHANGED
|
@@ -19,6 +19,7 @@ tracking `main` directly.
|
|
|
19
19
|
- **Persistence** — unified durable backend for Agent state and Workflow `workflow_states`.
|
|
20
20
|
- **Workflow** — state-machine-driven application workflow with explicit events and wait states.
|
|
21
21
|
- **Tool / Capability** — callable application capability exposed to an Agent; application-defined Tools subclass `Phronomy::Tool::Base`.
|
|
22
|
+
- **Multi-Agent Handoff** — semantic Source-to-Target responsibility transfer with policy-bounded Context projection and Runtime-local active-Agent continuity.
|
|
22
23
|
- **EventLoop + FSMSession** — the framework control plane for logical lifecycle coordination.
|
|
23
24
|
- **OffloadPool** — bounded operating-system-thread execution boundary for synchronous work that must not run on EventLoop.
|
|
24
25
|
- **Task** — the common thread-free completion handle returned by Phronomy asynchronous APIs, including OffloadPool-backed work.
|
|
@@ -91,17 +92,23 @@ task = ResearchAgent.new.invoke_async("Research Ruby AI frameworks")
|
|
|
91
92
|
result = task.wait_result # top-level/external caller only
|
|
92
93
|
```
|
|
93
94
|
|
|
94
|
-
|
|
95
|
+
Agent lifecycle events are bound to one live Agent Runtime incarnation.
|
|
96
|
+
Register `on_event:` (or the equivalent construction block) when the Agent
|
|
97
|
+
is created or loaded, then invoke it without a per-call listener:
|
|
95
98
|
|
|
96
99
|
```ruby
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
agent = ResearchAgent.new(
|
|
101
|
+
on_event: ->(event) {
|
|
102
|
+
puts event.type # :done, :error, :tool_call, :tool_result, etc.
|
|
103
|
+
}
|
|
104
|
+
)
|
|
100
105
|
|
|
101
|
-
|
|
102
|
-
task = ResearchAgent.new.invoke_async("Research Ruby AI frameworks", on_event: listener)
|
|
106
|
+
task = agent.invoke_async("Research Ruby AI frameworks")
|
|
103
107
|
```
|
|
104
108
|
|
|
109
|
+
The same listener registration is available on `create` and `load`.
|
|
110
|
+
Public per-invocation `on_event:` / listener blocks are removed.
|
|
111
|
+
|
|
105
112
|
## Runtime model
|
|
106
113
|
|
|
107
114
|
Phronomy uses one completion model with two execution mechanisms:
|
|
@@ -134,11 +141,13 @@ contracts, timeout/cancellation semantics, metrics, and callback rules.
|
|
|
134
141
|
|
|
135
142
|
- [Getting started](docs/getting-started.md) — installation, RubyLLM setup, Agent/Workflow basics, persistence, streaming.
|
|
136
143
|
- [Features and API stability](docs/features.md) — public feature matrix and stability labels.
|
|
144
|
+
- [Architecture](docs/architecture.md) — canonical current explanatory architecture entry and authority navigation.
|
|
137
145
|
- [Runtime and concurrency](docs/runtime-and-concurrency.md) — EventLoop, FSMSession, Task, OffloadPool, cancellation, observability.
|
|
138
146
|
- [MCP client](docs/mcp-client.md) — Model Context Protocol (MCP) integration and supported schema subset.
|
|
139
147
|
- [Migration from 0.15-era APIs](docs/migrations/0.15.md).
|
|
140
148
|
- [0.16 cleanup migration](docs/migrations/0.16.md).
|
|
141
149
|
- [0.19 unified Persistence migration](docs/migrations/0.19.md).
|
|
150
|
+
- [0.22 semantic Multi-Agent Handoff migration](docs/migrations/0.22.md).
|
|
142
151
|
- [Architecture Decision Records](docs/decisions/) — design rationale and superseding decisions.
|
|
143
152
|
- [CHANGELOG](CHANGELOG.md) — current development and recent release history.
|
|
144
153
|
- [Changelog archive: 0.14.0 and earlier](docs/changelog/0.14-and-earlier.md).
|