phronomy 0.33.0 → 0.34.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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +62 -0
  3. data/CONTRIBUTING.md +5 -5
  4. data/README.md +15 -2
  5. data/RELEASE_CHECKLIST.md +3 -1
  6. data/SECURITY.md +1 -1
  7. data/VERIFY.sh +1 -9
  8. data/docs/architecture/error-api-review.md +6 -2
  9. data/docs/architecture/structured-output-and-scope.md +3 -4
  10. data/docs/decisions/016-semantic-multi-agent-handoff.md +6 -5
  11. data/docs/features.md +2 -2
  12. data/docs/migrations/cleanup-audit.md +89 -0
  13. data/docs/migrations/legacy-format-removal.md +55 -0
  14. data/docs/migrations/r8-unit6.md +4 -2
  15. data/docs/migrations/vector-async-clients.md +6 -1
  16. data/docs/shared-state-sharing.md +14 -4
  17. data/lib/phronomy/agent/execution/agent_invocation.rb +0 -4
  18. data/lib/phronomy/agent/handoff/transfer_projection.rb +0 -9
  19. data/lib/phronomy/agent/journal/journal_record.rb +2 -2
  20. data/lib/phronomy/agent/recovery/recovery_rules.rb +0 -12
  21. data/lib/phronomy/agent/store.rb +3 -8
  22. data/lib/phronomy/agent/tool_execution/tool_invocation.rb +0 -3
  23. data/lib/phronomy/context/context_policy.rb +3 -7
  24. data/lib/phronomy/context/llm_input_manifest.rb +3 -3
  25. data/lib/phronomy/engine/runtime/shutdown_result.rb +0 -5
  26. data/lib/phronomy/execution/execution.rb +0 -11
  27. data/lib/phronomy/multi_agent/shared_state.rb +5 -8
  28. data/lib/phronomy/version.rb +1 -1
  29. metadata +4 -11
  30. data/lib/phronomy/execution/scheduler_reentrancy_error.rb +0 -9
  31. data/lib/phronomy/persistence/migration/initial_format_migration.rb +0 -226
  32. data/scripts/add_to_h_to_token_doubles.rb +0 -33
  33. data/scripts/add_to_h_unnamed_doubles.rb +0 -27
  34. data/scripts/migrate_generator_verifier_result.rb +0 -18
  35. data/scripts/migrate_spec_agent_definition.rb +0 -108
  36. data/scripts/migrate_spec_agent_definition_pass2.rb +0 -53
  37. data/scripts/migrate_spec_inline_pass3.rb +0 -24
  38. data/sig/phronomy/persistence/migration.rbs +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e696f701b22d91c4ccb8f566e28274b73e9fd69704a673e18a687a1d377b4583
4
- data.tar.gz: 7a63749fb58c70fb6c74a843a601bb48401ffe35fa02de03a63fa9f8d6320552
3
+ metadata.gz: 4c67e91b9abb65c5ab2ddc5b657afa6843b916a5ba84aefcd8f808ae297c3236
4
+ data.tar.gz: b5894936fa47d493da81c650edbf3c330eaeec7101c68ec91acf96bec00d1a79
5
5
  SHA512:
6
- metadata.gz: af029ecc2491d2912c48fef847f8501ce255040759bb5d8edba3949d2bea0352b2a6a89e731d70493570c5b72d26e094ed03d80aff412f6805af21a0da588219
7
- data.tar.gz: 529ece7bc74b4096d332e9f39a3097933f1441797f5dc22b5bb9ec9d5b39fde2c42709d2b53e83b99a3e42ec6e2e9a227920f10371e6ac65772241cb54d0abc7
6
+ metadata.gz: ebec13bc657697922f3f487eefe809a35570b36a574e8a3ea95d5124459035ca263ad39b89419e8042621e4971f550cbb7d21ab206d2961f8a7f01bec6b9514e
7
+ data.tar.gz: b1d930edb100e7782522a9d666d555756fcc50e5be46881c58c035f2e021631093132b4bde4cec8134f296f068ddb9cb0fd17548ea356afad32652d484b7da91
data/CHANGELOG.md CHANGED
@@ -12,6 +12,68 @@ Release history for 0.14.0 and earlier is archived in
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ## [0.34.0] - 2026-11-16
16
+
17
+ ### Changed
18
+
19
+ - Route ContextPolicy item estimates directly through the protected
20
+ `estimate_tokens` extension operation, removing the redundant private wrapper.
21
+ - Exercise Tool approval redaction through the display/snapshot path used by
22
+ production approval requests instead of internal convenience getters.
23
+ - Replace references to an absent repository language-check script with an
24
+ external maintainer check and recorded evidence. Correct the Storage phase
25
+ status: P4 is implemented; the separate final P5 review remains pending.
26
+
27
+ ### Fixed
28
+
29
+ - Derive default SharedState members through `Agent::Base.with_tools`, retaining
30
+ Phronomy authoring settings and filters as custom sharing already does. A
31
+ member's iteration limit, temperature and other configuration no longer reset
32
+ when built-in sharing Tools are added. Preserve Tool aliases, the generated
33
+ definition identity and default findings-store behavior.
34
+
35
+ ### Removed
36
+
37
+ - Remove Handoff's old selection-unit metadata fallback and Agent Store's raw
38
+ argument fallback. Current conversation groups and exact validated arguments
39
+ remain the authoritative saved facts; current record writers are unchanged.
40
+ - Retire `Persistence::Migration::InitialFormatMigration` and the old
41
+ GeneratorVerifier Result JSON conversion command, including their dedicated
42
+ migration tests and active usage instructions. No replacement converter or
43
+ compatibility entry point is supplied. Current codecs, Result validation and
44
+ the separate Unit4 snapshot migration remain. See the
45
+ [legacy-format cleanup](docs/migrations/legacy-format-removal.md).
46
+ - Remove `Runtime::ShutdownResult#success?`; use the equivalent
47
+ `cleanup_complete?`. Keep `clean?`, which additionally requires a graceful
48
+ shutdown.
49
+ - Remove the obsolete `SchedulerReentrancyError` subclass; use
50
+ `EventLoopReentrancyError`, which is already raised by current execution paths.
51
+ No compatibility aliases are retained. See the
52
+ [cleanup migration](docs/migrations/cleanup-audit.md).
53
+ - Remove unused internal Invocation, RecoveryRules and Execution helpers, along
54
+ with five completed development-only spec migration scripts. Keep the public
55
+ `JournalProjection#llm_call_records` and
56
+ `LLMInputManifest#referenced_content_refs` operations and the Scope hooks still
57
+ used for result composition.
58
+
59
+ ### Compatibility and verification
60
+
61
+ - Replace `Runtime::ShutdownResult#success?` with `cleanup_complete?` and rescue
62
+ `EventLoopReentrancyError` instead of the removed `SchedulerReentrancyError`.
63
+ No compatibility aliases are retained. See the
64
+ [cleanup migration](docs/migrations/cleanup-audit.md).
65
+ - Historical pre-S3 and GeneratorVerifier Result conversion support is retired
66
+ without a replacement command. Current record writers and saved representation
67
+ are unchanged; this release does not rewrite existing stores. Handoff no longer
68
+ derives groups from old selection-unit metadata, and authorization requires
69
+ validated argument evidence. Review the
70
+ [legacy-format migration](docs/migrations/legacy-format-removal.md) before
71
+ upgrading applications that still consume those historical records.
72
+ - Previously observed LM Studio/gpt-oss PEG-format failures are not resolved by
73
+ this cleanup. This release does not claim to fix their root cause or prevent
74
+ recurrence; offline persistence/recovery checks do not establish full real-LLM
75
+ acceptance.
76
+
15
77
  ## [0.33.0] - 2026-11-14
16
78
 
17
79
  ### Added
data/CONTRIBUTING.md CHANGED
@@ -25,11 +25,11 @@ Run the linter:
25
25
  bundle exec standardrb
26
26
  ```
27
27
 
28
- Check that no Japanese characters appear in source files:
29
-
30
- ```bash
31
- ruby scripts/check_japanese.rb
32
- ```
28
+ Check that source, comments, documentation and release notes are in English.
29
+ Use the maintainer's external language checker and record its command, checked
30
+ files and result with the review evidence. Check complete final files, including
31
+ new files; a diff-only check can miss retained non-English content. This
32
+ repository does not bundle a language-check script.
33
33
 
34
34
  ---
35
35
 
data/README.md CHANGED
@@ -37,19 +37,31 @@ tracking `main` directly.
37
37
 
38
38
  See [Features and Application Programming Interface (API) stability](docs/features.md) for the full feature matrix.
39
39
 
40
- The following table describes the application APIs available in v0.33.0.
41
- The new sharing, Tool composition and Context budgeting operations remain
40
+ The following table describes the application APIs available in v0.34.0.
41
+ The sharing, Tool composition and Context budgeting operations remain
42
42
  Experimental; their introduction version is shown below.
43
43
  Worker hosting and completed parent/child release require v0.32.0 or later.
44
44
  Review the [0.31 migration notes](docs/migrations/0.31.md) before upgrading
45
45
  persistent applications or custom Agent Tool subclasses.
46
46
 
47
+ The v0.34.0 cleanup removes obsolete entry points. Use
48
+ `EventLoopReentrancyError` for EventLoop reentrancy failures and
49
+ `Runtime#shutdown`'s `cleanup_complete?` result predicate for resource release;
50
+ `clean?` additionally requires a graceful shutdown. See the
51
+ [cleanup migration](docs/migrations/cleanup-audit.md) before upgrading to v0.34.0.
52
+ The [legacy-format cleanup](docs/migrations/legacy-format-removal.md) separately
53
+ retires old data-conversion entry points and read fallbacks without changing
54
+ the current saved representation.
55
+
47
56
  | API | Stability | Contract |
48
57
  |---|---|---|
58
+ | `Persistence::Migration::InitialFormatMigration` | Removed (v0.34.0) | The pre-S3 conversion API is retired without a replacement. Current domain codecs and the separate Unit4 snapshot migration remain. [Legacy-format cleanup](docs/migrations/legacy-format-removal.md) |
49
59
  | `Context::ContextPolicyInput#input_token_limit / #with_input_token_limit` and protected `ContextPolicy#estimate_tokens` | Experimental (since v0.33.0) | Inspect and constrain selection budgets and estimate candidate content through Context-owned operations. [Policy budgeting](docs/context-policy-budgeting.md) |
50
60
  | `Agent::Base.with_tools(definitions, id:, version:)` | Experimental (since v0.33.0) | Derive an Agent class with a complete replacement Tool map and explicit definition identity while preserving Phronomy authoring settings and filters. [Tool composition](docs/shared-state-sharing.md#deriving-an-agent-with-a-complete-tool-set) |
51
61
  | `MultiAgent::SharedState.sharing(provider, id:, version:)`, `SharedState::Binding` and `SharedState::MemberLifecycleError` | Experimental (since v0.33.0) | Connect application-owned shared data and Tools to sequential coordination through a synchronous invocation-scoped provider. [Custom sharing contract and example](docs/shared-state-sharing.md) |
52
62
  | `Tool::Base#approval_display(arguments:, facts:)` | Beta (since v0.33.0) | The Tool selects the arguments and derived facts a person can see in an approval request. [Approval display](docs/runtime-and-concurrency.md#tool-approval-display) |
63
+ | `Runtime#shutdown` result predicates `cleanup_complete?` and `clean?` | Beta | Check resource release with `cleanup_complete?`; `clean?` additionally requires a graceful shutdown. The obsolete `success?` alias is removed in v0.34.0. [Cleanup migration](docs/migrations/cleanup-audit.md#runtime-cleanup-completion) |
64
+ | `Phronomy::EventLoopReentrancyError` | Beta | Raised when a synchronous operation would block the EventLoop control thread. The obsolete `SchedulerReentrancyError` subclass is removed in v0.34.0. [Cleanup migration](docs/migrations/cleanup-audit.md#eventloop-reentrancy-errors) |
53
65
  | `Phronomy::LLMAdapter::LMStudio` | Beta | Explicit known-output-error identification and bounded opt-in retry; [policy and evidence limits](docs/architecture/lm-studio-output-failures.md) |
54
66
  | Agent `output_schema:`, `schema_delivery:`, `Agent::OutputError` and `OutputParser::JsonSchemaParser` | Beta | Agent returns validated immutable JSON or an explicit output failure; [contract and migration](docs/architecture/structured-output-and-scope.md) |
55
67
  | Agent `transcript_messages` / `transcript_messages_async` | Beta | Read immutable conversation Message values with the same restoration rules as execution results; [reading conversation state](docs/getting-started.md) |
@@ -206,6 +218,7 @@ contracts, timeout/cancellation semantics, metrics, and callback rules.
206
218
  - [0.19 unified Persistence migration](docs/migrations/0.19.md).
207
219
  - [0.22 semantic Multi-Agent Handoff migration](docs/migrations/0.22.md).
208
220
  - [0.31 persistence and Agent lifetime migration](docs/migrations/0.31.md).
221
+ - [0.34 cleanup migration](docs/migrations/cleanup-audit.md) — replacement entry points and retained public operations.
209
222
  - [Architecture Decision Records](docs/decisions/) — design rationale and superseding decisions.
210
223
  - [CHANGELOG](CHANGELOG.md) — current development and recent release history.
211
224
  - [Changelog archive: 0.14.0 and earlier](docs/changelog/0.14-and-earlier.md).
data/RELEASE_CHECKLIST.md CHANGED
@@ -24,7 +24,9 @@ Copy it into the GitHub Release draft and check off each item.
24
24
 
25
25
  - [ ] `bundle exec rspec --format documentation` — 0 failures
26
26
  - [ ] `bundle exec rspec --tag integration` — 0 failures, all expected pending
27
- - [ ] `ruby scripts/check_japanese.rb` — exit 0 (no Japanese in source)
27
+ - [ ] External language check passes on the complete release files; source,
28
+ comments, documentation and release notes are in English. Record the checker
29
+ command, file scope and result; no language-check script is bundled here.
28
30
  - [ ] `bundle exec standardrb` — 0 offenses
29
31
  - [ ] `COVERAGE=1 bundle exec rspec` — coverage above configured threshold (Issue #207)
30
32
  - [ ] CI green on all Ruby matrix versions (3.2 / 3.3 / 3.4 / head)
data/SECURITY.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Version | Supported |
6
6
  |---------|-----------|
7
- | Latest release (main branch) | ✅ |
7
+ | 0.34.0 (latest release) | ✅ |
8
8
  | Older versions | ❌ — please upgrade |
9
9
 
10
10
  Only the latest released version of `phronomy` receives security patches. If you
data/VERIFY.sh CHANGED
@@ -30,12 +30,10 @@ required_files=(
30
30
  lib/phronomy/persistence/durable_record.rb
31
31
  lib/phronomy/persistence/durable_codec.rb
32
32
  lib/phronomy/persistence/repository_facades.rb
33
- lib/phronomy/persistence/migration/initial_format_migration.rb
34
33
  sig/phronomy/persistence.rbs
35
34
  spec/phronomy/persistence/backend_spi_api_spec.rb
36
35
  spec/phronomy/persistence/durable_codec_spec.rb
37
36
  spec/phronomy/persistence/in_memory_spec.rb
38
- spec/phronomy/persistence/initial_format_migration_spec.rb
39
37
  lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb
40
38
  spec/phronomy/workflow_identity_contract_spec.rb
41
39
  lib/phronomy/engine/invocation_context.rb
@@ -128,11 +126,9 @@ syntax_files=(
128
126
  lib/phronomy/persistence/durable_record.rb
129
127
  lib/phronomy/persistence/durable_codec.rb
130
128
  lib/phronomy/persistence/repository_facades.rb
131
- lib/phronomy/persistence/migration/initial_format_migration.rb
132
129
  spec/phronomy/persistence/backend_spi_api_spec.rb
133
130
  spec/phronomy/persistence/durable_codec_spec.rb
134
131
  spec/phronomy/persistence/in_memory_spec.rb
135
- spec/phronomy/persistence/initial_format_migration_spec.rb
136
132
  lib/phronomy/testing/persistence_contract/a_workflow_state_repository.rb
137
133
  spec/phronomy/workflow_identity_contract_spec.rb
138
134
  lib/phronomy/engine/invocation_context.rb
@@ -327,17 +323,14 @@ ruby -c lib/phronomy/persistence/durable_record.rb >/dev/null
327
323
  ruby -c lib/phronomy/persistence/durable_codec.rb >/dev/null
328
324
  ruby -c lib/phronomy/persistence/repository_facades.rb >/dev/null
329
325
  ruby -c lib/phronomy/persistence/in_memory.rb >/dev/null
330
- ruby -c lib/phronomy/persistence/migration/initial_format_migration.rb >/dev/null
331
326
  ruby -c spec/phronomy/persistence/backend_spi_api_spec.rb >/dev/null
332
327
  ruby -c spec/phronomy/persistence/durable_codec_spec.rb >/dev/null
333
328
  ruby -c spec/phronomy/persistence/in_memory_spec.rb >/dev/null
334
- ruby -c spec/phronomy/persistence/initial_format_migration_spec.rb >/dev/null
335
329
  bundle exec rbs -I sig validate
336
330
  bundle exec rspec \
337
331
  spec/phronomy/persistence/backend_spi_api_spec.rb \
338
332
  spec/phronomy/persistence/durable_codec_spec.rb \
339
333
  spec/phronomy/persistence/in_memory_spec.rb \
340
- spec/phronomy/persistence/initial_format_migration_spec.rb \
341
334
  spec/phronomy/persistence/backend_contract_spec.rb \
342
335
  spec/phronomy/agent/agent_execution_codec_spec.rb \
343
336
  spec/phronomy/agent/llm_input_manifest_spec.rb \
@@ -530,8 +523,7 @@ legacy_agent_invocation_identity="$(
530
523
  legacy_agent_invocation_identity="$(
531
524
  printf '%s\n' "$legacy_agent_invocation_identity" |
532
525
  grep -v 'lib/phronomy/agent/base.rb' |
533
- grep -v 'lib/phronomy/agent/agent_execution.rb' |
534
- grep -v 'lib/phronomy/persistence/migration/initial_format_migration.rb' || true
526
+ grep -v 'lib/phronomy/agent/agent_execution.rb' || true
535
527
  )"
536
528
  if [[ -n "$legacy_agent_invocation_identity" ]]; then
537
529
  echo "FAIL: active source/RBS reintroduced agent_invocation_id domain identity:" >&2
@@ -175,7 +175,12 @@ unchanged and acyclic; Ruby+RBS architecture validation passes.
175
175
 
176
176
  ## Static exception inventory
177
177
 
178
- Ripper inspected 339 Ruby files. The following 63 definitions include base, private and optional-integration types; this is not a count of public APIs. Ruby declarations establish ownership. Existing RBS definitions and new owning-domain signatures are checked together.
178
+ The original inventory used Ripper to inspect 339 Ruby files and listed 63
179
+ definitions, including base, private and optional-integration types. The table
180
+ below removes the superseded `SchedulerReentrancyError` entry as part of the
181
+ [cleanup migration](../migrations/cleanup-audit.md). These historical scan totals
182
+ are not a current count of source files or public APIs. Ruby declarations
183
+ establish ownership; RBS declarations are checked at their owning boundaries.
179
184
 
180
185
  | Class | Parent | Declaration |
181
186
  |---|---|---|
@@ -208,7 +213,6 @@ Ripper inspected 339 Ruby files. The following 63 definitions include base, priv
208
213
  | `Phronomy::RecursionLimitError` | `Phronomy::Error` | `lib/phronomy/execution/recursion_limit_error.rb` |
209
214
  | `Phronomy::RuntimeShutdownError` | `Phronomy::Error` | `lib/phronomy/execution/runtime_shutdown_error.rb` |
210
215
  | `Phronomy::RuntimeShutdownReentrancyError` | `Phronomy::RuntimeShutdownError` | `lib/phronomy/execution/runtime_shutdown_reentrancy_error.rb` |
211
- | `Phronomy::SchedulerReentrancyError` | `Phronomy::EventLoopReentrancyError` | `lib/phronomy/execution/scheduler_reentrancy_error.rb` |
212
216
  | `Phronomy::TimeoutError` | `Phronomy::Error` | `lib/phronomy/execution/timeout_error.rb` |
213
217
  | `Phronomy::FilterBlockError` | `Phronomy::Error` | `lib/phronomy/filter/filter_block_error.rb` |
214
218
  | `Phronomy::GeneratorVerifier::UnacceptedResultError` | `Phronomy::Error` | `lib/phronomy/generation/generator_verifier/unaccepted_result_error.rb` |
@@ -173,10 +173,9 @@ Normal low-quality output follows the configured evaluation loop as before.
173
173
 
174
174
  `Result#failure` is nil except for output_failed, where it carries the owned error
175
175
  diagnostic (without raw_output). Hash/JSON round trips, equality, hashing and freeze
176
- include it. `Result.from_h` requires every new field; migrate old saved Result JSON
177
- explicitly with `scripts/migrate_generator_verifier_result.rb OLD.json NEW.json`.
178
- The script adds failure=nil, validates the result and creates a new file. It does
179
- not overwrite the source or silently alter invalid data. `raise_if_unaccepted`
176
+ include it. `Result.from_h` requires every field, including `failure: nil` for
177
+ results without an output failure. It rejects incomplete serialized results.
178
+ `raise_if_unaccepted`
180
179
  retains the Result and the original OutputError cause in the same process.
181
180
 
182
181
  ## Symmetric lifetime rules
@@ -61,11 +61,12 @@ Tool-role messages are one indivisible conversation group. When the selected
61
61
  Plan is realized, the Manifest records the Framework conversation-group identity
62
62
  and classifies canonical Tool exchanges as `tool_exchanges` for Handoff.
63
63
 
64
- `HandoffProjection` groups current-format Manifest segments by that conversation
65
- group identity. It may still read legacy `selection_unit_id` metadata from a
66
- finalized pre-ACS-04 Manifest, but new Context assembly does not recreate
67
- `Selection::Unit`. `Selection::Candidate` and `Selection::Constraint` remain
68
- internal Context-input normalization details only.
64
+ The current `Agent::TransferProjection` groups Manifest segments by that
65
+ conversation-group identity. Segments without a group identity are projected
66
+ independently. Historical selection-unit identifiers and kinds are no longer
67
+ interpreted, and Context assembly does not recreate `Selection::Unit`.
68
+ `Selection::Candidate` and `Selection::Constraint` remain internal Context-input
69
+ normalization details only.
69
70
 
70
71
  Handoff Policy answers what may cross the Agent boundary. Target Context Policy
71
72
  remains the final authority for what enters each Target LLM call. Transferred
data/docs/features.md CHANGED
@@ -90,7 +90,7 @@ Backend authors continue to implement the synchronous SPI only.
90
90
  | **OffloadPool sizing** — `offload_pool_size` / `offload_queue_size`; named pools available for application-owned isolation | Beta |
91
91
  | **InvocationContext** — Explicit cancellation/deadline/policy plus observability-correlation context for Agent and Workflow invocations | Beta |
92
92
  | **Metrics** — OffloadPool active/queue/abandoned metrics plus EventLoop queue/lag metrics | Beta |
93
- | **Runtime lifecycle** — Runtime-owned EventLoop and terminal `Runtime#shutdown` | Beta |
93
+ | **Runtime lifecycle** — Runtime-owned EventLoop and terminal `Runtime#shutdown`; use the result's `cleanup_complete?` for resource release and `clean?` for a graceful shutdown; [cleanup migration](migrations/cleanup-audit.md) | Beta |
94
94
 
95
95
  ## Agent and workflow patterns
96
96
 
@@ -109,7 +109,7 @@ See the [migration guide](migrations/parallel-tool-chat-removal.md).
109
109
  | **Hosted child approvals** — An Orchestrator can release a single direct child and its parent at successive Tool approvals within the same child execution. The host transfers exclusive ownership between workers. [Contract](runtime-and-concurrency.md#hosting-an-orchestrator-through-a-child-approval) | Beta |
110
110
  | **Completed native child release** — A host can unload the local Orchestrator and its finished direct child while preserving their saved results, conversation and coordination history. [Contract](runtime-and-concurrency.md#releasing-a-completed-orchestrator-and-child) | Beta |
111
111
  | **`Phronomy::MultiAgent::TeamCoordinator`** — LLM coordinator with stateful worker Agents | Beta |
112
- | **`Phronomy::MultiAgent::SharedState`** — Sequential peer-agent coordination through an invocation-local findings store; see the [namespace migration](migrations/shared-state-multi-agent.md) | Experimental |
112
+ | **`Phronomy::MultiAgent::SharedState`** — Sequential peer-agent coordination through an invocation-local findings store; default member derivation preserves Phronomy authoring settings through `Agent::Base.with_tools`; see the [sharing contract](shared-state-sharing.md#deriving-an-agent-with-a-complete-tool-set) and [namespace migration](migrations/shared-state-multi-agent.md) | Experimental |
113
113
  | **Agent Tool composition** — `Agent::Base.with_tools(definitions, id:, version:)` derives a class with a complete replacement Tool map while preserving Phronomy authoring settings and filters; [contract](shared-state-sharing.md#deriving-an-agent-with-a-complete-tool-set) | Experimental (Unreleased) |
114
114
  | **Custom shared data and Tools** — `SharedState.sharing(provider, id:, version:)` and `SharedState::Binding` connect application-owned stores and Tool definitions without private overrides; [contract and executable example](shared-state-sharing.md) | Experimental (Unreleased) |
115
115
  | **Human-in-the-loop approval** — durable suspension publishes `:approval_required` through the Agent listener; `approve` / `approve_async` resumes the same logical `execution_id` with a fresh FSMSession incarnation | Beta |
@@ -0,0 +1,89 @@
1
+ # Cleanup audit migration
2
+
3
+ Phronomy 0.34.0 removes redundant internal operations and old public entry points
4
+ whose behavior is already provided by a current operation. Applications must
5
+ use the current names; the removed names have no compatibility aliases. Current
6
+ record writers are unchanged. The subsequent [legacy-format cleanup](legacy-format-removal.md)
7
+ also removes old read fallbacks and explicitly retires two data-conversion
8
+ entry points. It does not rewrite existing stores.
9
+
10
+ For example, an application checking whether Runtime resources were released
11
+ uses `cleanup_complete?` on the result returned by `Runtime#shutdown`. The
12
+ removed `success?` method delegated to that same predicate.
13
+
14
+ ## Runtime cleanup completion
15
+
16
+ Use `cleanup_complete?` to determine whether Runtime-owned resources have stopped.
17
+ Use `clean?` only when the application also needs a graceful, error-free shutdown;
18
+ that stricter predicate is retained and is not a replacement for `success?`.
19
+
20
+ Before:
21
+
22
+ ```ruby
23
+ result = runtime.shutdown
24
+ resources_released = result.success?
25
+ ```
26
+
27
+ After:
28
+
29
+ ```ruby
30
+ result = runtime.shutdown
31
+ resources_released = result.cleanup_complete?
32
+ ```
33
+
34
+ The same replacement applies to a shutdown result returned by
35
+ `Runtime.reset_default!`. Existing reset guards still reject incomplete cleanup.
36
+
37
+ ## EventLoop reentrancy errors
38
+
39
+ Rescue `Phronomy::EventLoopReentrancyError` when a synchronous operation would
40
+ block the EventLoop control thread. Framework operations already raise this
41
+ class. The removed `SchedulerReentrancyError` was an empty subclass and did not
42
+ add a distinct failure or recovery behavior.
43
+
44
+ Before:
45
+
46
+ ```ruby
47
+ begin
48
+ Phronomy::Diagnostics.assert_not_in_event_loop!
49
+ rescue Phronomy::SchedulerReentrancyError => error
50
+ warn error.message
51
+ end
52
+ ```
53
+
54
+ After:
55
+
56
+ ```ruby
57
+ begin
58
+ Phronomy::Diagnostics.assert_not_in_event_loop!
59
+ rescue Phronomy::EventLoopReentrancyError => error
60
+ warn error.message
61
+ end
62
+ ```
63
+
64
+ Ruby rescue matches a class and its subclasses, not its parent. The old rescue
65
+ above therefore did not catch a directly raised `EventLoopReentrancyError` even
66
+ before this cleanup. The current error name describes the actual failure.
67
+
68
+ ## Internal operations
69
+
70
+ Internal cleanup keeps behavior at its owning boundary. Context item factories
71
+ call the protected `ContextPolicy#estimate_tokens` extension operation directly.
72
+ Tool approval requests obtain one display projection and snapshot its arguments
73
+ and facts in the public approval Item.
74
+
75
+ For example, an application that renders approval details continues to use
76
+ `ToolApprovalRequest::Item#arguments` and `#facts`; it does not need the removed
77
+ internal `ToolInvocation#display_arguments` and `#display_facts` getters. The
78
+ public `Tool::Base#approval_display` extension operation remains available.
79
+
80
+ The cleanup also removes the unused internal `AgentInvocation#streaming?`,
81
+ `RecoveryRules.subject_key`, and `Execution#__while_open` and
82
+ `Execution#__cancellation_token` methods. Scope-owned operations used by result
83
+ composition remain in `ExecutionScopeState`. Five completed scripts for migrating
84
+ the repository's own test sources are removed. The subsequent legacy-format
85
+ cleanup separately retires the pre-S3 migration API and old Result JSON converter.
86
+
87
+ `JournalProjection#llm_call_records` and
88
+ `LLMInputManifest#referenced_content_refs` remain available. Lack of calls from
89
+ the repository does not make an application-facing operation removable.
@@ -0,0 +1,55 @@
1
+ # Legacy-format cleanup
2
+
3
+ Phronomy 0.34.0 keeps current saved facts and removes specific historical read
4
+ fallbacks and conversion facilities. It does not rewrite stores or introduce a
5
+ new record version. Retiring the conversion facilities is an intentional removal
6
+ of migration support, not a claim that another public API replaces them.
7
+
8
+ For example, a newly authorized Tool operation continues to store its validated
9
+ arguments, including type coercion and meaningful null values. Its reader no
10
+ longer reconstructs those arguments from an older raw-input field.
11
+
12
+ ## Handoff conversation groups
13
+
14
+ Handoff uses the conversation group recorded by the current Context assembly.
15
+ The historical selection-unit ID and kind no longer supply grouping or category
16
+ information. Segments without a current group still use the ordinary per-segment
17
+ fallback; reserved internal metadata is still removed from transferred content.
18
+
19
+ For example, current Tool-call and Tool-result segments share
20
+ `context_policy_conversation_group_id` and remain together when a Handoff policy
21
+ selects that exchange. A saved `selection_unit_id` is no longer an alternative
22
+ source for that relationship. The Manifest codec remains strict about its
23
+ supported version and required fields.
24
+
25
+ ## Authorized Tool arguments
26
+
27
+ Agent Store reads the exact validated argument snapshot for an authorized
28
+ operation. The raw request remains a separate fact and is not a substitute when
29
+ the validated snapshot is absent.
30
+
31
+ For example, raw `{"count":"2","optional":null}` may validate as
32
+ `{"count":2,"optional":null}`. Authorization matching must use the integer and
33
+ retain the explicit null. An authorized record missing `validated_arguments`
34
+ fails instead of falling back to `arguments` and dropping null values.
35
+
36
+ Provider-response recovery can temporarily record an `authorized` placeholder
37
+ without that snapshot. The normal `framework_calls` continuation validates its
38
+ Tool invocation and saves the prepared snapshot before an operation consumer
39
+ reads it. Directly projecting the intermediate placeholder is rejected; its
40
+ status alone is not proof that its arguments have been validated. A resumed
41
+ `framework_tools` continuation instead uses its previously saved dispatch
42
+ snapshot.
43
+
44
+ ## Retired conversion support
45
+
46
+ The pre-S3 `Persistence::Migration::InitialFormatMigration` API and the
47
+ GeneratorVerifier Result JSON converter are removed, along with the former
48
+ command's usage instructions. There is no compatibility alias or replacement
49
+ conversion command. Ordinary Agent and Workflow persistence, current Manifest
50
+ decoding and GeneratorVerifier Result validation remain in their owning domains.
51
+
52
+ For example, `GeneratorVerifier::Result.from_h` still requires `failure` even
53
+ when its value is null. It does not add missing fields to historical JSON.
54
+ The separate `PersistenceComposition::Unit4Migration` snapshot conversion is
55
+ retained and was not an implementation of either removed conversion facility.
@@ -91,8 +91,10 @@ an explicit items schema to restrict them.
91
91
  Storage SPI and SQL schemas are unchanged. New Tool batch metadata additionally
92
92
  records `validated_arguments`, separately from the unchanged raw request fields.
93
93
  Agent authorization projects and compares that exact snapshot (including explicit
94
- null in explicit schemas). Older snapshots without this field use the historical
95
- raw-argument/optional-nil-omission rule. Existing journal message boundaries,
94
+ null in explicit schemas). Authorization projection requires this validated
95
+ dispatch evidence; it does not infer approved values from raw request fields.
96
+ Provider-recovery placeholders are revalidated and replaced by the normal Tool
97
+ dispatch barrier before framework operations run. Existing journal message boundaries,
96
98
  Tool call identities and recorded usage remain readable. Legacy top-level
97
99
  thought_signature is decoded into opaque CallRequest metadata and rendered by
98
100
  the backend. Old SDK usage field spellings remain accepted by SavedContextReader.
@@ -107,4 +107,9 @@ The public class names below are unchanged. Their implementation files move:
107
107
  Use `require "phronomy"` and the public constants. Direct partial-load paths are
108
108
  not the public loading contract; no require shim is kept in the contract
109
109
  directories. Backend Contracts have no execution or implementation dependency.
110
- P4 Storage/ContentStore work remains pending.
110
+ P4 Storage/ContentStore work is implemented; see the
111
+ [Storage asynchronous execution guide](storage-async-client.md).
112
+ [ADR-062](../decisions/062-content-store-service.md) subsequently classified
113
+ ContentStore as a content service over Storage, rather than a physical backend.
114
+ The final P5 cross-repository/API/documentation review remains pending, as
115
+ recorded in [Backend responsibilities](../architecture/backend-groups.md).
@@ -102,8 +102,9 @@ argument to the default `read_store` Tool or a search method to that store.
102
102
  The public `Agent::Base.with_tools(definitions, id:, version:)` factory creates
103
103
  an Agent subclass with a replacement Tool map and an explicit definition
104
104
  identity. Agent owns preservation of its authoring settings; SharedState uses
105
- this public operation after composing the member and application Tools. It does
106
- not need to read Agent private settings.
105
+ this public operation after composing the member Tools with either its built-in
106
+ sharing Tools or the application's Tools. It does not need to read Agent private
107
+ settings.
107
108
 
108
109
  For example, inside the complete example's module, a provider can supply the
109
110
  entire Tool map for a derived researcher class:
@@ -131,6 +132,13 @@ The original class is unchanged. This explicit factory does not change general
131
132
  Agent subclass inheritance or define copying rules for application-specific
132
133
  class state.
133
134
 
135
+ The default findings-store mode now preserves these settings through the same
136
+ factory. For example, a member configured with `max_iterations 3` and
137
+ `temperature 0.25` keeps those settings when SharedState adds `read_store` and
138
+ `write_finding`. Member Tool aliases, the generated definition identity and the
139
+ default store/prompt behavior remain unchanged. This fixes the earlier default
140
+ derivation, which explicitly copied only the model setting.
141
+
134
142
  ## Application search and LLM input
135
143
 
136
144
  Application Tools own record fields and search conditions. ContextPolicy and the
@@ -151,8 +159,10 @@ explicitly through the existing appropriate contracts.
151
159
  SharedState continues to use the member's configured ContextPolicy. The binding
152
160
  does not automatically populate `before_llm_input` candidates, inspect Context
153
161
  internals or manage a provider message buffer. Example 22's adaptive reader is a
154
- separate application implementation; this extension alone does not migrate it
155
- or remove its existing private-API dependency.
162
+ separate application implementation. Its current version uses the public sharing
163
+ contract and Context budgeting APIs introduced in v0.33.0; its previous private
164
+ overrides have been removed. The application still owns adaptive retrieval and
165
+ budget allocation rather than delegating those policies to the sharing binding.
156
166
 
157
167
  ## Lifetime and verification
158
168
 
@@ -114,10 +114,6 @@ module Phronomy
114
114
  @callback_failure = nil
115
115
  end
116
116
 
117
- def streaming?
118
- @mode == :stream
119
- end
120
-
121
117
  def set_graph_metadata(phase: nil)
122
118
  @phase = phase
123
119
  end
@@ -83,9 +83,6 @@ module Phronomy
83
83
  return :current_request if segment.delivery.to_sym == :ask_argument
84
84
  return nil if CONTROL_CATEGORIES.include?(segment.category.to_sym)
85
85
  return :knowledge if segment.category.to_sym == :knowledge
86
- unit_kind = segment.metadata["selection_unit_kind"] ||
87
- segment.metadata[:selection_unit_kind]
88
- return :tool_exchanges if unit_kind.to_s == "tool_exchange"
89
86
 
90
87
  case segment.category.to_sym
91
88
  when :external_message, :assistant_message, :tool_message,
@@ -102,12 +99,6 @@ module Phronomy
102
99
  return "context-policy-conversation:#{conversation_group_id}"
103
100
  end
104
101
 
105
- # Compatibility for finalized pre-ACS-04 manifests. New manifests use
106
- # context_policy_conversation_group_id and do not recreate Phronomy::Context::Unit.
107
- unit_id = segment.metadata["selection_unit_id"] ||
108
- segment.metadata[:selection_unit_id]
109
- return "unit:#{unit_id}" if unit_id
110
-
111
102
  "segment:#{policy_category}:#{segment.position}"
112
103
  end
113
104
 
@@ -57,8 +57,8 @@ module Phronomy
57
57
  ATTRIBUTES.to_h { |name| [name.to_s, public_send(name)] }
58
58
  end
59
59
 
60
- # Historical durable fields are not accepted here. Explicit migration must
61
- # convert them to the current semantic payload first.
60
+ # Reads the current semantic payload only. Historical durable fields are
61
+ # rejected rather than converted.
62
62
  def self.from_h(hash)
63
63
  source = hash.to_h { |key, value| [key.to_s, value] }
64
64
  expected = ATTRIBUTES.map(&:to_s).sort
@@ -88,18 +88,6 @@ module Phronomy
88
88
  normalized.freeze
89
89
  end
90
90
 
91
- def subject_key(subject)
92
- normalized = normalize_subject(subject)
93
- case normalized.fetch(:type)
94
- when :llm_call
95
- "llm_call:#{normalized.fetch(:llm_call_id)}"
96
- when :tool_invocation
97
- "tool_invocation:#{normalized.fetch(:tool_invocation_id)}"
98
- when :persistence_operation
99
- "persistence_operation:#{normalized.fetch(:entity)}"
100
- end
101
- end
102
-
103
91
  def subject_equal?(left, right)
104
92
  normalize_subject(left) == normalize_subject(right)
105
93
  rescue ArgumentError, KeyError
@@ -48,6 +48,7 @@ module Phronomy
48
48
 
49
49
  # Validate the exact requested call and project its authorized batch in
50
50
  # Provider order from one execution snapshot in the caller's transaction.
51
+ # Only the validated dispatch snapshot is authorization evidence.
51
52
  # The receiving domain owns application and replay of these operations.
52
53
  def authorized_operations(scope, agent_id:, execution_id:, invocation_id:, name:, arguments:, names:)
53
54
  participate(scope) do |records|
@@ -58,7 +59,7 @@ module Phronomy
58
59
  batch = Array(execution.metadata[ExecutionMetadata::TOOL_BATCH_METADATA_KEY])
59
60
  requested = batch.find { |entry| entry.fetch("tool_invocation_id") == invocation_id }
60
61
  unless names.include?(name) && requested && requested.fetch("status") == "authorized" &&
61
- requested.fetch("tool_name") == name && authorized_argument_values(requested) == arguments
62
+ requested.fetch("tool_name") == name && requested.fetch("validated_arguments") == arguments
62
63
  raise Phronomy::Persistence::StateConflictError, "Operation #{invocation_id} is not the authorized call"
63
64
  end
64
65
  batch.filter_map do |entry|
@@ -66,7 +67,7 @@ module Phronomy
66
67
  AuthorizedOperation.new(
67
68
  invocation_id: Phronomy::Values::Immutable.copy(entry.fetch("tool_invocation_id")),
68
69
  name: Phronomy::Values::Immutable.copy(entry.fetch("tool_name")),
69
- arguments: Phronomy::Values::Immutable.copy(authorized_argument_values(entry))
70
+ arguments: Phronomy::Values::Immutable.copy(entry.fetch("validated_arguments"))
70
71
  )
71
72
  end.freeze
72
73
  end
@@ -286,12 +287,6 @@ module Phronomy
286
287
  Phronomy::Values::Immutable.json(contents.fetch_json(execution.result_ref)) : contents.fetch_text(execution.result_ref)
287
288
  end
288
289
 
289
- def authorized_argument_values(entry)
290
- # Unit 6 persists the exact validated snapshot. Older records encoded
291
- # legacy raw params, whose explicit optional nil meant omission.
292
- entry.key?("validated_arguments") ? entry.fetch("validated_arguments") : entry.fetch("arguments").compact
293
- end
294
-
295
290
  def with_scope(scope, &block)
296
291
  assert_observation_thread!
297
292
  scope ? participate(scope, &block) : transaction(&block)
@@ -345,9 +345,6 @@ module Phronomy
345
345
  display
346
346
  end
347
347
 
348
- def display_arguments = immutable_copy(approval_display.fetch(:arguments))
349
- def display_facts = immutable_copy(approval_display.fetch(:facts))
350
-
351
348
  private
352
349
 
353
350
  def restore_saved_state!(status, result)