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.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.mutant.yml +3 -4
  3. data/CHANGELOG.md +200 -10
  4. data/CONTRIBUTING.md +81 -9
  5. data/README.md +15 -6
  6. data/VERIFY.sh +587 -0
  7. data/benchmark/bench_agent_invoke.rb +2 -2
  8. data/benchmark/bench_context_assembler.rb +39 -68
  9. data/benchmark/bench_regression.rb +2 -2
  10. data/docs/architecture/agent-context.md +174 -0
  11. data/docs/architecture/before-llm-input.md +78 -0
  12. data/docs/architecture/context-management.md +232 -0
  13. data/docs/architecture/knowledge-and-rag.md +130 -0
  14. data/docs/architecture/multi-agent-handoff.md +152 -0
  15. data/docs/architecture/persistence.md +175 -0
  16. data/docs/architecture/removed/agent-context.md +72 -0
  17. data/docs/architecture/security-boundaries.md +173 -0
  18. data/docs/architecture/tracing.md +194 -0
  19. data/docs/architecture.md +82 -0
  20. data/docs/archive/design/archived/04_api_design.md +507 -0
  21. data/docs/archive/design/archived/09_guardrails.md +186 -0
  22. data/docs/archive/design/archived/17_rails_integration.md +175 -0
  23. data/docs/archive/design/historical/00_design_philosophy.md +122 -0
  24. data/docs/archive/design/historical/01_rubyllm_evaluation.md +178 -0
  25. data/docs/archive/design/historical/06_design_decisions.md +143 -0
  26. data/docs/changelog/0.14-and-earlier.md +1 -1
  27. data/docs/decisions/001-rubyllm-as-provider-layer.md +6 -1
  28. data/docs/decisions/002-workflow-context-immutability.md +26 -1
  29. data/docs/decisions/006-no-built-in-guardrails.md +2 -1
  30. data/docs/decisions/012-canonical-execution-log-and-context-policy.md +120 -38
  31. data/docs/decisions/014-unified-persistence-durable-state.md +9 -2
  32. data/docs/decisions/016-semantic-multi-agent-handoff.md +112 -0
  33. data/docs/decisions/017-design-authority-and-adr-governance.md +200 -0
  34. data/docs/decisions/018-durability-guarantees-and-failure-model.md +488 -0
  35. data/docs/decisions/019-filter-contract-and-security-boundaries.md +229 -0
  36. data/docs/decisions/020-canonical-workflow-instance-identity.md +177 -0
  37. data/docs/decisions/021-generic-agent-invocation-identity-removal.md +119 -0
  38. data/docs/decisions/022-agent-execution-parent-identity-and-runtime-routing-boundary.md +193 -0
  39. data/docs/decisions/023-fsm-session-incarnation-identity-and-routing.md +139 -0
  40. data/docs/decisions/024-event-loop-single-writer-agent-runtime.md +188 -0
  41. data/docs/decisions/025-process-local-agent-ownership-and-runtime-admission.md +249 -0
  42. data/docs/decisions/026-workflow-runtime-admission-and-durable-terminal-barrier.md +257 -0
  43. data/docs/decisions/027-llm-adapter-provider-boundary.md +93 -0
  44. data/docs/decisions/README.md +172 -0
  45. data/docs/features.md +31 -11
  46. data/docs/getting-started.md +77 -45
  47. data/docs/migrations/0.19.md +14 -7
  48. data/docs/migrations/0.22.md +390 -0
  49. data/docs/persistence-backends.md +88 -38
  50. data/docs/runtime-and-concurrency.md +227 -33
  51. data/examples/README.md +13 -0
  52. data/lib/phronomy/agent/agent_execution.rb +19 -15
  53. data/lib/phronomy/agent/agent_invocation.rb +288 -93
  54. data/lib/phronomy/agent/agent_invocation_session_builder.rb +236 -202
  55. data/lib/phronomy/agent/agent_root.rb +3 -3
  56. data/lib/phronomy/agent/approval_evaluation_request.rb +37 -19
  57. data/lib/phronomy/agent/async_event_api.rb +145 -72
  58. data/lib/phronomy/agent/base.rb +388 -181
  59. data/lib/phronomy/agent/concerns/before_llm_input.rb +1 -1
  60. data/lib/phronomy/agent/context_assembler.rb +437 -178
  61. data/lib/phronomy/agent/context_candidate_resolver.rb +2 -2
  62. data/lib/phronomy/agent/context_plan.rb +18 -13
  63. data/lib/phronomy/agent/context_plan_validator.rb +246 -88
  64. data/lib/phronomy/agent/context_policies/default.rb +123 -34
  65. data/lib/phronomy/agent/context_policy.rb +109 -3
  66. data/lib/phronomy/agent/context_policy_input.rb +244 -0
  67. data/lib/phronomy/agent/context_policy_input_builder.rb +241 -0
  68. data/lib/phronomy/agent/execution_coordinator.rb +1975 -587
  69. data/lib/phronomy/agent/journal_record.rb +17 -4
  70. data/lib/phronomy/agent/llm_input_build_context.rb +1 -1
  71. data/lib/phronomy/agent/llm_input_manifest.rb +277 -2
  72. data/lib/phronomy/agent/llm_operation_result.rb +12 -7
  73. data/lib/phronomy/agent/phase_machine_builder.rb +19 -7
  74. data/lib/phronomy/agent/provider_call_outcome.rb +23 -7
  75. data/lib/phronomy/agent/recovery_coordinator/continuation.rb +271 -0
  76. data/lib/phronomy/agent/recovery_coordinator/installation.rb +427 -0
  77. data/lib/phronomy/agent/recovery_coordinator/resolution.rb +635 -0
  78. data/lib/phronomy/agent/recovery_coordinator.rb +211 -0
  79. data/lib/phronomy/agent/recovery_support.rb +512 -0
  80. data/lib/phronomy/agent/ruby_llm_materializer.rb +22 -13
  81. data/lib/phronomy/agent/selection/candidate.rb +53 -0
  82. data/lib/phronomy/agent/selection/constraint.rb +49 -0
  83. data/lib/phronomy/agent/shared_state.rb +38 -1
  84. data/lib/phronomy/agent/tool_approval_request.rb +33 -5
  85. data/lib/phronomy/agent/tool_definition_set.rb +49 -3
  86. data/lib/phronomy/agent/tool_invocation.rb +336 -102
  87. data/lib/phronomy/agent/tool_invocation_session_builder.rb +49 -45
  88. data/lib/phronomy/agent.rb +20 -2
  89. data/lib/phronomy/agent_already_exists_error.rb +5 -0
  90. data/lib/phronomy/agent_purged_error.rb +5 -0
  91. data/lib/phronomy/engine/concurrency/offload_pool.rb +17 -3
  92. data/lib/phronomy/engine/concurrency/physical_completion_task.rb +135 -0
  93. data/lib/phronomy/engine/event_loop.rb +622 -63
  94. data/lib/phronomy/engine/fsm_session.rb +194 -21
  95. data/lib/phronomy/engine/runtime/agent_ownership_registry.rb +352 -0
  96. data/lib/phronomy/engine/runtime.rb +77 -20
  97. data/lib/phronomy/generator_verifier.rb +12 -14
  98. data/lib/phronomy/invocation_context.rb +9 -29
  99. data/lib/phronomy/multi_agent/admission_registry.rb +51 -0
  100. data/lib/phronomy/multi_agent/coordination_state.rb +18 -0
  101. data/lib/phronomy/multi_agent/coordinator.rb +154 -0
  102. data/lib/phronomy/multi_agent/execution_coordinator.rb +116 -0
  103. data/lib/phronomy/multi_agent/fan_out_invocation.rb +24 -33
  104. data/lib/phronomy/multi_agent/fan_out_session_builder.rb +12 -19
  105. data/lib/phronomy/multi_agent/handoff.rb +24 -45
  106. data/lib/phronomy/multi_agent/handoff_capability_factory.rb +87 -0
  107. data/lib/phronomy/multi_agent/handoff_context.rb +95 -0
  108. data/lib/phronomy/multi_agent/handoff_policy.rb +137 -0
  109. data/lib/phronomy/multi_agent/handoff_projection.rb +191 -0
  110. data/lib/phronomy/multi_agent/handoff_request.rb +45 -0
  111. data/lib/phronomy/multi_agent/orchestrator.rb +12 -15
  112. data/lib/phronomy/multi_agent/runner.rb +98 -0
  113. data/lib/phronomy/persistence/durable_codec.rb +646 -0
  114. data/lib/phronomy/persistence/durable_record.rb +117 -0
  115. data/lib/phronomy/persistence/in_memory.rb +210 -134
  116. data/lib/phronomy/persistence/migration/initial_format_migration.rb +226 -0
  117. data/lib/phronomy/persistence/repository_facades.rb +316 -0
  118. data/lib/phronomy/persistence.rb +81 -41
  119. data/lib/phronomy/recovery.rb +186 -0
  120. data/lib/phronomy/testing/persistence_contract/a_journal_repository.rb +2 -2
  121. data/lib/phronomy/testing/persistence_contract/a_persistence_backend.rb +1 -1
  122. data/lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb +19 -19
  123. data/lib/phronomy/testing/persistence_contract/an_agent_repository.rb +3 -3
  124. data/lib/phronomy/testing/persistence_contract/an_execution_repository.rb +5 -5
  125. data/lib/phronomy/tracing/automatic.rb +176 -0
  126. data/lib/phronomy/tracing/base.rb +11 -2
  127. data/lib/phronomy/tracing/langfuse_tracer.rb +20 -12
  128. data/lib/phronomy/version.rb +1 -1
  129. data/lib/phronomy/workflow.rb +3 -6
  130. data/lib/phronomy/workflow_context.rb +14 -5
  131. data/lib/phronomy/workflow_recovery.rb +123 -0
  132. data/lib/phronomy/workflow_runner.rb +468 -256
  133. data/lib/phronomy.rb +6 -0
  134. data/scripts/api_snapshot.rb +12 -0
  135. data/sig/phronomy/agent.rbs +209 -7
  136. data/sig/phronomy/multi_agent.rbs +39 -0
  137. data/sig/phronomy/persistence.rbs +62 -4
  138. data/sig/phronomy/runtime.rbs +1 -4
  139. data/sig/phronomy/workflow.rbs +2 -2
  140. data/sig/phronomy.rbs +10 -0
  141. metadata +65 -17
  142. data/examples/workflows/agent_event_mapping.rb +0 -101
  143. data/examples/workflows/generic_task_event_mapping.rb +0 -66
  144. data/lib/phronomy/agent/activation_registry.rb +0 -28
  145. data/lib/phronomy/agent/agent_execution_activation.rb +0 -172
  146. data/lib/phronomy/agent/context_candidate.rb +0 -47
  147. data/lib/phronomy/agent/context_parts/budget/token_budget_packer.rb +0 -53
  148. data/lib/phronomy/agent/context_parts/requirements/required_context_resolver.rb +0 -56
  149. data/lib/phronomy/agent/context_parts/selectors/recent_first_selector.rb +0 -30
  150. data/lib/phronomy/agent/context_parts/unit_builders/dependency_aware_unit_builder.rb +0 -118
  151. data/lib/phronomy/agent/context_policy_descriptor.rb +0 -49
  152. data/lib/phronomy/agent/context_policy_registry.rb +0 -46
  153. data/lib/phronomy/agent/context_request.rb +0 -35
  154. data/lib/phronomy/agent/context_selection_unit.rb +0 -38
  155. data/lib/phronomy/agent/derived_content_spec.rb +0 -34
  156. data/lib/phronomy/agent/runner.rb +0 -97
@@ -0,0 +1,488 @@
1
+ # ADR-018: Durability Guarantees and Failure Model Vocabulary
2
+
3
+ ## Status
4
+
5
+ Accepted.
6
+
7
+ ## Date
8
+
9
+ 2026-08-23
10
+
11
+ ## Context
12
+
13
+ Phronomy already has concrete durability, transaction, concurrency,
14
+ cancellation and fault-handling behavior, but terms such as "durable",
15
+ "recoverable", "safe", "conflict protection" and "exactly once" can describe
16
+ materially different guarantees.
17
+
18
+ That ambiguity is unsafe for later recovery and distributed-ownership work.
19
+ A durable record being readable after restart does not imply that a lost
20
+ execution can resume. Transaction atomicity does not imply that a caller can
21
+ always determine whether a commit occurred. Optimistic conflict detection
22
+ does not imply distributed exclusion. Neither durability nor exclusion
23
+ implies exactly-once execution of external side effects.
24
+
25
+ This ADR establishes the repository-wide guarantee vocabulary and failure
26
+ taxonomy used by architecture review, fault-injection review and downstream
27
+ Architecture Change Sets.
28
+
29
+ It is a normative **target architecture contract**. It does not claim that
30
+ every target guarantee below is already implemented. Known implementation
31
+ gaps remain explicit downstream reconciliation work.
32
+
33
+ ## Decision
34
+
35
+ ### 1. Guarantee statements name the subject, property and provider
36
+
37
+ Do not use a bare statement such as:
38
+
39
+ ```text
40
+ recoverable = yes
41
+ safe = yes
42
+ durable = yes
43
+ ```
44
+
45
+ A guarantee statement must make clear:
46
+
47
+ ```text
48
+ guarantee subject + guarantee property
49
+ provided / enforced by
50
+ guarantee provider / contract
51
+ ```
52
+
53
+ For example:
54
+
55
+ ```text
56
+ Agent logical state:
57
+ logical-state rehydration = YES
58
+ provided by supported Agent load/hydration + Persistence
59
+
60
+ In-flight external Tool execution:
61
+ execution resumption = CONDITIONAL
62
+ provided only when its recovery/integration contract supports safe
63
+ reconciliation or replay
64
+ ```
65
+
66
+ ### 2. Canonical guarantee vocabulary
67
+
68
+ The following ten terms are distinct guarantees.
69
+
70
+ #### G1 — durable state persistence
71
+
72
+ **Subject:** semantic state/records explicitly defined as durable Phronomy
73
+ state, such as AgentRoot, JournalRecord, AgentExecution, durable Workflow
74
+ checkpoints and content-addressed Content.
75
+
76
+ **Guarantee:** after a known-successful Persistence commit, the state is held
77
+ in durable storage independently of process-local Runtime object lifetime.
78
+
79
+ **Provider:** Phronomy Persistence contract plus a conforming backend.
80
+
81
+ Process-local objects such as FSMSession, Activation, AgentInvocation, Task
82
+ and EventLoop queue entries are not covered by this guarantee.
83
+
84
+ #### G2 — durable-state restart readability
85
+
86
+ **Subject:** state/records already durably committed.
87
+
88
+ **Guarantee:** after Phronomy Runtime/process restart, the state can be read
89
+ through the supported Persistence API.
90
+
91
+ **Provider:** Persistence contract plus backend.
92
+
93
+ Readability does not imply logical-state rehydration or execution resumption.
94
+
95
+ #### G3 — logical-state rehydration
96
+
97
+ **Subject:** state of a logical entity with durable identity.
98
+
99
+ **Guarantee:** supported Phronomy APIs can construct usable live/domain state
100
+ representing the same logical entity from confirmed durable state, without
101
+ requiring the old process-local Ruby/Runtime objects.
102
+
103
+ **Provider:** Phronomy load/hydration semantics plus Persistence.
104
+
105
+ Rehydration does not restore the pre-crash object graph and does not itself
106
+ imply execution resumption.
107
+
108
+ #### G4 — execution resumption
109
+
110
+ **Subject:** an unfinished logical execution/continuation.
111
+
112
+ **Guarantee:** supported recovery/resume semantics can continue the same
113
+ logical execution from durable recovery state without blindly re-executing
114
+ semantic work already known to have completed.
115
+
116
+ **Provider:** Phronomy Runtime/recovery/resume semantics together with the
117
+ relevant operation-specific recovery contracts.
118
+
119
+ A durable AgentExecution record is necessary recovery evidence but is not,
120
+ by itself, an execution-resumption guarantee.
121
+
122
+ #### G5 — durable-transition atomicity
123
+
124
+ **Subject:** one semantic durable transition whose durable mutations are
125
+ defined as one transaction boundary.
126
+
127
+ **Guarantee:** durable mutations in that transition commit all-or-nothing.
128
+
129
+ **Provider:** Persistence transaction contract plus backend.
130
+
131
+ Atomicity does not guarantee that the caller can always know a commit's
132
+ outcome after a transport/database failure.
133
+
134
+ #### G6 — same-process competing-execution exclusion
135
+
136
+ **Subject:** competing semantic executions for one logical entity that must
137
+ not be admitted concurrently.
138
+
139
+ **Guarantee:** one Phronomy Runtime/process does not concurrently admit the
140
+ prohibited competing executions.
141
+
142
+ **Provider:** Phronomy Runtime/admission semantics and, where applicable,
143
+ process-local/backend admission mechanics.
144
+
145
+ This does not exclude immutable reads or observation.
146
+
147
+ #### G7 — cross-process competing-execution exclusion
148
+
149
+ **Subject:** the same competing executions across multiple processes,
150
+ containers, replicas or Runtime instances.
151
+
152
+ **Guarantee:** prohibited competing executions are not simultaneously
153
+ admitted across those environments.
154
+
155
+ **Provider:** Phronomy plus stable routing/partitioning or a cross-process
156
+ coordination mechanism that establishes exclusive ownership.
157
+
158
+ A process-local registry, Mutex or optimistic CAS alone is not this guarantee.
159
+
160
+ #### G8 — stale durable-transition conflict detection
161
+
162
+ **Subject:** a durable write/transition based on a stale revision, Journal
163
+ position, watermark or equivalent durable base.
164
+
165
+ **Guarantee:** the stale transition is detected and rejected instead of
166
+ silently overwriting newer durable state.
167
+
168
+ **Provider:** Persistence optimistic revision/CAS/watermark contract plus the
169
+ Phronomy layer that uses it correctly.
170
+
171
+ Conflict detection is not competing-execution exclusion and cannot roll back
172
+ an already-performed external side effect.
173
+
174
+ #### G9 — duplicate external-side-effect prevention
175
+
176
+ **Subject:** one semantic side effect outside Phronomy's durable transaction
177
+ domain, such as an external API update, payment, email, external database
178
+ mutation or application callback effect.
179
+
180
+ **Guarantee:** under the defined failure/retry/recovery conditions, the same
181
+ semantic side effect does not become effective more than once.
182
+
183
+ **Provider:** Phronomy semantic identity/retry/recovery behavior together
184
+ with whatever external idempotency/deduplication protocol is required.
185
+
186
+ A semantic ID existing in Phronomy does not, by itself, provide this guarantee.
187
+
188
+ #### G10 — exactly-once external-side-effect execution
189
+
190
+ **Subject:** one semantic external side effect.
191
+
192
+ **Guarantee:** within the stated failure model the side effect becomes
193
+ effective exactly once: neither zero times nor more than once.
194
+
195
+ **Provider:** never assumed to be Phronomy alone. It requires sufficient
196
+ external-system protocol, idempotency and/or transaction coordination.
197
+
198
+ Duplicate prevention is weaker than exactly-once: a system can avoid
199
+ duplicates while still permitting zero executions after failure.
200
+
201
+ ### 3. Guarantee terms are not an implication hierarchy
202
+
203
+ These guarantees do not imply each other unless another architecture contract
204
+ says so.
205
+
206
+ In particular:
207
+
208
+ ```text
209
+ durable state persistence
210
+ != durable-state restart readability
211
+ != logical-state rehydration
212
+ != execution resumption
213
+
214
+ durable-transition atomicity
215
+ != commit outcome certainty
216
+
217
+ same-process competing-execution exclusion
218
+ != cross-process competing-execution exclusion
219
+
220
+ stale durable-transition conflict detection
221
+ != competing-execution exclusion
222
+
223
+ cross-process competing-execution exclusion
224
+ != duplicate external-side-effect prevention
225
+ != exactly-once external-side-effect execution
226
+ ```
227
+
228
+ `durable state`, `durable transition`, and `durable barrier` also remain
229
+ separate architecture concepts. A durable barrier is continuation ordering
230
+ around a confirmed durable outcome; it is not EventLoop-wide blocking and
231
+ does not create X0 external-effect atomicity.
232
+
233
+ ### 4. Canonical failure taxonomy
234
+
235
+ `F0` through `F4` are identifiers, not a severity scale, execution-stage
236
+ ordering, containment hierarchy or recovery-difficulty ranking. One scenario
237
+ may match more than one failure class.
238
+
239
+ #### F0 — Operation Failure
240
+
241
+ **Analysis subject:** one semantic/runtime operation.
242
+
243
+ The operation starts but does not reach its contract-defined normal
244
+ completion. Exceptions, explicit errors, rejection, cancellation and timeout
245
+ are possible concrete mechanisms.
246
+
247
+ F0 and F1 describe different dimensions and may apply to the same scenario.
248
+ F0 means the Phronomy operation did not reach contract-defined normal
249
+ completion. F1 may simultaneously apply when the underlying durable or
250
+ external outcome cannot be determined. Do not infer outcome certainty merely
251
+ from an F0 result.
252
+
253
+ #### F1 — Outcome Uncertainty
254
+
255
+ **Analysis subject:** Phronomy's knowledge about an operation, durable
256
+ transition or external effect outcome.
257
+
258
+ Phronomy cannot determine whether the operation succeeded, whether a durable
259
+ transition committed, or whether an external effect occurred.
260
+
261
+ Observing an error/connection loss does not prove that the remote operation
262
+ did not occur or that a commit did not happen.
263
+
264
+ F1 therefore requires reconciliation/recovery treatment rather than blind
265
+ inference from the failure response.
266
+
267
+ #### F2 — Concurrency Conflict
268
+
269
+ **Analysis subject:** multiple actors/operations competing over the same
270
+ logical entity, state or execution lifecycle.
271
+
272
+ The class identifies the conflict. It does not decide whether architecture
273
+ prevents admission, detects stale state after admission, or permits the
274
+ concurrency.
275
+
276
+ #### F3 — Asynchronous Lifecycle Mismatch
277
+
278
+ **Analysis subject:** an asynchronous completion and the lifecycle/owner that
279
+ could accept it.
280
+
281
+ The receiver's execution context, FSMSession, operation generation or
282
+ authority has ended, cancelled, resumed, changed or been replaced before the
283
+ completion arrives. Late completion, duplicate completion and an event
284
+ targeting an old session are examples.
285
+
286
+ #### F4 — Execution-Environment Loss
287
+
288
+ **Analysis subject:** process-local Runtime state supporting a logical
289
+ execution.
290
+
291
+ Runtime/process loss makes live objects such as Activation,
292
+ AgentInvocation, FSMSession, Task, EventLoop queue and Runtime-local admission
293
+ unavailable.
294
+
295
+ F4 does not imply that confirmed durable state was lost. It is the primary
296
+ reason recovery must not depend on old live Runtime objects.
297
+
298
+ #### X0 — External Effect Boundary
299
+
300
+ `X0` is **not a failure class**. It is a boundary label.
301
+
302
+ X0 identifies semantic effects outside Phronomy's durable transaction domain,
303
+ including Tool/provider/application/remote-system effects. Unless an explicit
304
+ protocol provides stronger coordination, such effects are not atomic with a
305
+ Phronomy Persistence transaction.
306
+
307
+ F0-F4 can occur on either side of X0. Combining X0 with F1, retry, recovery or
308
+ competing execution is where duplicate-prevention and exactly-once questions
309
+ become significant.
310
+
311
+ ### 5. Failure-model assumptions
312
+
313
+ Core guarantee analysis assumes:
314
+
315
+ - Persistence backends honor the Phronomy Persistence contract.
316
+ - Tool, LLMAdapter and application extension code honor their published
317
+ contracts.
318
+ - process-local Runtime state may be lost under F4.
319
+ - confirmed durable backend state survives according to the backend's own
320
+ durability guarantee.
321
+ - OS, database, network and external services may fail.
322
+ - X0 external side effects and Phronomy Persistence commits are not one atomic
323
+ transaction unless a specific protocol says otherwise.
324
+
325
+ Storage-media destruction, backup/restore policy, multi-region disaster
326
+ recovery and malicious/contract-violating extension code are outside the
327
+ general Phronomy core guarantee.
328
+
329
+ ### 6. Final guarantee matrix
330
+
331
+ The matrix uses:
332
+
333
+ ```text
334
+ YES baseline target guarantee
335
+ CONDITIONAL guarantee only when the stated additional condition holds
336
+ NO not a baseline guarantee
337
+ N/A not applicable to that subject
338
+ ```
339
+
340
+ A `CONDITIONAL` row is incomplete without its condition.
341
+
342
+ #### Durable state
343
+
344
+ | Subject | Durable persistence | Restart readability | Logical rehydration |
345
+ |---|---|---|---|
346
+ | Durable Agent state | **YES** | **YES** | **YES** |
347
+ | AgentExecution / Journal | **YES** | **YES** | **YES** — as logical continuation state/evidence |
348
+ | Durable Workflow checkpoint | **YES** | **YES** | **YES** |
349
+ | Ephemeral Workflow state | **NO** | **NO** | **NO** |
350
+ | Runtime objects (FSMSession, Activation, Task, etc.) | **NO** | **NO** | **N/A** — object itself is not rehydrated |
351
+
352
+ Logical rehydration reconstructs current logical/domain state from confirmed
353
+ durable state; it does not restore the old Ruby object graph.
354
+
355
+ #### Execution resumption
356
+
357
+ | Subject | Guarantee |
358
+ |---|---|
359
+ | Restart-safe HITL durable continuation | **YES** |
360
+ | Durable Workflow continuation | **CONDITIONAL** — dependency consistency and ownership requirements must hold |
361
+ | Process loss with no unresolved external semantic operation | **YES** |
362
+ | In-flight LLM Provider Call | **CONDITIONAL** — operation recovery classification/integration contract |
363
+ | In-flight Tool Execution | **CONDITIONAL** — operation recovery classification/integration contract |
364
+ | Outcome uncertain and not safely resolvable by Phronomy/integration contract | **CONDITIONAL** — Application resolution is required |
365
+ | Terminal Execution | **N/A** |
366
+
367
+ `logical-state rehydration = YES` never means unconditional automatic resume.
368
+ Ownership, durable dependency consistency and pending-operation recovery
369
+ classification govern safe continuation.
370
+
371
+ #### Durable transition and concurrency
372
+
373
+ | Guarantee | Agent | Workflow |
374
+ |---|---|---|
375
+ | Durable-transition atomicity | **YES** | **YES** — for a defined durable transition |
376
+ | Same-process competing-execution exclusion | **YES** | **YES** |
377
+ | Cross-process competing-execution exclusion | **CONDITIONAL** | **CONDITIONAL** |
378
+ | Stale durable-transition conflict detection | **YES** | **YES** |
379
+
380
+ Cross-process exclusion requires stable application routing/partitioning or a
381
+ cross-process coordinator that provides exclusive ownership. Persistence CAS
382
+ or revision checking alone is not enough.
383
+
384
+ #### Cancellation and Task invariants
385
+
386
+ | Subject | Guarantee |
387
+ |---|---|
388
+ | Prevent late result from updating live state after cancellation/authority loss | **YES** |
389
+ | Cancellation request physically terminates the worker/external operation | **NO** |
390
+ | Runtime supervises cancelling/cancelled work until quiescence or operation-specific safe detach | **YES** |
391
+ | Waiter-local timeout cancels the Execution | **NO** |
392
+ | Semantic deadline invalidates result authority | **YES** |
393
+ | Caller Task settlement coincides with the authoritative completion boundary | **YES** |
394
+ | Runtime Task object itself is recovered after restart | **NO** |
395
+
396
+ #### External side effects
397
+
398
+ | Guarantee | Baseline |
399
+ |---|---|
400
+ | Retry eligibility is based on operation-specific contract and outcome certainty | **YES** |
401
+ | Blind automatic retry when safety is not established | **NO** |
402
+ | Reconciliation capability is usable when the integration provides it | **YES** |
403
+ | Arbitrary external-effect duplicate prevention | **CONDITIONAL** — external idempotency/deduplication or equivalent contract is required |
404
+ | Arbitrary external-effect exactly-once execution | **NO** |
405
+
406
+ ### 7. Review and test usage
407
+
408
+ Architecture-sensitive failure/recovery/concurrency changes must state:
409
+
410
+ 1. the guarantee subject;
411
+ 2. the guarantee property from G1-G10;
412
+ 3. the provider/condition that makes the guarantee true;
413
+ 4. the applicable failure class(es) F0-F4;
414
+ 5. whether X0 is crossed;
415
+ 6. whether the claimed result is YES, CONDITIONAL or NO in the target matrix.
416
+
417
+ Fault-injection tests should identify the failure class/boundary they exercise.
418
+ A test that observes F0 must not be presented as F1 reconciliation coverage.
419
+ A graceful Runtime shutdown test is not automatically F4 recovery coverage.
420
+ A Tool failure test crossing X0 does not prove duplicate prevention or
421
+ exactly-once behavior.
422
+
423
+ The taxonomy is architecture/test vocabulary. This ADR does **not** add a
424
+ public `FailureClass` enum, public guarantee-level enum or one-error-class-per-
425
+ failure-category hierarchy. Observable public errors are designed only where
426
+ a concrete API contract requires them.
427
+
428
+ ### 8. Relationship to current implementation and downstream ACS work
429
+
430
+ This ADR intentionally separates vocabulary from implementation mechanics.
431
+
432
+ Known downstream responsibility includes:
433
+
434
+ - ACS-14: cross-process ownership/fencing and G7 conditions.
435
+ - ACS-15: F1/F4 durable recovery, reconciliation and execution resumption.
436
+ - ACS-16: cancellation supervision and caller-facing Task settlement.
437
+ - ACS-17: X0 semantic retry, outcome certainty, causal durable barriers and
438
+ duplicate/side-effect guarantees.
439
+ - ACS-02: final explanatory architecture guarantee matrix/document placement.
440
+
441
+ Existing ADRs remain authoritative for their current scopes:
442
+
443
+ - ADR-010: EventLoop/FSMSession/Task/Offload concurrency boundary.
444
+ - `011-delegate-transport-policy-to-adapters`: transport retry ownership.
445
+ - ADR-012: canonical Journal/Manifest authority.
446
+ - ADR-014: unified durable Persistence intent until coherent successor
447
+ decisions replace stale portions.
448
+ - ADR-017: repository Design Authority/governance.
449
+
450
+ This ADR does not silently declare known implementation gaps resolved. Later
451
+ ACS changes use this vocabulary to state exactly which target guarantee they
452
+ implement.
453
+
454
+ ## Consequences
455
+
456
+ ### Positive
457
+
458
+ - "durable", "recoverable" and "safe" can no longer hide different guarantees.
459
+ - F0 known failure and F1 outcome uncertainty are reviewably distinct.
460
+ - cross-process exclusion cannot be mistaken for optimistic conflict
461
+ detection.
462
+ - external duplicate prevention cannot be inferred from a semantic ID alone.
463
+ - exactly-once external effects remain explicitly outside the unconditional
464
+ Phronomy baseline.
465
+ - recovery/fencing/cancellation/retry work shares one acceptance vocabulary.
466
+
467
+ ### Trade-offs
468
+
469
+ - architecture-sensitive PRs must state guarantees and failure conditions more
470
+ precisely.
471
+ - the normative matrix can temporarily describe target behavior that current
472
+ source has not yet reconciled; those gaps must remain explicit.
473
+ - deployment-specific details are not encoded in this ADR. The ADR fixes the
474
+ semantic conditions; deployment documentation explains how a particular
475
+ deployment satisfies them.
476
+
477
+ ## Non-goals
478
+
479
+ This ADR does not:
480
+
481
+ - introduce public failure/guarantee enums;
482
+ - add new Runtime/Persistence error classes merely to mirror F0-F4;
483
+ - implement cross-process coordination;
484
+ - implement restart recovery/reconciliation;
485
+ - redesign cancellation/Task settlement;
486
+ - introduce semantic external-operation retry;
487
+ - claim arbitrary external exactly-once execution;
488
+ - perform the final ACS-02 architecture-document migration.