phronomy 0.23.0 → 0.24.1

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/.mutant.yml +2 -2
  3. data/CHANGELOG.md +18 -0
  4. data/CONTRIBUTING.md +2 -2
  5. data/README.md +1 -1
  6. data/docs/architecture/multi-agent-handoff.md +35 -40
  7. data/docs/architecture/persistence.md +19 -8
  8. data/docs/architecture.md +8 -1
  9. data/docs/decisions/016-semantic-multi-agent-handoff.md +3 -1
  10. data/docs/decisions/028-preparing-recovery-replay-contract.md +106 -0
  11. data/docs/decisions/029-semantic-completion-and-application-effect-boundary.md +220 -0
  12. data/docs/decisions/030-agent-handoff-domain-and-durable-responsibility.md +235 -0
  13. data/docs/decisions/031-durable-multi-agent-coordination.md +301 -0
  14. data/docs/decisions/README.md +5 -1
  15. data/docs/design/durable-semantic-coordination/CHANGELOG_V2_REVISION_2.md +33 -0
  16. data/docs/design/durable-semantic-coordination/CONTINUATION_DECISION_REFACTOR.md +191 -0
  17. data/docs/design/durable-semantic-coordination/IMPLEMENTATION_DESIGN_V2.md +862 -0
  18. data/docs/design/durable-semantic-coordination/IMPLEMENTATION_REPORT.md +106 -0
  19. data/docs/design/durable-semantic-coordination/RECOVERY_CONTRACT_CLARIFICATIONS.md +179 -0
  20. data/docs/design/durable-semantic-coordination/RESPONSIBILITY_BOUNDARY_REVIEW.md +302 -0
  21. data/docs/features.md +35 -1
  22. data/docs/migrations/durable-semantic-coordination-v2.md +65 -0
  23. data/docs/persistence-backends.md +42 -3
  24. data/lib/phronomy/agent/agent_execution.rb +2 -2
  25. data/lib/phronomy/agent/agent_invocation.rb +1 -1
  26. data/lib/phronomy/agent/async_event_api.rb +18 -1
  27. data/lib/phronomy/agent/base.rb +28 -0
  28. data/lib/phronomy/agent/context_assembler.rb +1 -1
  29. data/lib/phronomy/agent/exact_execution.rb +153 -0
  30. data/lib/phronomy/agent/execution_cancellation.rb +25 -0
  31. data/lib/phronomy/agent/execution_coordinator.rb +484 -27
  32. data/lib/phronomy/{multi_agent → agent}/handoff.rb +4 -4
  33. data/lib/phronomy/{multi_agent → agent}/handoff_capability_factory.rb +3 -45
  34. data/lib/phronomy/{multi_agent → agent}/handoff_context.rb +26 -1
  35. data/lib/phronomy/{multi_agent/execution_coordinator.rb → agent/handoff_execution_coordinator.rb} +32 -5
  36. data/lib/phronomy/{multi_agent → agent}/handoff_policy.rb +7 -1
  37. data/lib/phronomy/{multi_agent → agent}/handoff_projection.rb +18 -2
  38. data/lib/phronomy/{multi_agent → agent}/handoff_request.rb +2 -2
  39. data/lib/phronomy/agent/handoff_runner.rb +178 -0
  40. data/lib/phronomy/agent/handoff_state.rb +43 -0
  41. data/lib/phronomy/agent/recovery_coordinator/continuation.rb +114 -211
  42. data/lib/phronomy/agent/recovery_coordinator/installation.rb +84 -130
  43. data/lib/phronomy/agent/recovery_coordinator/resolution.rb +76 -200
  44. data/lib/phronomy/agent/recovery_coordinator.rb +11 -5
  45. data/lib/phronomy/agent/recovery_support.rb +15 -23
  46. data/lib/phronomy/agent/ruby_llm_materializer.rb +2 -8
  47. data/lib/phronomy/agent/tool_invocation.rb +4 -2
  48. data/lib/phronomy/engine/runtime/team_ownership_registry.rb +77 -0
  49. data/lib/phronomy/engine/runtime.rb +16 -1
  50. data/lib/phronomy/multi_agent/durable_subagent_coordinator.rb +134 -0
  51. data/lib/phronomy/multi_agent/orchestrator.rb +59 -11
  52. data/lib/phronomy/multi_agent/team_coordinator.rb +473 -125
  53. data/lib/phronomy/multi_agent/team_execution.rb +44 -0
  54. data/lib/phronomy/multi_agent/team_root.rb +41 -0
  55. data/lib/phronomy/persistence/durable_codec.rb +60 -0
  56. data/lib/phronomy/persistence/in_memory.rb +264 -2
  57. data/lib/phronomy/persistence/repository_facades.rb +221 -2
  58. data/lib/phronomy/persistence.rb +95 -1
  59. data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +1 -0
  60. data/lib/phronomy/testing/persistence_contract/coordination_repositories.rb +137 -0
  61. data/lib/phronomy/testing/persistence_contract.rb +5 -0
  62. data/lib/phronomy/tools/agent.rb +1 -1
  63. data/lib/phronomy/version.rb +1 -1
  64. data/scripts/api_snapshot.rb +3 -3
  65. data/sig/phronomy/handoff.rbs +41 -0
  66. data/sig/phronomy/multi_agent.rbs +28 -32
  67. data/sig/phronomy/persistence.rbs +64 -3
  68. metadata +44 -12
  69. data/lib/phronomy/multi_agent/coordination_state.rb +0 -18
  70. data/lib/phronomy/multi_agent/coordinator.rb +0 -154
  71. data/lib/phronomy/multi_agent/runner.rb +0 -98
@@ -0,0 +1,235 @@
1
+ # ADR-030: Agent Handoff Domain and Durable Responsibility
2
+
3
+ ## Status
4
+
5
+ Accepted. V2 revision 2, 2026-09-06.
6
+
7
+ User approval covers the V2 boundary and the five recovery-contract clarifications.
8
+ Acceptance is design authority; it is not a claim of repository integration or test success.
9
+
10
+ ## Date
11
+
12
+ 2026-09-06
13
+
14
+ ## Partially supersedes
15
+
16
+ `016-semantic-multi-agent-handoff` for:
17
+
18
+ - namespace/domain placement of Handoff;
19
+ - Runtime-local-only active responsibility;
20
+ - allowance for independent Source/Target Persistence domains in the durable
21
+ Handoff path; and
22
+ - the public Handoff Runner namespace.
23
+
24
+ ADR-016 remains the historical rationale and remains authoritative for the
25
+ Source-to-Target semantic transfer model, HandoffPolicy category semantics,
26
+ Context dependency grouping, immutable transferred Context, Target ContextPolicy
27
+ ownership, and provenance rules except where this ADR explicitly changes them.
28
+
29
+ ## Context
30
+
31
+ ADR-016 intentionally made active Handoff responsibility Runtime-local. Process
32
+ reset therefore restarted responsibility at the main Agent.
33
+
34
+ That behavior is insufficient for a framework-owned Handoff abstraction once the
35
+ Source execution has durably committed `:handed_off`: process loss must not force
36
+ Source semantic work to run again merely to rediscover the Target.
37
+
38
+ This is a framework semantic-routing concern, not an Application callback concern.
39
+ ADR-029 therefore does not make Handoff durability depend on restart-spanning
40
+ notification delivery.
41
+
42
+ ## Decision
43
+
44
+ ### 1. Handoff moves to the Agent domain
45
+
46
+ Public types move as a clean break:
47
+
48
+ ```text
49
+ Phronomy::MultiAgent::Handoff
50
+ -> Phronomy::Agent::Handoff
51
+
52
+ Phronomy::MultiAgent::HandoffPolicy
53
+ -> Phronomy::Agent::HandoffPolicy
54
+
55
+ Phronomy::MultiAgent::Runner
56
+ -> Phronomy::Agent::HandoffRunner
57
+ ```
58
+
59
+ Handoff-specific private types move under the Agent Handoff implementation
60
+ boundary.
61
+
62
+ No compatibility alias is required by this ADR.
63
+
64
+ ### 2. `main_agent.agent_id` is the durable routing anchor
65
+
66
+ No generic coordination/thread/session identity is introduced.
67
+
68
+ ```text
69
+ main_agent.agent_id
70
+ = durable Handoff routing anchor
71
+ ```
72
+
73
+ One durable HandoffState is keyed by that identity.
74
+
75
+ ### 3. Persistence adds `handoff_states`
76
+
77
+ The durable state contains semantic routing facts only:
78
+
79
+ ```text
80
+ main_agent_id
81
+ handoff_revision
82
+ active_agent_id
83
+ active_handoff_context_ref
84
+ phase
85
+ pending_source_execution_id
86
+ pending_target_execution_id
87
+ created_at
88
+ updated_at
89
+ metadata
90
+ ```
91
+
92
+ It never stores Agent instances, Agent classes, Procs, HandoffPolicy objects,
93
+ Tasks, FSMSessions or EventLoop routing state.
94
+
95
+ ### 4. One durable Handoff graph uses one Persistence domain
96
+
97
+ The main/source/target Agents and HandoffState must use the same
98
+ `Phronomy::Persistence` transaction domain.
99
+
100
+ A graph requiring a distributed transaction across independent Persistence
101
+ domains is rejected before semantic work.
102
+
103
+ ### 5. Source terminalization and responsibility transfer are one semantic transaction
104
+
105
+ When a Source chooses a valid Handoff, Phronomy:
106
+
107
+ 1. resolves the current finalized Source Manifest;
108
+ 2. applies HandoffPolicy projection;
109
+ 3. materializes immutable HandoffContext;
110
+ 4. reserves the exact Target `execution_id`;
111
+ 5. commits Source `:handed_off` and HandoffState transfer atomically.
112
+
113
+ The transaction records at least:
114
+
115
+ ```text
116
+ Source AgentExecution -> :handed_off
117
+ Source AgentRoot terminal/idle revision
118
+ Source Journal audit facts
119
+ HandoffContext content reference
120
+ HandoffState.active_agent_id -> Target
121
+ HandoffState.active_handoff_context_ref -> transferred Context
122
+ HandoffState.phase -> target_pending
123
+ HandoffState.pending_source_execution_id -> Source execution_id
124
+ HandoffState.pending_target_execution_id -> reserved Target execution_id
125
+ ```
126
+
127
+ There is no terminal callback-delivery descriptor in this transaction.
128
+
129
+ ### 6. Target execution identity is reserved before Target semantic work
130
+
131
+ Recovery uses the exact reserved Target `execution_id`:
132
+
133
+ ```text
134
+ authoritatively absent after a successful read
135
+ -> establish that exact reserved execution only after admission is confirmed
136
+
137
+ nonterminal
138
+ -> recover that exact execution
139
+
140
+ terminal
141
+ -> consume its durable outcome; never create a replacement execution
142
+ ```
143
+
144
+ The execution ID is semantic Agent identity, not Runtime FSMSession identity.
145
+
146
+ ### 7. Active responsibility survives later turns and process loss
147
+
148
+ When a Handoff turn ends normally at Target B, `active_agent_id` remains B.
149
+
150
+ The next HandoffRunner turn starts at B.
151
+
152
+ After process reset, compatible HandoffRunner wiring loads the same HandoffState
153
+ and again starts/resumes from B rather than reverting to the original main Agent.
154
+
155
+ ### 8. Multi-hop updates the same HandoffState
156
+
157
+ A -> B -> C updates the original main-Agent-anchored HandoffState.
158
+
159
+ No nested generic coordination IDs are created.
160
+
161
+ ### 9. Runtime graph/Policy wiring is Application code
162
+
163
+ HandoffRunner requires the current Application-supplied Handoff graph and Policies
164
+ to reconstruct Runtime behavior.
165
+
166
+ Those Ruby objects are never persisted.
167
+
168
+ If required wiring is absent or incompatible, recovery fails closed instead of:
169
+
170
+ - reverting to main Agent;
171
+ - inventing a graph;
172
+ - blindly replaying Source work.
173
+
174
+ ### 10. HandoffContext is durably materializable but not adopted automatically
175
+
176
+ The canonical immutable HandoffContext value is stored in ContentStore and
177
+ referenced by HandoffState/execution metadata.
178
+
179
+ Transferred material remains request-scoped Target Context unless Target
180
+ execution creates its own canonical Journal/Knowledge facts.
181
+
182
+ ### 11. Local Application events are Runtime-only
183
+
184
+ A Source may emit a same-process `:handoff` event.
185
+
186
+ That event is not durable routing authority and is not redelivered after restart.
187
+
188
+ Handoff coordination correctness depends only on durable semantic routing facts.
189
+
190
+ ### 12. Recovery evidence, compatibility and cancellation
191
+
192
+ Apply [RC-01 through RC-05](../design/durable-semantic-coordination/RECOVERY_CONTRACT_CLARIFICATIONS.md).
193
+ Read failures/unknown commit outcomes must not be treated as Target absence.
194
+ Readback reconciles the same reserved execution and transfer facts; admission
195
+ races use existing atomic admission/CAS, never a replacement Target ID.
196
+
197
+ Before continuation, check main/active/Target identities, current required graph
198
+ connections, declared definition compatibility and the same Persistence instance.
199
+ Absent an existing explicit migration/compatibility contract, definition id/version
200
+ must match. Current wiring never reprojects committed HandoffContext. Proc/code
201
+ hashing and automatic semantic code-compatibility detection are not introduced.
202
+
203
+ Result reads follow the specified run's recorded Target, not an unrelated later
204
+ turn's latest active result. Continuation wiring is not required merely to read
205
+ stored status/canonical results.
206
+
207
+ After transfer commit the Source remains handed_off. Observation loss or cancel
208
+ must not roll active responsibility back to main. An explicit cancellation of the
209
+ current turn is routed to that turn's exact reserved Target under existing Agent
210
+ cancellation rules; it does not cancel unrelated/later executions. Preserve the
211
+ facts needed to reconcile cancellation/admission races and process loss.
212
+
213
+ ## Required invariants
214
+
215
+ 1. Handoff is an Agent-domain capability.
216
+ 2. `main_agent.agent_id` is the durable routing anchor.
217
+ 3. Active responsibility survives process loss.
218
+ 4. Source `:handed_off` and durable responsibility transfer cannot diverge.
219
+ 5. Target semantic work never starts without a recoverable reserved execution ID.
220
+ 6. A committed Source Handoff is never blindly replayed.
221
+ 7. Recovery reconstructs fresh Runtime objects.
222
+ 8. Graph/Policy Ruby objects are supplied by Application code, not persisted.
223
+ 9. All durable graph participants share one Persistence domain.
224
+ 10. Application callback delivery is not part of Handoff durability.
225
+
226
+ ## Non-goals
227
+
228
+ This ADR does not:
229
+
230
+ - make arbitrary external effects exactly once;
231
+ - provide restart-spanning local Handoff callback delivery;
232
+ - add distributed transactions across Persistence domains;
233
+ - add generic coordination/session/thread identity;
234
+ - persist HandoffPolicy/Application code;
235
+ - merge Source and Target Agent state.
@@ -0,0 +1,301 @@
1
+ # ADR-031: Durable Multi-Agent Semantic Coordination
2
+
3
+ ## Status
4
+
5
+ Accepted. V2 revision 2, 2026-09-06.
6
+
7
+ User approval covers the V2 boundary and the five recovery-contract clarifications.
8
+ Acceptance is design authority; it is not a claim of repository integration or test success.
9
+
10
+ ## Date
11
+
12
+ 2026-09-06
13
+
14
+ ## Context
15
+
16
+ Phronomy exposes:
17
+
18
+ - `MultiAgent::Orchestrator < Agent::Base`, with child Agents/Tools and fan-out
19
+ helpers; and
20
+ - `MultiAgent::TeamCoordinator`, with coordinator-generated tasks and a worker pool.
21
+
22
+ Individual AgentExecutions are durable, but process-local coordination state is
23
+ not. Losing child identities, task assignments or confirmed worker outcomes can
24
+ cause Phronomy to repeat semantic work it owns.
25
+
26
+ The previous proposal also attempted to make standalone fan-out convenience APIs,
27
+ arbitrary Team aggregation callbacks and terminal Application callbacks durable.
28
+ Responsibility review found those parts too broad.
29
+
30
+ This ADR therefore defines durability at the **framework-owned semantic
31
+ coordination boundary**, not at every callback/convenience API boundary.
32
+
33
+ ## Decision
34
+
35
+ ### 1. MultiAgent durability means semantic progress recovery
36
+
37
+ For a durable MultiAgent operation:
38
+
39
+ ```text
40
+ process/runtime loss
41
+ -> reconstruct from durable coordination facts
42
+ -> reuse confirmed child/worker outcomes
43
+ -> recover exact unfinished executions
44
+ -> admit absent reserved executions only after authoritative read/admission
45
+ -> resolve unknown external effects through existing Agent Recovery
46
+ ```
47
+
48
+ FSMSession, Task, callback and Runtime queues remain disposable.
49
+
50
+ ### 2. Orchestrator durability is rooted in an existing Orchestrator AgentExecution
51
+
52
+ `MultiAgent::Orchestrator < Agent::Base` already has canonical Agent identity.
53
+
54
+ When child coordination occurs **inside an existing Orchestrator AgentExecution**,
55
+ that AgentExecution references an immutable coordination snapshot containing, as
56
+ needed:
57
+
58
+ ```text
59
+ coordination kind / phase
60
+ child slot
61
+ child Agent definition identity/version
62
+ reserved child agent_id
63
+ reserved child execution_id
64
+ restart-required input/config refs
65
+ child semantic state
66
+ result_ref / error_ref
67
+ on_error / max_concurrency semantic options
68
+ ```
69
+
70
+ No separate Orchestrator repository or generic multi-agent execution ID is added.
71
+
72
+ ### 3. Existing fan-out Runtime FSM remains reconstructable machinery
73
+
74
+ `FanOutInvocation` / `FSMSession` remain Runtime projections.
75
+
76
+ Recovery builds a fresh runtime invocation/session from the durable coordination
77
+ snapshot and fresh Runtime identities.
78
+
79
+ ### 4. Framework-owned child identities are reserved before semantic work
80
+
81
+ Before a durable Orchestrator child begins:
82
+
83
+ ```text
84
+ reserve child agent_id
85
+ reserve child execution_id
86
+ persist parent child slot + restart-required refs
87
+ then create/load child and start exact reserved execution
88
+ ```
89
+
90
+ Recovery distinguishes absent/nonterminal/terminal exact child state and never
91
+ creates a replacement simply because Runtime callbacks were lost.
92
+
93
+ ### 5. Durable child definitions must be reconstructable from stable wiring
94
+
95
+ For the durable path, a child Agent class must be resolvable from stable current
96
+ Orchestrator/Application wiring, initially the concrete Orchestrator class's
97
+ registered subagents.
98
+
99
+ Invocation-only anonymous/arbitrary class handles are not persisted.
100
+
101
+ This restriction applies only to APIs/paths that claim restart durability.
102
+
103
+ ### 6. Standalone `dispatch_parallel*` / `fan_out*` remain Runtime-only convenience APIs
104
+
105
+ A direct Application call to:
106
+
107
+ ```ruby
108
+ orchestrator.dispatch_parallel(...)
109
+ orchestrator.fan_out(...)
110
+ ```
111
+
112
+ outside a live parent Orchestrator AgentExecution does **not** create a synthetic
113
+ AgentExecution solely for durability.
114
+
115
+ It keeps current-process semantics and may continue accepting Runtime-only Agent
116
+ class wiring.
117
+
118
+ If durable fan-out is required, the Application must place the work under:
119
+
120
+ - an Orchestrator AgentExecution with stable child wiring; or
121
+ - an Application Workflow when the operation is application-process
122
+ orchestration.
123
+
124
+ This avoids inventing durable parent identity for a convenience call.
125
+
126
+ ### 7. Durable framework-owned Orchestrator children share the parent Persistence domain
127
+
128
+ A durable parent/child coordination path uses the same Persistence domain.
129
+
130
+ External remote effects reached through Tools/Application integration remain X0
131
+ external effects.
132
+
133
+ ### 8. TeamCoordinator is a purpose-specific durable semantic entity
134
+
135
+ TeamCoordinator remains under `MultiAgent`, not `Agent::Base`.
136
+
137
+ It gains:
138
+
139
+ ```text
140
+ team_id
141
+ team_execution_id
142
+ team_definition id/version
143
+ TeamRoot
144
+ TeamExecution
145
+ ```
146
+
147
+ This is retained because Phronomy itself owns the Team queue/assignment/worker
148
+ abstraction.
149
+
150
+ ### 9. Team task queue and worker assignment are durable facts
151
+
152
+ TeamExecution durably records:
153
+
154
+ ```text
155
+ canonical tasks
156
+ task-generation finalized state
157
+ worker slots / stable worker agent_id
158
+ task -> worker assignment
159
+ reserved worker execution_id
160
+ worker terminal result/error
161
+ final Team result/error
162
+ ```
163
+
164
+ Before worker semantic execution starts, its assignment and reserved exact
165
+ execution identity are committed.
166
+
167
+ ### 10. Worker identity is stable within one TeamExecution
168
+
169
+ A worker slot reuses its logical Agent identity for that TeamExecution so worker
170
+ context/transcript semantics remain coherent across assigned tasks.
171
+
172
+ This ADR does not require worker identity/history to survive into another
173
+ TeamExecution.
174
+
175
+ ### 11. Team scheduler is a replay-safe decision function
176
+
177
+ Application `schedule` may run again while no assignment has been durably
178
+ committed.
179
+
180
+ Contract:
181
+
182
+ - it must not perform externally observable one-shot effects;
183
+ - it selects from the supplied available worker projection;
184
+ - repeated execution before assignment commit is allowed;
185
+ - after assignment commit, recovery uses the durable assignment and does not
186
+ rerun scheduling for that task.
187
+
188
+ No scheduler result needs a separate unknown-outcome protocol.
189
+
190
+ ### 12. Team aggregation is pure/replay-safe result computation
191
+
192
+ Application `aggregate` receives canonical durable assignment results.
193
+
194
+ Contract:
195
+
196
+ - no externally observable one-shot side effects;
197
+ - repeated invocation with the same canonical assignments must be semantically
198
+ equivalent;
199
+ - if process loss occurs before aggregate result/error is durably committed,
200
+ Phronomy may invoke `aggregate` again;
201
+ - on normal return/raise, Phronomy durably records the final result/error before
202
+ Team terminalization.
203
+
204
+ There is no `aggregation=started -> outcome unknown -> manual resolve` protocol.
205
+
206
+ Applications perform external post-Team effects after obtaining/reconciling the
207
+ Team result.
208
+
209
+ ### 13. Team progress and terminal callbacks are Runtime-only
210
+
211
+ Streaming task-completion callbacks and final Application notifications are
212
+ current-process observations.
213
+
214
+ Canonical task/worker/Team semantic outcomes are durable; callback delivery is
215
+ not.
216
+
217
+ No Team delivery-pending index or restart redelivery obligation is introduced.
218
+
219
+ ### 14. Workflow remains the Application process-orchestration domain
220
+
221
+ Public domain ownership remains:
222
+
223
+ ```text
224
+ Agent
225
+ Agent semantic execution + Agent Handoff
226
+
227
+ MultiAgent
228
+ durable framework-owned Orchestrator child coordination
229
+ durable Team queue/assignment/worker coordination
230
+ Runtime-only convenience fan-out outside a durable parent
231
+
232
+ Workflow
233
+ explicit Application-defined durable process/state-machine orchestration
234
+ durable ordering of Application-owned steps/effects when modeled by the app
235
+ ```
236
+
237
+ ### 15. Recovery contract clarifications
238
+
239
+ The normative [RC-01 through RC-05 contracts](../design/durable-semantic-coordination/RECOVERY_CONTRACT_CLARIFICATIONS.md)
240
+ apply to existing Orchestrator executions and Team executions:
241
+
242
+ - expose read-only status/result access and retained execution discovery;
243
+ - distinguish authoritative absence from read failure/unknown commit outcome;
244
+ - reconcile writes with the same reserved identities using existing Persistence
245
+ protocols, including Team-owned operation facts;
246
+ - verify declared definition id/version, registered slot wiring and reserved
247
+ owner/Agent/execution identities before continuation;
248
+ - preserve committed inputs/config, assignments and outcomes instead of
249
+ recalculating them with changed current code;
250
+ - distinguish observation loss/shutdown from semantic cancellation;
251
+ - stop new dispatch on accepted parent-run cancellation, reconcile already
252
+ admitted children using existing Agent cancellation and terminal barriers,
253
+ retain terminal outcomes and exact identities needed after restart;
254
+ - restrict cancellation to the current run's owned children, never unrelated
255
+ executions or later runs.
256
+
257
+ Stable version declarations do not prove Ruby code equivalence. Application code
258
+ must maintain declared compatibility; no Proc hash or generic registry is added.
259
+ Uncommitted replay-safe schedule/aggregate computation remains replayable.
260
+ No dedicated cancellation execution engine or callback recovery service is added.
261
+
262
+ ## Persistence changes
263
+
264
+ The durable root surface expands to include:
265
+
266
+ ```text
267
+ handoff_states
268
+ teams
269
+ team_executions
270
+ ```
271
+
272
+ Orchestrator continues to use Agent repositories.
273
+
274
+ No execution/team terminal-delivery pending index is added.
275
+
276
+ ## Required invariants
277
+
278
+ 1. Durable coordination is claimed only where a durable semantic root exists.
279
+ 2. Confirmed child/worker terminal work is never blindly rerun.
280
+ 3. Child/worker semantic work begins only after exact recoverable identity is
281
+ durably known.
282
+ 4. Orchestrator durable child coordination uses its existing AgentExecution.
283
+ 5. Standalone convenience fan-out is explicitly Runtime-only.
284
+ 6. Team has stable identity/execution and durable tasks/assignments/worker results.
285
+ 7. Scheduler and aggregator are replay-safe Application functions, not arbitrary
286
+ side-effect transaction boundaries.
287
+ 8. Callback/Task/FSMSession/Proc objects are never persisted.
288
+ 9. Workflow remains the appropriate domain for Application-defined durable process
289
+ orchestration.
290
+
291
+ ## Non-goals
292
+
293
+ This ADR does not:
294
+
295
+ - make standalone convenience fan-out restart-durable;
296
+ - make external Provider/Tool/Application effects exactly once;
297
+ - persist scheduler/aggregator Procs or callbacks;
298
+ - provide restart-spanning Team callback delivery;
299
+ - require worker history across TeamExecutions;
300
+ - add a generic global Agent class registry;
301
+ - turn MultiAgent into a public Workflow alias.
@@ -64,7 +64,7 @@ resolved explicitly.
64
64
  | [`013-journal-backed-knowledge-as-context-candidates`](013-journal-backed-knowledge-as-context-candidates.md) | Accepted | Yes | Current persistent Knowledge authority. |
65
65
  | [`014-unified-persistence-durable-state`](014-unified-persistence-durable-state.md) | Accepted | Yes | Durable-backend and live-owner/no-reload intent remains current; live Agent execution mutation is refined by ADR-024, same-process Agent identity/admission ownership by ADR-025, and same-process Workflow admission/terminal-barrier ordering by ADR-026. Workflow identity terminology is superseded by ADR-020, generic `InvocationContext` / Agent correlation semantics by ADR-021, and concrete FSMSession/Agent-Tool routing identity by ADR-023. |
66
66
  | [`015-tool-public-facade-and-rbs-boundary`](015-tool-public-facade-and-rbs-boundary.md) | Accepted | Yes | Current Tool façade / extension-SPI / RBS boundary. |
67
- | [`016-semantic-multi-agent-handoff`](016-semantic-multi-agent-handoff.md) | Accepted | Yes | Current semantic Handoff intent; runtime/context-transfer reconciliation is implemented and reflected in current architecture documentation. |
67
+ | [`016-semantic-multi-agent-handoff`](016-semantic-multi-agent-handoff.md) | Superseded | No | Superseded by [ADR-030](030-agent-handoff-domain-and-durable-responsibility.md), including Agent-domain ownership and exact Target recovery. |
68
68
  | [`017-design-authority-and-adr-governance`](017-design-authority-and-adr-governance.md) | Accepted | Yes | Repository-wide architecture authority and ADR governance. |
69
69
  | [`018-durability-guarantees-and-failure-model`](018-durability-guarantees-and-failure-model.md) | Accepted | Yes | Repository-wide durability/concurrency/external-effect guarantee vocabulary and F0-F4/X0 failure model. |
70
70
  | [`019-filter-contract-and-security-boundaries`](019-filter-contract-and-security-boundaries.md) | Accepted | Yes | Current Filter transform/block and bounded PromptInjectionFilter/isolation boundaries; the follow-up review adds no fourth Context Filter call site and places semantic Context trust in Application ContextPolicy. |
@@ -76,6 +76,10 @@ resolved explicitly.
76
76
  | [`025-process-local-agent-ownership-and-runtime-admission`](025-process-local-agent-ownership-and-runtime-admission.md) | Accepted | Yes | One mutable live Agent owner per `agent_id` per Runtime; EventLoop is the primary same-process top-level admission authority while Persistence admission remains durable defense. |
77
77
  | [`026-workflow-runtime-admission-and-durable-terminal-barrier`](026-workflow-runtime-admission-and-durable-terminal-barrier.md) | Accepted | Yes | EventLoop-owned opaque Workflow admission owner, admission-before-hydration ordering, and FSMSession-integrated durable terminal save barrier with fail-closed uncertain outcomes. |
78
78
  | [`027-llm-adapter-provider-boundary`](027-llm-adapter-provider-boundary.md) | Accepted | Yes | Phronomy-owned Provider-call extension boundary; RubyLLM is the default adapter/integration while current input materialization remains RubyLLM-specific. |
79
+ | [`028-preparing-recovery-replay-contract`](028-preparing-recovery-replay-contract.md) | Accepted | Yes | Adds replay-safe same-`execution_id` recovery for durably admitted Agent `:preparing` executions when replayability is durably established; unsupported Runtime-only dependencies fail closed. |
80
+ | [`029-semantic-completion-and-application-effect-boundary`](029-semantic-completion-and-application-effect-boundary.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. |
81
+ | [`030-agent-handoff-domain-and-durable-responsibility`](030-agent-handoff-domain-and-durable-responsibility.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. |
82
+ | [`031-durable-multi-agent-coordination`](031-durable-multi-agent-coordination.md) | Accepted | Yes | V2 revision 2; framework semantic coordination and Application effect boundary. |
79
83
 
80
84
  ## Legacy duplicate `011`
81
85
 
@@ -0,0 +1,33 @@
1
+ # V2 revision 2 — 改訂内容
2
+
3
+ 更新日: 2026-09-06 / 状態: Accepted
4
+
5
+ ## 合意反映
6
+
7
+ | 項目 | 今回の修正 |
8
+ |---|---|
9
+ | RC-01 結果参照 | exact実行IDで状態・結果を読み取る契約と、ID受領前の停止に備えたownerからの候補発見を追加 |
10
+ | RC-02 保存成否不明 | 正常な不存在、read障害、CAS競合、commit成否不明を区別。同じ予約済みidentityで照合 |
11
+ | RC-03 wiring互換性 | 定義id/version・slot・graph・Persistence境界の最低照合と、確定済みfactの優先を明記 |
12
+ | RC-04 cancellation | 観測終了/shutdownとsemantic cancelを区別。子の状態別処理、競合、restart後の再発見を明記 |
13
+ | RC-05 保証表現 | 確定outcome再利用・同一identity復旧・外部成否不明は既存Recovery、に統一 |
14
+
15
+ ADR-029/030/031、実装設計、責務境界レビュー、READMEへ対応する規範的記述を反映した。
16
+ 詳細契約と検証条件はRECOVERY_CONTRACT_CLARIFICATIONS.mdにまとめ、資料間で参照する。
17
+ 承認前のProposed表記をAcceptedへ更新した。新機能の再承認を要求しない。
18
+
19
+ ## 実装状態の訂正
20
+
21
+ 引き継ぎ文書の旧実装件数・静的検証成功は、前セッションの報告として残す。
22
+ この分岐先で実装を再検証した事実にはしない。現在取得できたのは設計資料と引き継ぎ文書であり、
23
+ 旧overlay/apply.py/APPLY.sh/VERIFY.shは未取得。再開手順も実ファイルの回収から始める形に更新した。
24
+
25
+ ## 今回実施した確認
26
+
27
+ - 対象資料の承認状態、baseline、相互参照の整合確認。
28
+ - 旧い「未承認のため実装停止」表現と、外部効果のexactly-onceに読める保証表現の修正。
29
+ - RC-01〜05のADR・実装設計・検証条件への対応確認。
30
+ - ZIP構成、全文書のSHA256SUMS、ZIP/引き継ぎ文書の外部SHA256の検証。
31
+
32
+ 対象repositoryのコード変更・RSpec実行は行っていない。
33
+ API名や例外名は未確認のものを作らず、baselineへの対応付けを実装前の必須作業とした。