Add concat_flatten + merge_all reducers; activate 0035/0036 fixtures#88
Merged
Merged
Conversation
Bumps the spec submodule v0.26.1 → v0.27.1 and lands the remaining two proposals of the v0.10.0 batch. Proposal 0036 (fan-out collection reducers): - concat_flatten — the list-of-lists analog of append. A fan-out subgraph emitting list[X] per instance lands list[list[X]] at the parent target_field; this reducer flattens one level onto prior. - merge_all — the list-of-mappings analog of merge. A fan-out subgraph emitting dict[str, X] per instance lands list[dict]; this reducer folds the sequence into prior with shallow last-write-wins per key. Both are strict like their single-level counterparts: they raise TypeError on a bad update-element shape, which the engine wraps as ReducerError per graph-engine §4. Exported from openarmature.graph and registered in the conformance adapter's REDUCERS map. No fan-out config-validation change was needed — OA never restricted target_field to append (it only checks field declaration). Proposal 0035 (Langfuse graph-topology fixtures): - Un-defers 031/032/033 in the Langfuse conformance harness. Spec v0.27.1 patched the two fixture-vs-impl ambiguities raised in the clarify-subgraph-name-semantics coord thread (fixture 031's outer_out step 2 → 3 per the §6 shared counter; fixture 033's detached-trace inner namespace → the wrapper node name). The Option A subgraph_identity wiring already on main satisfies both. - Ports the OTel harness's _patch_unsupported_directives into the Langfuse harness so the topology fixtures' update_pure_from_state inner nodes (computed values the structural assertions don't inspect) run as no-ops. Conformance adapter: parse bare `list` / `dict` field types (the 0036 fixtures use unconstrained container types so the reducer, not the typed-state layer, is the gatekeeper for the list-of-lists / list-of-mappings shape). conformance.toml: spec_pin → v0.27.1, [proposals."0036"] added. All of 0031-0036 stay not-yet until the v0.10.0 release PR flips them to implemented since = 0.10.0 together. Docs: state-and-reducers + fan-out concept pages document the five built-in reducers and the per-instance collection-shape recipe; the AGENTS.md non-obvious-shape note is reframed from a custom- reducer workaround to the now-real built-ins. 12 new reducer unit tests (success + strict-raise paths for both). 937 passed, 130 skipped; lint / format / pyright / manifest clean.
There was a problem hiding this comment.
Pull request overview
Adds proposal 0036 fan-out collection reducers and updates conformance/spec metadata to v0.27.1, while activating Langfuse topology fixtures from proposal 0035.
Changes:
- Adds
concat_flattenandmerge_allreducers, exports them, and covers them with reducer unit tests. - Updates conformance adapter/version pins and enables Langfuse topology fixtures with fixture patching.
- Updates user-facing docs and bundled agent guide for the new reducer patterns.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/openarmature/graph/reducers.py |
Implements the two new built-in reducers. |
src/openarmature/graph/__init__.py |
Exports the new reducers from the public graph API. |
tests/unit/test_state_and_reducers.py |
Adds reducer success and strict-error tests. |
tests/conformance/adapter.py |
Registers new reducers and parses bare list/dict fixture types. |
tests/conformance/test_observability_langfuse.py |
Activates Langfuse topology fixtures and patches unsupported directives. |
src/openarmature/__init__.py |
Bumps package spec version metadata. |
tests/test_smoke.py |
Updates smoke assertion for the new spec version. |
pyproject.toml |
Updates OpenArmature spec metadata. |
conformance.toml |
Pins conformance to v0.27.1 and adds proposal 0036. |
docs/concepts/state-and-reducers.md |
Documents five built-in reducers. |
docs/concepts/fan-out.md |
Documents reducer selection for fan-out collection shapes. |
docs/agent/non-obvious-shapes.md |
Updates agent docs to recommend built-in reducers. |
src/openarmature/AGENTS.md |
Updates bundled agent guide with new spec version and reducer guidance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- concat_flatten / merge_all doc snippets: add the missing `from typing import Annotated` / `from pydantic import Field` imports so each recipe is self-contained. - Reword the per-instance collection-shape sentence: a mapping per-instance value lands list[dict] (merge_all), not list[list[X]] — name the two non-flat shapes separately instead of lumping the mapping case under "list-of-lists". AGENTS.md regenerated from docs/agent/non-obvious-shapes.md.
chris-colinsky
added a commit
that referenced
this pull request
May 29, 2026
From PR #95 review: - Rewrite the conformance.toml convention block to acknowledge that feature PRs which bump the spec submodule pin update this file too, setting `since` to the upcoming release version (matches the v0.10.0 cycle's pattern in PR #85 / #88, and how this PR works). - Emit warnings.warn for 028's deferred augment_metadata case so pytest's end-of-run summary surfaces the deferred coverage by name rather than silently passing.
chris-colinsky
added a commit
that referenced
this pull request
May 29, 2026
* Bump spec pin to v0.31.0 + 0039/0041 fixtures Bumps the spec submodule from v0.27.1 to v0.31.0 (proposals 0037 Anthropic, 0039 caller invocation_id, 0040 open-span, 0041 reserved keys) and wires conformance to python's current state for v0.11.0. conformance.toml: spec_pin to v0.31.0 + entries for 0037 / 0039 / 0040 / 0041. 0039 and 0041 are implemented since 0.11.0; 0037 and 0040 stay not-yet (Anthropic provider + #22 open-span are out of scope for this PR). __spec_version__ in src and pyproject likewise bumps; AGENTS.md regenerated. Conformance harness updates: defer Anthropic fixtures (llm-provider/ 033-043) in both the cross-capability parser and the llm-provider runner; defer observability/034 (waits on #22); defer observability/ 035-036 from the cross-capability parser (the langfuse_trace shape isn't modeled; the derivation is pinned by unit tests against the same vector). The _run_fixture_028 runner recognises both the 0034 prefix-rejection and 0041 exact-name rejection patterns; the mid-invocation augment_metadata case waits on #22's harness primitive. Full suite green: 962 passed, 170 skipped. * Align conformance.toml note + visible 028 skip From PR #95 review: - Rewrite the conformance.toml convention block to acknowledge that feature PRs which bump the spec submodule pin update this file too, setting `since` to the upcoming release version (matches the v0.10.0 cycle's pattern in PR #85 / #88, and how this PR works). - Emit warnings.warn for 028's deferred augment_metadata case so pytest's end-of-run summary surfaces the deferred coverage by name rather than silently passing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Bumps the spec submodule v0.26.1 → v0.27.1 and lands the last two proposals of the v0.10.0 batch: 0035 (Langfuse graph-topology fixtures, un-deferred) and 0036 (the
concat_flatten+merge_allfan-out collection reducers).Proposal 0036 — fan-out collection reducers
concat_flatten— the list-of-lists analog ofappend. A fan-out subgraph emittinglist[X]per instance landslist[list[X]]at the parenttarget_field; this reducer flattens one level onto prior.merge_all— the list-of-mappings analog ofmerge. A fan-out subgraph emittingdict[str, X]per instance landslist[dict]; this reducer folds the sequence into prior with shallow last-write-wins per key.Both strict like their single-level counterparts — they raise
TypeErroron a bad update-element shape, which the engine wraps asReducerErrorper graph-engine §4. Exported fromopenarmature.graph, registered in the conformance adapter.No fan-out config-validation change needed — OA never restricted
target_fieldtoappend(it only checks field declaration), so the spec's "relax your validation" caveat doesn't apply.Proposal 0035 — Langfuse graph-topology fixtures un-deferred
031/032/033activated in the Langfuse conformance harness. Spec v0.27.1 patched the two fixture-vs-impl ambiguities raised in theclarify-subgraph-name-semanticscoord thread (msg 04): fixture 031'souter_outstep 2→3 per the §6 shared counter; fixture 033's detached-trace inner namespace → wrapper node name. The Option Asubgraph_identitywiring already on main satisfies both — no impl change, just the un-defer + version bump.Ported the OTel harness's
_patch_unsupported_directivesinto the Langfuse harness so the topology fixtures'update_pure_from_stateinner nodes (computed values the structural assertions don't inspect) run as no-ops.Other
list/dictfield types (the 0036 fixtures use unconstrained container types so the reducer, not the typed-state layer, is the shape gatekeeper).conformance.toml: spec_pin → v0.27.1,[proposals."0036"]added. All of 0031-0036 staynot-yetuntil the v0.10.0 release PR flips them together.__spec_version__/pyproject/ smoke test → 0.27.1.Test plan
026-reducer-concat-flatten,027-reducer-merge-all, Langfuse031/032/033all passruff check/ruff format --checkcleanpyrightcleanscripts/check_conformance_manifest.py— 32/32 consistenttests/test_smoke.py— spec_version consistency (init / pyproject / submodule changelog) green