phronomy 0.29.0 → 0.30.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +107 -1
  3. data/README.md +17 -6
  4. data/docs/architecture/agent-configuration-and-tool-binding.md +8 -0
  5. data/docs/architecture/agent-iteration-budget.md +81 -0
  6. data/docs/architecture/dx05-agent-scope.md +9 -2
  7. data/docs/architecture/error-api-review.md +4 -4
  8. data/docs/architecture/generator-verifier-lifecycle-result.md +126 -0
  9. data/docs/architecture/generator-verifier-ownership.md +18 -109
  10. data/docs/architecture/llm-continuation-metadata.md +88 -0
  11. data/docs/architecture/lm-studio-output-failures.md +111 -0
  12. data/docs/architecture/r8-unit1.md +68 -68
  13. data/docs/architecture/r8-unit15.md +3 -0
  14. data/docs/architecture/r8-unit2.md +34 -34
  15. data/docs/architecture/r8-unit7.md +2 -1
  16. data/docs/architecture/structured-output-and-scope.md +183 -0
  17. data/docs/architecture/tracing.md +22 -4
  18. data/docs/architecture/transport-error-boundaries.md +103 -0
  19. data/docs/architecture/trust-acceptance-followup.md +87 -0
  20. data/docs/decisions/029-semantic-completion-and-application-effect-boundary.md +1 -1
  21. data/docs/design/durable-semantic-coordination/CHANGELOG_V2_REVISION_2.md +23 -23
  22. data/docs/design/durable-semantic-coordination/IMPLEMENTATION_REPORT.md +99 -99
  23. data/docs/design/durable-semantic-coordination/RECOVERY_CONTRACT_CLARIFICATIONS.md +135 -136
  24. data/docs/features.md +10 -1
  25. data/docs/migrations/r8-unit15.md +3 -0
  26. data/gemfiles/http_minimum.gemfile +6 -1
  27. data/lib/phronomy/agent/admission.rb +1 -1
  28. data/lib/phronomy/agent/async_event_api.rb +16 -7
  29. data/lib/phronomy/agent/base.rb +8 -1
  30. data/lib/phronomy/agent/context_importer.rb +4 -0
  31. data/lib/phronomy/agent/execution/agent_invocation.rb +6 -2
  32. data/lib/phronomy/agent/execution/dispatch_preparation.rb +6 -1
  33. data/lib/phronomy/agent/execution/exact_execution.rb +9 -0
  34. data/lib/phronomy/agent/execution/execution_cancellation.rb +1 -1
  35. data/lib/phronomy/agent/execution/execution_coordinator.rb +63 -5
  36. data/lib/phronomy/agent/execution/execution_outcome_committer.rb +24 -4
  37. data/lib/phronomy/agent/execution/execution_registry.rb +5 -1
  38. data/lib/phronomy/agent/execution/initial_preparation.rb +10 -1
  39. data/lib/phronomy/agent/execution/invocation_actions.rb +1 -1
  40. data/lib/phronomy/agent/execution/invocation_transitions.rb +4 -4
  41. data/lib/phronomy/agent/execution/iteration_budget.rb +35 -0
  42. data/lib/phronomy/agent/execution/runtime_record_encoder.rb +3 -0
  43. data/lib/phronomy/agent/execution_observation.rb +5 -5
  44. data/lib/phronomy/agent/lifecycle/scope.rb +33 -23
  45. data/lib/phronomy/agent/lifecycle/scope_cleanup_error.rb +4 -2
  46. data/lib/phronomy/agent/output_contract.rb +64 -0
  47. data/lib/phronomy/agent/output_error.rb +53 -0
  48. data/lib/phronomy/agent/recovery/recovery_coordinator/continuation.rb +3 -3
  49. data/lib/phronomy/agent/recovery/recovery_coordinator/installation.rb +1 -0
  50. data/lib/phronomy/agent/recovery/recovery_coordinator.rb +1 -1
  51. data/lib/phronomy/agent/recovery/recovery_support.rb +5 -1
  52. data/lib/phronomy/agent/runtime_binding/engine_session_builder.rb +2 -1
  53. data/lib/phronomy/agent/runtime_input.rb +15 -4
  54. data/lib/phronomy/agent/saved_context_reader.rb +2 -1
  55. data/lib/phronomy/agent/store.rb +10 -2
  56. data/lib/phronomy/common/values/immutable.rb +33 -0
  57. data/lib/phronomy/context/assembly.rb +7 -4
  58. data/lib/phronomy/embeddings/backends/ruby_llm_embeddings.rb +3 -1
  59. data/lib/phronomy/engine/fsm_session.rb +16 -1
  60. data/lib/phronomy/generation/generator_verifier/agent_operation.rb +28 -5
  61. data/lib/phronomy/generation/generator_verifier/agent_result_receiver.rb +14 -27
  62. data/lib/phronomy/generation/generator_verifier/approval.rb +30 -0
  63. data/lib/phronomy/generation/generator_verifier/cleanup_error.rb +15 -0
  64. data/lib/phronomy/generation/generator_verifier/invocation.rb +147 -0
  65. data/lib/phronomy/generation/generator_verifier/pipeline_state.rb +16 -0
  66. data/lib/phronomy/generation/generator_verifier/protocol.rb +55 -0
  67. data/lib/phronomy/generation/generator_verifier/result.rb +121 -0
  68. data/lib/phronomy/generation/generator_verifier/unaccepted_result_error.rb +14 -0
  69. data/lib/phronomy/generation/generator_verifier/workflow_builder.rb +13 -11
  70. data/lib/phronomy/generation/generator_verifier.rb +170 -85
  71. data/lib/phronomy/llm_adapter/backends/lm_studio.rb +139 -0
  72. data/lib/phronomy/llm_adapter/backends/ruby_llm.rb +134 -12
  73. data/lib/phronomy/llm_adapter/backends/structured_response_capture.rb +41 -0
  74. data/lib/phronomy/llm_adapter/message.rb +4 -0
  75. data/lib/phronomy/llm_adapter/request.rb +17 -2
  76. data/lib/phronomy/llm_adapter/response.rb +11 -4
  77. data/lib/phronomy/llm_adapter/structured_output_unsupported_error.rb +14 -0
  78. data/lib/phronomy/llm_adapter/transport_error.rb +4 -0
  79. data/lib/phronomy/multi_agent/shared_state.rb +1 -0
  80. data/lib/phronomy/output_parser/json_schema_parser.rb +113 -0
  81. data/lib/phronomy/output_parser/parse_error.rb +10 -1
  82. data/lib/phronomy/runtime_composition/agent_defaults.rb +4 -0
  83. data/lib/phronomy/tracing/automatic.rb +14 -8
  84. data/lib/phronomy/tracing/base.rb +2 -1
  85. data/lib/phronomy/tracing/langfuse_tracer.rb +3 -3
  86. data/lib/phronomy/tracing/observation.rb +2 -1
  87. data/lib/phronomy/tracing/open_telemetry_tracer.rb +3 -3
  88. data/lib/phronomy/version.rb +1 -1
  89. data/lib/phronomy.rb +1 -2
  90. data/scripts/api_snapshot.rb +3 -0
  91. data/scripts/migrate_generator_verifier_result.rb +18 -0
  92. data/sig/phronomy/agent/execution_contract.rbs +4 -3
  93. data/sig/phronomy/agent.rbs +20 -7
  94. data/sig/phronomy/extensions.rbs +8 -3
  95. data/sig/phronomy/generation/generator_verifier.rbs +70 -0
  96. data/sig/phronomy/llm_adapter/backends/lm_studio.rbs +8 -0
  97. data/sig/phronomy/llm_adapter/backends/ruby_llm.rbs +1 -0
  98. data/sig/phronomy/llm_adapter/values.rbs +8 -2
  99. data/sig/phronomy/tracing/observation.rbs +1 -1
  100. data/sig/phronomy.rbs +2 -0
  101. metadata +59 -8
  102. data/lib/phronomy/generation/generator_verifier/default_parser.rb +0 -27
  103. data/lib/phronomy/generation/low_confidence_error.rb +0 -14
  104. data/lib/phronomy/runtime_composition/generation_defaults.rb +0 -6
  105. data/sig/phronomy/generation/low_confidence_error.rbs +0 -6
@@ -0,0 +1,88 @@
1
+ # LLM continuation metadata preservation
2
+
3
+ This correction follows [ADR-066](../decisions/066-llm-and-tool-operation-contracts.md).
4
+ It does not change the LLM/Tool/Agent ownership decision, add a dependency to the
5
+ contract, or teach Agent a provider wire format.
6
+
7
+ ## Problem and contract
8
+
9
+ The RubyLLM backend converted SDK responses into Phronomy Response values without
10
+ their reasoning data. A later model turn therefore lost information RubyLLM could
11
+ otherwise replay. Saved assistant records already contained Message metadata, but
12
+ RuntimeInput reconstructed only model_id. Explicit Message imports dropped the
13
+ metadata too. These were separate losses along the same conversation path.
14
+
15
+ C09 Message/Response metadata remains immutable canonical JSON. Backend-owned
16
+ continuation data accompanies its assistant message through a Tool round, Journal
17
+ serialization, recovery and explicit Phronomy-message import. Agent preserves the
18
+ value without inspecting its backend keys. Metadata does not authorize a Tool,
19
+ change context selection, become answer content or become arbitrary SDK options.
20
+ Record/control metadata remains distinct from metadata inside an assistant payload.
21
+
22
+ The concrete RubyLLM backend owns the ruby_llm_continuation namespace, format
23
+ version 1, and conversion of SDK thinking text/signature and raw_reasoning. It
24
+ reconstructs those SDK options only inside the backend. RubyLLM still owns wire
25
+ format rendering; no SDK class or provider registry is patched for this fix.
26
+ No thinking toggle, extra model call, fallback, retry, sampling change or Tool
27
+ execution is introduced. Existing Tool thought_signature behavior is unchanged.
28
+
29
+ Streaming's final Response retains the same continuation data. Public content
30
+ chunks remain answer chunks; this change adds no reasoning-display event API.
31
+ SDK token usage semantics are unchanged.
32
+
33
+ ## Replay compatibility
34
+
35
+ The backend records the requested model ID, provider, selected protocol name and
36
+ a SHA-256 of the API base. The endpoint itself and credentials are not stored in
37
+ the envelope. Reuse requires an exact match of this scope and format version.
38
+ An incompatible scope/version raises ConfigurationError before sending the next
39
+ model request. State is neither silently discarded nor sent to a different target.
40
+ Malformed envelopes fail explicitly. Legacy messages without the envelope remain
41
+ usable; missing historical reasoning cannot be reconstructed.
42
+
43
+ This conservative equality check is not a claim that all identical endpoints are
44
+ semantically unchanged, or that different models can never share reasoning. It
45
+ does not detect server runtime/template changes behind one URL, account changes,
46
+ or model replacements behind one model ID. Cross-model/provider reasoning
47
+ conversion is outside this correction.
48
+
49
+ Handoff continues to use its existing context selection policy. If a selected
50
+ assistant message carries this state, a same-scope target can replay it and a
51
+ different-scope RubyLLM target rejects it. Applications requiring transfer across
52
+ incompatible scopes must intentionally select/derive portable context using the
53
+ existing context policy; they must not forge the scope or treat metadata as
54
+ authority. Other backend implementations own their own metadata conventions.
55
+
56
+ ## Persistence and compatibility
57
+
58
+ There is no DB schema change, new SDK object in storage, or changed public method
59
+ signature. RuntimeInput restores the canonical metadata Hash and uses historical
60
+ top-level model_id only when metadata does not already contain it. Canonical
61
+ metadata is authoritative if both representations exist. Missing metadata means
62
+ an empty Hash; malformed non-Hash metadata is rejected.
63
+
64
+ ContextImporter preserves explicitly supplied canonical Message metadata. It does
65
+ not inspect an externally supplied RubyLLM object's thinking field; converting
66
+ SDK-specific external histories remains a backend-boundary concern, not a new
67
+ Agent SDK dependency. Signed/provider-shaped values stay unmodified and subject
68
+ to the SDK 2.0.0 representation supported by the existing dependency constraint.
69
+ This is not general preservation of every SDK field (for example server-tool
70
+ raw_content), nor a promise of compatibility with untested providers.
71
+
72
+ ## Evidence and acceptance
73
+
74
+ The compatibility regressions are:
75
+
76
+ - spec/phronomy/llm_adapter/continuation_metadata_spec.rb: actual SDK parsing and
77
+ rendered HTTP for text/signature, streaming, Responses encrypted state and
78
+ provider-shaped OpenRouter reasoning; scope/version rejection and legacy input.
79
+ - spec/phronomy/agent/continuation_metadata_spec.rb: real Agent Tool loops,
80
+ subsequent invocation, approval across reconstructed storage/Runtime, Handoff,
81
+ and an independent backend with opaque metadata and no RubyLLM calls.
82
+ - spec/phronomy/agent/ruby_llm_materializer_spec.rb: historical model_id reading.
83
+
84
+ The LM Studio gpt-oss-20b reasoning omission was independently reproduced before
85
+ this change. The prior isolated A/B diagnostic returned HTTP 200 in all four
86
+ trials. This correction therefore does not claim to explain or fix peg-native
87
+ HTTP 400, nor to complete Example 22. Actual model behavior and the entire
88
+ application acceptance remain separate verification stages.
@@ -0,0 +1,111 @@
1
+ # LM Studio provider output failures
2
+
3
+ ## Scope and ownership
4
+
5
+ `Phronomy::LLMAdapter::LMStudio` is an explicitly selected concrete RubyLLM
6
+ backend. It handles rejection of the provider's generated conversation format.
7
+ It does not parse or repair partial model output, change prompts or sampling
8
+ parameters, split Tool/schema requests, or replay Agent/Workflow/Tool work.
9
+ The default `RubyLLM` backend and SDK global configuration remain unchanged.
10
+
11
+ C09 owns the meaning of the public `TransportError` reason code
12
+ `llm.provider_output_parse_failed`. A code does not itself authorize retry.
13
+ The concrete backend owns HTTP-body decoding and its transport policy under
14
+ ADR-011/066. Application composition selects that backend and its retry limit.
15
+ No new Contract or Contract dependency is required.
16
+
17
+ ## Recognition and evidence limits
18
+
19
+ Recognition requires a RubyLLM BadRequestError/ServerError with its own HTTP
20
+ response and actual HTTP status 400 or 500. The JSON body must contain `error`
21
+ with the exact engine code 500, type `server_error`, and message:
22
+
23
+ The model produced output that does not match the expected peg-native format
24
+
25
+ The engine object may be direct, or JSON after the exact LM Studio prefix
26
+ `Engine protocol predict stream returned an error: `, carried in an error string
27
+ or the error object's message field. No search through arbitrary strings or
28
+ nested exception causes is performed. A malformed/unknown envelope, missing
29
+ response or different status/type/code/message remains an ordinary SDK failure.
30
+ The original SDK exception remains `cause`; the original HTTP status and body
31
+ are not rewritten. The engine's internal 500 is not treated as HTTP 500.
32
+
33
+ The offline HTTP fixture envelopes are synthetic. Follow-up real LM Studio
34
+ acceptance on 2026-10-24 captured the actual HTTP 400 error body and confirmed
35
+ classification as `llm.provider_output_parse_failed`. The eligible request was
36
+ resent once with identical bytes. After the retry also failed, the adapter
37
+ returned the final TransportError at its own limit; the measurement guard did
38
+ not trigger, and Agent/Workflow work was not replayed. A separate application
39
+ invocation completed initially with HTTP 200. Total: two application invocations
40
+ and three generation POSTs; this is not recovery within the failed invocation.
41
+
42
+ Live error identification and bounded retry are verified. Recovery by retry,
43
+ recovery rate, the PEG root cause and recurrence resolution remain unverified.
44
+ The unrecognized-envelope branch was not observed live. The failing host logs
45
+ contain parser suffixes but do not establish the complete pre-parser token
46
+ stream. Unknown formats fail closed without retry.
47
+
48
+ ## Retry policy and configuration
49
+
50
+ ```ruby
51
+ context = RubyLLM.context do |config|
52
+ config.openai_api_base = "http://127.0.0.1:1234/v1"
53
+ config.openai_api_key = "lm-studio"
54
+ config.openai_protocol = :chat_completions
55
+ config.request_timeout = 120
56
+ end
57
+
58
+ Phronomy.configure do |config|
59
+ config.llm_adapter = Phronomy::LLMAdapter::LMStudio.new(
60
+ context: context,
61
+ max_parse_retries: 1 # default 0; only 0 or 1 is accepted
62
+ )
63
+ end
64
+ ```
65
+
66
+ The selected backend snapshots the RubyLLM 2.0 context and disables SDK retries
67
+ within that snapshot. **Ordinary 429/500/network retries are also disabled for
68
+ this backend.** Applications needing the existing SDK transport policy should
69
+ keep the default RubyLLM backend; this selection is deliberately explicit.
70
+ The caller's context and global settings are not modified. The frozen snapshot
71
+ prevents later scalar context changes from increasing the retry budget.
72
+
73
+ Only a recognized parse failure can trigger the optional second attempt. It is
74
+ limited to non-streaming `complete`, provider `openai`, model
75
+ `openai/gpt-oss-20b`, no advertised Tools, no response schema, and no Tool messages
76
+ or pending Tool calls in the supplied history. The same immutable request is
77
+ used to construct a fresh operation-local SDK chat. Total generation POSTs are
78
+ at most two. The one-additional-attempt limit is a conservative policy choice,
79
+ not an empirically established optimum or a reliability guarantee.
80
+
81
+ Streaming is never replayed. Delivered chunks and application callback exception
82
+ identity are preserved. Cancellation is checked before another attempt; existing
83
+ worker lifetime and deadline behavior remain unchanged. A final failure exposes
84
+ the final SDK exception as cause. No successful result is synthesized from an
85
+ error body.
86
+
87
+ ## Observation
88
+
89
+ The existing logical `llm.call` span covers the complete adapter operation.
90
+ There is no new trace identity or dependency from C09 to C15. Individual SDK HTTP
91
+ requests continue to use RubyLLM's instrumentation. Every failed adapter attempt
92
+ also emits a safe warning containing attempt number, reason code, actual HTTP
93
+ status when known, and whether a retry was selected; no prompt, raw body or
94
+ credential is included. Therefore a later success does not erase the first
95
+ failure from the diagnostic record.
96
+
97
+ An optional concrete-backend `on_attempt:` callable receives these safe fields
98
+ plus `outcome`. It must support concurrent calls if an adapter is shared and is
99
+ not a durable audit store. Logging/callback failures cannot replace the business
100
+ result or original exception. Applications can use SDK instrumentation when they
101
+ need request correlation or detailed HTTP evidence. Successful response events
102
+ do not invent an HTTP status that the public response does not expose.
103
+
104
+ ## Verification
105
+
106
+ Offline contracts use a real loopback TCP HTTP server and the actual
107
+ RubyLLM/Faraday stack. They verify status/cause fidelity, default no retry, exactly
108
+ two POSTs for opt-in recovery/exhaustion, unchanged request JSON, excluded
109
+ requests, cancellation between attempts, callback identity, unknown responses,
110
+ configuration isolation and unchanged default-backend SDK retries. They do not
111
+ invoke a live model.
@@ -1,4 +1,4 @@
1
- # r8第1適用版:Context/ToolとExecutionの共通基盤
1
+ # r8 unit 1: Shared Context, Tool, and Execution foundations
2
2
 
3
3
  > Current boundary: r8 unit 6 supersedes the historical Chat/SDK ownership and
4
4
  > adapter extension SPI below. Agent uses LLMAdapter values; the backend owns SDK
@@ -6,99 +6,99 @@
6
6
  > `docs/architecture/r8-unit6.md` and `docs/migrations/r8-unit6.md`.
7
7
 
8
8
 
9
- 対象は2026-09-30に確認したmain `653e255a34fe4062d4beca47530e084fdd3a6ba9`。設計基準は同日更新のr8修正仕様・directory配置資料である。本変更はその第1適用単位であり、r8全体、S1全項目、S2/S3全受入条件の完了を意味しない。互換alias・転送だけの旧APIは残さない。
9
+ The baseline is main `653e255a34fe4062d4beca47530e084fdd3a6ba9`, checked on 2026-09-30. The design references are the revised r8 specification and directory layout documents updated that day. This change is the first implementation unit; it does not mean that all of r8, every S1 item, or every S2/S3 acceptance condition is complete. Compatibility aliases and old APIs that only forward calls are not retained.
10
10
 
11
- ## 実装した責務と操作
11
+ ## Implemented responsibilities and operations
12
12
 
13
- | 所有者 | 共通基盤が実行すること | 利用側に残すこと |
13
+ | Owner | What the shared foundation does | What remains with the caller |
14
14
  |---|---|---|
15
- | `Context::Assembly` | Policyを一度呼びPlanを検証する。内容を正規化し、最終予算を検査してManifestを保存する | Agentはsnapshotを取得し、保存直前のwatermark再確認とAgent実行記録更新を行う |
16
- | `Tool::DefinitionSet` | Tool定義の正規化、名前重複と保存済み定義の整合性を検証する | Agentは自身のTool alias・decorator・runtime実体を準備する |
17
- | `Tool::Authorization` | 不変の引数・認可contextでfacts→requirement→policy→decisionを評価する | Agentは対象実行の照合、承認状態、受付結果、supervisionを管理する |
18
- | `Tool::ToolExecutor` | cooperative/offloadedの実行規則と結果を扱う | Engineのpool選択はExecutionの機構接続へ委ねる |
19
- | `LLMAdapter::Base` / `RubyLLM` | 同期生成とchat構築・設定・message/tool-call構築。RubyLLM実装がSDK失敗を変換する | Agentは自身の保存データ・Tool定義を検証してadapterへ渡す |
20
- | `Execution` | submitの入口、fan-out/fan-in、結果合成、取消・期限・待機規則 | Engineはpool・timer・RuntimeとFSMの機構を実装する |
21
- | `Tracing::Observation` | 明示的な観測とPII秘匿。実際の返り値は変えない | Runnableはinvoke/stream/batchの実行契約を持つ |
15
+ | `Context::Assembly` | Calls the Policy once and validates the Plan; normalizes content, checks the final budget, and stores the Manifest | Agent obtains the snapshot, rechecks the watermark immediately before persistence, and updates the Agent execution record |
16
+ | `Tool::DefinitionSet` | Normalizes Tool definitions and validates name uniqueness and consistency with persisted definitions | Agent prepares its own Tool aliases, decorators, and runtime instances |
17
+ | `Tool::Authorization` | Evaluates facts -> requirement -> policy -> decision using immutable arguments and authorization context | Agent manages execution matching, approval state, admission results, and supervision |
18
+ | `Tool::ToolExecutor` | Handles cooperative/offloaded execution rules and results | Pool selection in Engine is delegated to the Execution mechanism binding |
19
+ | `LLMAdapter::Base` / `RubyLLM` | Handles synchronous generation and chat construction/configuration, message construction, and tool-call construction; the RubyLLM implementation translates SDK failures | Agent validates its persisted data and Tool definitions before passing them to the adapter |
20
+ | `Execution` | Owns the submit entry point, fan-out/fan-in, result composition, and cancellation/deadline/waiting rules | Engine implements pools, timers, Runtime, and FSM mechanisms |
21
+ | `Tracing::Observation` | Provides explicit observation and PII redaction without changing the actual return value | Runnable owns the invoke/stream/batch execution contract |
22
22
 
23
- ContextとToolはAgentの薄い型定義の置場ではなく、実際の共通手順を所有する。ただし、Contextの現在の入力にはAgent由来の識別情報や由来情報が残る。完全に汎用の新domainモデルまで設計し直したものではない。ToolのDSL基底は引き続きRubyLLM::Toolを使用する。
23
+ Context and Tool own real shared procedures, rather than merely housing thin Agent type definitions. However, current Context inputs still contain Agent-derived identifiers and provenance. This is not a redesign into a fully generic domain model. The Tool DSL base continues to use RubyLLM::Tool.
24
24
 
25
- `Context::Assembly#prepare(input:, policy:, adapter_identity:)` は保存transaction外でPolicyを呼ぶ。`#store(prepared, contents:)` は呼出側が渡す同じtransactionのcontents repositoryだけを使い、自分では独立transactionを開始しない。初回とfollow-upのAgent commitは既存transaction内でManifestとAgentExecutionの参照を保存する。後続書込に失敗したときManifestもrollbackされ、Policyは再実行されない。live projectionをcommit後に適用する既存順序を維持する。これはP02のAgent/Context部分の検証であり、任意domainの外側transaction参加を完成させたものではない。
25
+ `Context::Assembly#prepare(input:, policy:, adapter_identity:)` calls the Policy outside the persistence transaction. `#store(prepared, contents:)` uses only the contents repository supplied by the caller from the same transaction; it does not start an independent transaction. Initial and follow-up Agent commits store the Manifest and the AgentExecution reference within the existing transaction. If a later write fails, the Manifest is rolled back too, and the Policy is not executed again. The existing ordering, which applies the live projection after commit, is preserved. This validates the Agent/Context part of P02; it does not complete participation in outer transactions for arbitrary domains.
26
26
 
27
- Executionは`_ExecutionBackend`の操作に依存する。構成処理が遅延providerを設定し、Engineの`ExecutionBinding`がsubmit/afterを実装する。settled TaskResultの生成・map/flat_map/all_settled・待機制約の確認ではEngineを読み込まない。Runtime取得は実際のsubmit/タイマー登録時に行う。単なる名義移管に留めず、機構参照をここへ集約した。
27
+ Execution depends on the operations of `_ExecutionBackend`. Composition configures a deferred provider, and Engine's `ExecutionBinding` implements submit/after. Creating settled TaskResults, using map/flat_map/all_settled, and checking waiting constraints do not load Engine. Runtime is obtained only when work is actually submitted or a timer is registered. Mechanism references are consolidated here, rather than merely being renamed or nominally reassigned.
28
28
 
29
- WorkflowのFINISHと終了値は`Workflow::Completion`が所有し、WorkflowRunnerがFSM側へ変換する。FSMSession専用のEvent/FSMProtocol/TerminalDecisionはEngineに置く。Agent・MultiAgentのFSM専用接続の全面分離は残っている。
29
+ `Workflow::Completion` owns Workflow FINISH and completion values, and WorkflowRunner translates them into the FSM representation. Event/FSMProtocol/TerminalDecision, which are specific to FSMSession, live in Engine. Full separation of Agent and MultiAgent FSM-specific bindings remains outstanding.
30
30
 
31
- ## 公開名・配置の変更
31
+ ## Public names and layout changes
32
32
 
33
- | 旧配置・API | 新配置・API | 判断 |
33
+ | Previous location/API | New location/API | Rationale |
34
34
  |---|---|---|
35
- | `agent/context_contract/` と `Agent::ContextPolicy` 等 | `context/`、`Context::ContextPolicy` 等 | Policy・Plan・Manifest・検証を共通操作と同じ所有者へ統合 |
36
- | `agent/context_policies/default.rb` | `context/default_policy.rb`、`Context::DefaultPolicy` | 具体Policyも同domainに配置 |
37
- | `Agent::Context::Instruction::PromptTemplate` | `Context::PromptTemplate` | Agent内の旧公開名を削除 |
38
- | `Agent::Selection::{Candidate,Constraint}` | `Context::{Candidate,Constraint}` | 薄いSelection下位区分を削除 |
39
- | `Agent::LLMInputPatch` / `LLMInputBuildContext` | `Context::LLMInputPatch` / `LLMInputBuildContext` | hook入力・返却値の所有を統一 |
40
- | `ContextBudgetExceededError` | `Context::BudgetExceededError` | LLMのprovider失敗ではなくContext予算失敗 |
41
- | `agent/context_assembly/` | `context/assembly.rb` とAgent直下の準備・状態・入力処理 | Context共通手順、Agent snapshot/state、LLM SDK処理を分離 |
42
- | `Agent::Context::Capability::Base` | 実装本体の `Tool::Base` | 旧名とaliasを削除 |
43
- | `agent/tool_execution/tool_definition_set.rb` | `tool/definition_set.rb` | 共通定義処理を移管。Agent固有生成はAgent内 |
44
- | `execution_contract/` と `execution_services/` | `execution/` と必要な `execution/concurrency/` | 操作・値・共通規則を統合。`execution_result`等の薄い別分割を追加しない |
45
- | `WorkerSubmission` | `Execution.submit` | 転送専用moduleを削除 |
46
- | `Runnable#trace` | `Tracing::Observation.trace` | 実行基盤から観測への依存を除去 |
47
- | `tool/contract`、`filter/contract`、`output_parser/contract`、`agent/lifecycle_contract` | 各所有domain配下の例外ファイル | 例外だけのdirectoryを削除。既存の意味を持つ例外定数名は実体として保持 |
48
-
49
- 独自LLM adapterはcomplete/streamだけでなく、`build_chat`、`configure_chat`、`message`、`tool_call`を実装する。`identity`には基底の既定値、`input_budget`にはnilの既定値がある。正確なkeywordと返却契約は`sig/phronomy/llm_adapter/base.rbs`を参照する。SDK固有例外はadapter操作の境界でLLM失敗へ変換し、元のcauseを保持する。アプリ例外・取消は無関係なprovider失敗へ変換しない。
50
-
51
- 既存設定APIの`tool_result_max_size`/loggerはアプリ構成から中立RuntimeSettingsへ供給する。Toolから構成factoryへの参照を除き、default・nil・scoped copyの意味を維持する。RBSは`sig/`と`sig/_private/`に置き、実装定数・宣言所有者に基づいて依存を解析する。
52
-
53
- ## r8項目別の到達点
54
-
55
- | 項目 | この適用版 | 未完了部分 |
35
+ | `agent/context_contract/` and APIs such as `Agent::ContextPolicy` | `context/` and APIs such as `Context::ContextPolicy` | Consolidate Policy, Plan, Manifest, and validation under the owner of the shared operations |
36
+ | `agent/context_policies/default.rb` | `context/default_policy.rb`, `Context::DefaultPolicy` | Keep the concrete Policy in the same domain |
37
+ | `Agent::Context::Instruction::PromptTemplate` | `Context::PromptTemplate` | Remove the old public name under Agent |
38
+ | `Agent::Selection::{Candidate,Constraint}` | `Context::{Candidate,Constraint}` | Remove the thin Selection subdivision |
39
+ | `Agent::LLMInputPatch` / `LLMInputBuildContext` | `Context::LLMInputPatch` / `LLMInputBuildContext` | Unify ownership of hook inputs and return values |
40
+ | `ContextBudgetExceededError` | `Context::BudgetExceededError` | Represent a Context budget failure, not an LLM provider failure |
41
+ | `agent/context_assembly/` | `context/assembly.rb` plus preparation, state, and input handling directly under Agent | Separate shared Context procedures, Agent snapshot/state handling, and LLM SDK handling |
42
+ | `Agent::Context::Capability::Base` | The actual implementation, `Tool::Base` | Remove the old name and alias |
43
+ | `agent/tool_execution/tool_definition_set.rb` | `tool/definition_set.rb` | Transfer shared definition handling; keep Agent-specific construction in Agent |
44
+ | `execution_contract/` and `execution_services/` | `execution/` and the necessary `execution/concurrency/` | Consolidate operations, values, and shared rules; do not add thin subdivisions such as `execution_result` |
45
+ | `WorkerSubmission` | `Execution.submit` | Remove the forwarding-only module |
46
+ | `Runnable#trace` | `Tracing::Observation.trace` | Remove the execution foundation's dependency on observation |
47
+ | `tool/contract`, `filter/contract`, `output_parser/contract`, `agent/lifecycle_contract` | Exception files under their owning domains | Remove exception-only directories; retain existing meaningful exception constant names as actual definitions |
48
+
49
+ Custom LLM adapters implement `build_chat`, `configure_chat`, `message`, and `tool_call` in addition to complete/stream. The base class supplies a default `identity` and a nil default for `input_budget`. See `sig/phronomy/llm_adapter/base.rbs` for exact keywords and return contracts. Translate SDK-specific exceptions into LLM failures at adapter operation boundaries, preserving the original cause. Do not translate application exceptions or cancellation into unrelated provider failures.
50
+
51
+ The existing `tool_result_max_size` configuration API and logger are supplied by application composition to neutral RuntimeSettings. Remove references from Tool to the composition factory while preserving default, nil, and scoped-copy semantics. Place RBS in `sig/` and `sig/_private/`, and analyze dependencies based on implementation constants and declaration ownership.
52
+
53
+ ## Progress by r8 item
54
+
55
+ | Item | This implementation unit | Outstanding work |
56
56
  |---|---|---|
57
- | DP01 Context集約 | 主対象を実装 | より広いdomain入力・公開操作レビューは残る |
58
- | DP02 Tool共通基盤 | 定義・認可評価・呼出しの共通部分を実装 | Agent側FSM接続と全親子認可の整理はDP12/P04 |
59
- | DP03 Execution統合 | 実装 | domain全体のFSM利用整理を完了としない |
60
- | DP04 Persistence | 未着手 | facade除去、共通transaction/参加/成否照合API |
61
- | DP05 domain保存schema | 未着手 | MultiAgent/Workflowのstorage_contract統合 |
62
- | DP06 LLM集約 | 前提部分のみ | llm_contractとllm_adapterの全面統合 |
63
- | DP07 薄い失敗directory統合 | 実装 | domainごとの失敗語彙全体の再設計ではない |
64
- | DP08 composition集約 | 接続追加のみ | runtime/persistence/agent構成の物理統合 |
65
- | DP09 Embeddings独立 | 未着手 | vector_storeからの独立配置 |
66
- | DP10 Documents | 未着手 | loader/splitter再配置 |
67
- | DP11 assembly/concerns分解 | 主対象を実装 | Agent固有処理はAgent直下に保持 |
68
- | DP12 domain実行接続 | Workflow終了境界など一部 | Agent/ToolInvocation/Teamのdomain判断とFSM接続の全面分離 |
69
- | DP13 Recovery/Handoff | 未着手 | domain復旧・Persistence成否照合・親子操作の所有整理 |
70
- | P02保存参加 | Agent/Contextの既存transactionで検証 | 外側scope、savepoint、複数domainの公開参加API |
71
- | P01/P03〜P06保存・親子連携 | 未着手 | 下記の原子性条件を確定する必要がある |
72
- | 155組・393件の三角形レビュー | 再判定未完了 | 図の再解析は判定完了の代わりにはならない |
57
+ | DP01 Context consolidation | Main scope implemented | Broader domain inputs and public operations still require review |
58
+ | DP02 Shared Tool foundation | Shared definition, authorization evaluation, and invocation implemented | Agent FSM bindings and all parent/child authorization rules remain under DP12/P04 |
59
+ | DP03 Execution consolidation | Implemented | This does not complete the review of FSM use across all domains |
60
+ | DP04 Persistence | Not started | Facade removal and shared transaction/participation/outcome-reconciliation APIs |
61
+ | DP05 Domain persistence schemas | Not started | Consolidation of MultiAgent/Workflow storage_contract |
62
+ | DP06 LLM consolidation | Prerequisites only | Full consolidation of llm_contract and llm_adapter |
63
+ | DP07 Consolidation of thin failure directories | Implemented | This is not a redesign of every domain's failure vocabulary |
64
+ | DP08 Composition consolidation | Bindings added only | Physical consolidation of runtime/persistence/agent composition |
65
+ | DP09 Independent Embeddings domain | Not started | Placement independent of vector_store |
66
+ | DP10 Documents | Not started | Loader/splitter relocation |
67
+ | DP11 Decomposition of assembly/concerns | Main scope implemented | Agent-specific processing remains directly under Agent |
68
+ | DP12 Domain execution bindings | Partial, including the Workflow completion boundary | Full separation of Agent/ToolInvocation/Team domain decisions from FSM bindings |
69
+ | DP13 Recovery/Handoff | Not started | Ownership of domain recovery, Persistence outcome reconciliation, and parent/child operations |
70
+ | P02 Persistence participation | Validated in the existing Agent/Context transaction | Outer scopes, savepoints, and public participation APIs across multiple domains |
71
+ | P01/P03-P06 Persistence and parent/child coordination | Not started | The atomicity conditions below must be established |
72
+ | Triangle review: 155 pairs, 393 cases | Reassessment incomplete | Regenerating the diagrams does not substitute for completing the assessment |
73
73
 
74
- NC/F/RMの全項目を「対応済み」とする資料は作成していない。受入可否はこの表の実装単位と同梱テスト証拠に限定する。
74
+ No document claims that every NC/F/RM item has been addressed. Acceptance claims are limited to the implementation units in this table and the accompanying test evidence.
75
75
 
76
- ## Persistenceをこの適用単位から外した理由
76
+ ## Why Persistence is outside this implementation unit
77
77
 
78
- 現在のAgent初回受付は保存transaction内でTeam予約を読む。AgentからTeam内部への参照は最終設計では解消すべきだが、検証を単純に先行呼出へ移すと次の競合が生じる。
78
+ Initial Agent admission currently reads the Team reservation inside the persistence transaction. The final design should eliminate Agent's reference to Team internals, but simply moving validation to an earlier call creates this race:
79
79
 
80
- 1. 親側が予約の有効性を確認する。
81
- 2. 別の処理が予約を取り消す。
82
- 3. Agentが新しいtransactionで受付記録を保存し、取消済みの子を開始してしまう。
80
+ 1. The parent checks that the reservation is valid.
81
+ 2. Another operation cancels the reservation.
82
+ 3. Agent saves its admission record in a new transaction and starts the cancelled child.
83
83
 
84
- 次の適用単位では、親が所有する予約確認とAgent受付記録を同一scopeで行う参加APIが必要である。親は予約規則、Agentは受付規則、Persistenceは参加とcommit境界を所有する。Agentが親kindをswitchしてTeamを選ぶ現在の逆依存を、新しいcallbackの裏へ隠すだけでは解決にならない。
84
+ The next implementation unit needs a participation API that performs the parent-owned reservation check and records Agent admission within the same scope. The parent owns reservation rules, Agent owns admission rules, and Persistence owns participation and commit boundaries. Merely hiding the current reverse dependency, where Agent switches on parent kind to select Team, behind a new callback would not resolve it.
85
85
 
86
- 具体的に未確定なのは、参加操作の公開keyword/返却値、取消との競合条件、commit後のRuntime admission、停止後の同じ子IDによる照会・再開である。Workflowのhalt/finish snapshotだけで任意action内の子実行が耐障害化されるとは扱わない。Workflow→Agent/Teamの具体経路、checkpoint、結果取込一回性をP05で定める。成否不明は単一record一致だけで成功にせず、複数domainの証拠をP06で定める。
86
+ The unresolved details are public participation keywords/return values, races with cancellation, post-commit Runtime admission, and querying/resuming with the same child ID after interruption. Workflow halt/finish snapshots alone do not make child execution inside arbitrary actions durable. P05 must define the concrete Workflow-to-Agent/Team paths, checkpoints, and one-time result incorporation. Unknown outcomes must not be treated as success based on a single matching record; P06 must define evidence across multiple domains.
87
87
 
88
- そのため既存Persistence facade、Team受付検証、予約・子記録のtransaction境界を本変更では改変しない。保証を弱めた仮実装を入れず、次の仕様・実装単位として残す。
88
+ Therefore this change does not alter the existing Persistence facade, Team admission validation, or transaction boundaries for reservations and child records. These remain for the next specification and implementation unit, rather than introducing provisional code with weaker guarantees.
89
89
 
90
- ## 解析図の読み方
90
+ ## Reading the analysis diagrams
91
91
 
92
- 実ソースとRBSから再生成する。従来の水平帯・グループ色・個別module枠を維持し、文字の背景は透過。M33/M41/M44への矢印は表示のみ省略し、JSON・行列・境界判定にはすべて残す。旧IDは再利用せず退役させる。
92
+ Regenerate the diagrams from actual source and RBS. Preserve the existing horizontal bands, group colors, individual module boxes, and transparent text backgrounds. Arrows to M33/M41/M44 are omitted only from the display; retain them in JSON, matrices, and boundary assessments. Retire old IDs instead of reusing them.
93
93
 
94
- これは修正版candidateの実測図であり、全r8完了時の構想図ではない。残る循環・逆依存もそのまま出力する。静的解析で見えない注入先・動的dispatchはRBSだけで完全に証明できない。Engine機構接続とdomain保存の実行テストを併用する。
94
+ These are measured diagrams of the revised candidate, not conceptual diagrams of a completed r8. Include remaining cycles and reverse dependencies. RBS alone cannot fully prove injected targets or dynamic dispatch that static analysis cannot observe. Combine it with execution tests for Engine mechanism bindings and domain persistence.
95
95
 
96
96
  ```bash
97
97
  bundle exec rbs -I sig validate
98
98
  python -m pip install -r tools/architecture/tools/requirements.txt
99
99
  python -m unittest discover -s tools/architecture/tests -v
100
- # lib/sigをcommitした後、未公開candidateでは次の指定を用いる
100
+ # After committing lib/sig, use this option for an unpublished candidate.
101
101
  python tools/architecture/refresh_diagram.py . tmp/architecture-r8-unit1 --candidate
102
102
  ```
103
103
 
104
- 同梱SVGのSHAは作成用のローカルcandidateを示す。利用者が適用してcommitしたSHAとは異なるため、適用後の図はそのcheckoutで再生成する。Rubyの検証環境、件数、skip理由、未検証環境と適用手順は配布パッケージの検証報告を参照する。
104
+ The SHA in the supplied SVG identifies the local candidate used to generate it. It differs from the SHA created when the user applies and commits the changes, so regenerate the post-application diagrams from that checkout. See the distribution package's verification report for the Ruby environment, test counts, skip reasons, unverified environments, and application procedure.
@@ -1,5 +1,8 @@
1
1
  # r8 unit15: Generation contract boundaries
2
2
 
3
+ > Historical contract: parser injection/fallback is superseded by
4
+ > [structured output and scope](../architecture/structured-output-and-scope.md).
5
+
3
6
  This responsibility refactor is based on applied unit14, commit
4
7
  `97c3d76b35594bb971a60a2932410ddf22e48d3a` (tree
5
8
  `c326196212a4ac369294a9ccb936619813e51250`).
@@ -1,55 +1,55 @@
1
- # r8 unit 2:親の予約確認とAgent受付
1
+ # r8 unit 2: Parent reservation checks and Agent admission
2
2
 
3
- この単位はP02/P03の受付境界を実装する。基準はcore `16e6fcb2dd49836735598525114abfc256d0773e`。r8全体やPersistenceの全面整理の完了ではない。
3
+ This unit implements the P02/P03 admission boundary. The core baseline is `16e6fcb2dd49836735598525114abfc256d0773e`. It does not complete all of r8 or the entire Persistence reorganization.
4
4
 
5
- ## 責務と操作
5
+ ## Responsibilities and operations
6
6
 
7
- | 担当 | 公開操作・共通規則 | 依存と内部実装 |
7
+ | Owner | Public operations and shared rules | Dependencies and internal implementation |
8
8
  |---|---|---|
9
- | 共通Persistence | `atomic`、`Transaction#participate`、`committed?`。同じPersistence、同期thread、有効scope、savepoint、commit応答を検証 | Storageの公開transaction・scope規則を利用。Agent/Team/Workflowや構成担当を選ばない |
10
- | Agent | `Admission#accept_in`。入力記録・実行ID・Agentの受付とrevision更新を同一scopeへ保存 | Agentの保存担当を使用。親のkind・Team割当・subagent snapshot・Handoff予約を解釈しない |
11
- | MultiAgent | `ReservedChildAdmission#admit`。親の取消・slot・子IDを検証し、Agent受付を同じscopeへ参加させる | 自分の保存担当が予約の根拠を読み、必要なguardを取得する |
12
- | 保存担当 | `Agent::Persistence::Admission`、`MultiAgent::Persistence::Reservation` | raw Storage viewはこの境界で使用。ドメイン操作へraw viewを渡さない |
9
+ | Shared Persistence | `atomic`, `Transaction#participate`, and `committed?`; validates the same Persistence instance, synchronous thread, active scope, savepoints, and commit acknowledgements | Uses Storage's public transaction/scope rules; does not select Agent, Team, Workflow, or composition components |
10
+ | Agent | `Admission#accept_in`; persists input records, execution identity, Agent admission, and revision updates in the same scope | Uses Agent's persistence component; does not interpret parent kind, Team assignments, subagent snapshots, or Handoff reservations |
11
+ | MultiAgent | `ReservedChildAdmission#admit`; validates parent cancellation, slot, and child ID, and has Agent admission participate in the same scope | Its own persistence component reads the reservation evidence and acquires the required guards |
12
+ | Persistence components | `Agent::Persistence::Admission`, `MultiAgent::Persistence::Reservation` | Uses raw Storage views at this boundary; does not pass raw views to domain operations |
13
13
 
14
- AgentのRuntime admission取得、FSM開始、live状態の反映は既存のExecutionCoordinatorが引き続き所有する。新しいAdmissionはその短い保存フェーズだけであり、Agent実行全体を親のDB transactionへ入れない。通常のアプリは新しい参加クラスを実装・生成する必要がない。
14
+ The existing ExecutionCoordinator continues to own acquiring Agent Runtime admission, starting the FSM, and applying live state. The new Admission covers only the short persistence phase; it does not place the entire Agent execution inside the parent's database transaction. Ordinary applications do not need to implement or instantiate the new participation classes.
15
15
 
16
- `phronomy_admission` は内部の現在の配線であり、Procやオブジェクトを保存しない。永続化するのは従来の相関情報と親子IDだけ。Team/subagent/Handoffの開始・再開担当が現在の参加者を渡す。保存済み実行への再接続はExactExecutionの同一ID照合と復旧規則を維持する。
16
+ `phronomy_admission` is current internal wiring; no Proc or object is persisted. Only the existing correlation information and parent/child IDs are stored. The Team/subagent/Handoff start and resume components supply the current participant. Reconnecting to a persisted execution preserves ExactExecution's same-ID matching and recovery rules.
17
17
 
18
- ## 保存順序と失敗
18
+ ## Persistence ordering and failures
19
19
 
20
- 1. Agentが既存のRuntime受付を取得し、同期workerで保存操作を開始する。
21
- 2. MultiAgentが短い`atomic` scopeを開き、親のguardを取得してから予約を読み直す。
22
- 3. 親の取消・割当・子の識別子を検証する。Agentは同じscopeで入力内容・AgentExecution・AgentRootを保存する。
23
- 4. commit応答が成功した後に、Agent実行担当だけが受付結果を取得し、準備・FSM・live反映を進める。
20
+ 1. Agent acquires the existing Runtime admission and begins the persistence operation on a synchronous worker.
21
+ 2. MultiAgent opens a short `atomic` scope, acquires the parent guard, and then rereads the reservation.
22
+ 3. It validates parent cancellation, assignment, and child identity. Agent stores the input content, AgentExecution, and AgentRoot in the same scope.
23
+ 4. Only after a successful commit acknowledgement does the Agent execution component obtain the admission result and continue preparation, FSM execution, and live-state updates.
24
24
 
25
- 参加操作の戻り値はcommit成功を意味しない。`accept_in`はnilを返し、Agent内部の`result`は外側のcommitまで利用できない。二重参加、別Persistence、別thread、終了後scopeは拒否する。同じbackendを包む別Persistenceも同一scopeと扱わない。raw backend transactionの中から新しくcommit所有者を名乗ることも拒否する。
25
+ A participation operation's return value does not mean that commit succeeded. `accept_in` returns nil, and the Agent-internal `result` is unavailable until the outer commit. Duplicate participation, a different Persistence instance, a different thread, or an expired scope is rejected. Separate Persistence instances wrapping the same backend are not treated as the same scope. Code inside a raw backend transaction cannot claim to be a new commit owner.
26
26
 
27
- 明示的な入れ子はsavepointとして動く。内側が成功しても外側がrollbackした場合は未成立。参加処理中の例外を内側で捕捉しても、失敗したscopeの先行変更をcommitできない。LLM、Tool、scheduler、外部callback、非同期待機を参加処理へ入れない。
27
+ Explicit nesting uses savepoints. Inner success is not committed if the outer transaction rolls back. Even if an exception during participation is caught inside the scope, earlier changes in that failed scope cannot be committed. Do not perform LLM calls, Tool calls, scheduling, external callbacks, or asynchronous waits inside participation operations.
28
28
 
29
- Storageのscope違反は`Persistence::TransactionError`へcause・backtraceを保持して変換する。この名前の変更は、保存成否が既知であるとの宣言ではない。IOError等の成否不明な保存失敗は変換・自動retryせず、既存のAgent復旧規則へ渡す。今回、一般化した保存成否照合APIは追加していない。
29
+ Storage scope violations are translated into `Persistence::TransactionError`, preserving cause and backtrace. This naming change does not assert that the persistence outcome is known. Persistence failures with unknown outcomes, such as IOError, are neither translated nor automatically retried; they pass to existing Agent recovery rules. This unit does not add a generalized persistence-outcome reconciliation API.
30
30
 
31
- ## 取消との競合
31
+ ## Races with cancellation
32
32
 
33
- TeamはTeamRoot、subagentは親AgentRoot、Handoffはrouting recordをguardとする。PostgreSQLではそのguardの行ロックと既存の条件付き更新によって、取消・変更と子受付を順序付ける。子受付側の通常readだけでは、この保証は成立しなかった。
33
+ Team uses TeamRoot as its guard, subagents use the parent AgentRoot, and Handoff uses the routing record. On PostgreSQL, row locks on the guard and existing conditional updates order cancellation/changes against child admission. Ordinary reads on the child admission path alone did not provide this guarantee.
34
34
 
35
- Handoff取消側は最初に子の状態を観測し、未完了/不在ならroutingをロックして**子の状態を再取得**する。待機中に子受付がcommitした場合、古い「不在」の判断を捨て、受付済みの子へ公開取消を送る。既に終端の実行への取消は従来どおり結果参照として扱う。
35
+ The Handoff cancellation path first observes the child state. If the child is incomplete or absent, it locks routing and **reads the child state again**. If child admission committed while it was waiting, it discards the stale absence observation and sends public cancellation to the admitted child. Cancellation of an already terminal execution continues to act as result access.
36
36
 
37
- InMemoryは共有Monitor、SQLiteはtransactionと書込競合検出、PostgreSQLは行ロックを使用する。SQLiteで競合したtransactionは成功とみなさず、backendの失敗を扱う。分散leaseや外部副作用のexactly-onceは追加しない。実PostgreSQLでの待機順序はexamplesの新しい3件の並行テストで確認する対象であり、InMemory/SQLiteの成功から推定して済ませない。
37
+ InMemory uses a shared Monitor, SQLite uses transactions and write-conflict detection, and PostgreSQL uses row locks. A conflicting SQLite transaction is not considered successful; its backend failure is handled. No distributed lease or exactly-once guarantee for external effects is added. Actual PostgreSQL waiting order is to be checked by the three new concurrency tests in examples; it must not be inferred from successful InMemory/SQLite tests.
38
38
 
39
- ## API・ファイル変更
39
+ ## API and file changes
40
40
 
41
- - Agent::InitialPreparationの`build_admitted_execution`と3種の親検証・kind分岐を削除。Agent自身の受付共通処理とMultiAgentの予約判断へ分離した。
42
- - 共通の参加frameworkを`persistence/transaction.rb`、Agent受付を`agent/admission.rb`、保存接続を既存の各domainの`persistence/`へ置いた。新しいディレクトリや独立Contractは増やしていない。
43
- - Storage SPIに同期contextの`transaction_open?`を追加。Storage::Backendの継承実装には共通実装が提供される。継承しない独自SPI実装はこの操作も提供する必要がある。RBS・SPI snapshot・duck-typed backendの検証を更新した。
44
- - Persistenceの既知scope失敗の公開型を`Persistence::TransactionError`へ統一し、旧Storage例外のaliasは設けない。Storageを直接使う処理では従来のStorage例外を使用する。
45
- - RBSはsigに配置し、参加者factory、Agent受付、MultiAgentの依存を宣言する。動的な`phronomy_admission`注入も本書と利用箇所で追跡する。
46
- - 依存解析のExecution境界規則を図のrevision表示名から分離した。unit名の更新で同期backendからExecutionへの禁止規則が解除されないことを回帰テストする。
47
- - 保存recordの形式、ID、revision規則は変更していない。データ移行は不要。
41
+ - Remove Agent::InitialPreparation's `build_admitted_execution`, its three kinds of parent validation, and its parent-kind branches. Separate shared Agent admission handling from MultiAgent reservation decisions.
42
+ - Place the shared participation framework in `persistence/transaction.rb`, Agent admission in `agent/admission.rb`, and persistence bindings in each domain's existing `persistence/`. No new directory or independent Contract is added.
43
+ - Add synchronous-context `transaction_open?` to the Storage SPI. Implementations inheriting Storage::Backend receive a shared implementation. Custom SPI implementations that do not inherit it must also provide this operation. Update RBS, the SPI snapshot, and duck-typed backend validation.
44
+ - Unify the public type for known Persistence scope failures as `Persistence::TransactionError`; do not add an alias for the old Storage exception. Code using Storage directly continues to use the existing Storage exception.
45
+ - Place RBS in sig and declare participant factories, Agent admission, and MultiAgent dependencies. Track dynamic `phronomy_admission` injection in this document and at its use sites.
46
+ - Separate dependency analysis rules for the Execution boundary from the diagram's revision display name. Add a regression test ensuring that changing the unit name does not disable the prohibition on synchronous-backend dependencies on Execution.
47
+ - Preserve persisted record formats, IDs, and revision rules. No data migration is required.
48
48
 
49
- ## 残る課題
49
+ ## Outstanding work
50
50
 
51
- `Persistence#transaction`とdomain repositoryの一括窓口は現行利用箇所が残るため、この単位では全面削除していない。互換維持のために新しい旧名aliasを追加したものではないが、P01/DP04の完了条件は未達である。次にdomain照会・保存構成を移し、不要な窓口を利用側と同時に削除する。
51
+ `Persistence#transaction` and the combined domain-repository facade still have callers and are not fully removed in this unit. This does not add new aliases for old names to preserve compatibility, but the P01/DP04 completion conditions remain unmet. Next, move domain queries and persistence composition, then remove unnecessary entry points together with their callers.
52
52
 
53
- MultiAgentの保存担当にはAgentのexecution/Handoff repositoryへの参照が残る。予約検証の所有者は整理したが、親子の公開投影・認可照会・結果取込まで隠蔽したとは扱わない。P04/F02/F03の残課題として、Agentが公開する操作と、MultiAgentが所有すべき保存形式を確定する。一般的なmetadata getterを足すだけの解決にはしない。
53
+ MultiAgent's persistence component still references Agent execution/Handoff repositories. Ownership of reservation validation has been clarified, but this does not mean that public parent/child projections, authorization queries, and result incorporation have all been encapsulated. Under the remaining P04/F02/F03 work, establish the operations Agent should expose and the persistence formats MultiAgent should own. Adding a generic metadata getter alone is not a solution.
54
54
 
55
- Agent/TeamのFSM接続、Workflowのdurableな子連携(P05)、複数記録の保存成否照合(P06)、残りの配置整理、155組・393件の意味的再判定も残る。今回のSVGは実装候補を描き、全体の循環解消を示す構想図にはしない。
55
+ Agent/Team FSM bindings, durable Workflow child coordination (P05), reconciliation of persistence outcomes across multiple records (P06), the remaining layout reorganization, and semantic reassessment of 155 pairs/393 cases also remain outstanding. The SVG for this unit depicts the implementation candidate, not a conceptual graph claiming that all cycles have been eliminated.
@@ -6,7 +6,8 @@ all of C04, C06 or the overall target complete.
6
6
 
7
7
  | Owner | Responsibility after this change |
8
8
  | --- | --- |
9
- | Agent InvocationTransitions | Phase vocabulary, ordered automatic/external transitions, guard evaluation, iteration bound |
9
+ | Agent IterationBudget | Logical LLM-call limit over durable AgentExecution records; see [iteration budget](agent-iteration-budget.md) |
10
+ | Agent InvocationTransitions | Phase vocabulary, ordered automatic/external transitions, guard evaluation, automatic-chain safety bound |
10
11
  | Agent InvocationActions | Prepared input, LLM dispatch, Tool batch orchestration and result/event interpretation |
11
12
  | Agent ExecutionCoordinator / RecoveryCoordinator | Admission, durable preparation, approval, terminal outcome, recovery and causal revision checks |
12
13
  | Agent ExecutionEnvironment | Private process-local connection required by the Agent framework; session construction/registration, serial owner and operation submission |