Skip to content

Add concat_flatten + merge_all reducers; activate 0035/0036 fixtures#88

Merged
chris-colinsky merged 2 commits into
mainfrom
feature/proposals-0035-0036-reducers
May 28, 2026
Merged

Add concat_flatten + merge_all reducers; activate 0035/0036 fixtures#88
chris-colinsky merged 2 commits into
mainfrom
feature/proposals-0035-0036-reducers

Conversation

@chris-colinsky

Copy link
Copy Markdown
Member

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_all fan-out collection reducers).

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 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, registered in the conformance adapter.

No fan-out config-validation change needed — OA never restricted target_field to append (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/033 activated 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 (msg 04): fixture 031's outer_out step 2→3 per the §6 shared counter; fixture 033's detached-trace inner namespace → wrapper node name. The Option A subgraph_identity wiring already on main satisfies both — no impl change, just the un-defer + version bump.

Ported 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.

Other

  • Conformance adapter parses bare list / dict field 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 stay not-yet until the v0.10.0 release PR flips them 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 reframed from a custom-reducer workaround to the real built-ins.
  • __spec_version__ / pyproject / smoke test → 0.27.1.

Test plan

  • 12 new reducer unit tests (success + strict-raise paths for both reducers)
  • Conformance: 026-reducer-concat-flatten, 027-reducer-merge-all, Langfuse 031/032/033 all pass
  • Full suite — 937 passed, 130 skipped
  • ruff check / ruff format --check clean
  • pyright clean
  • scripts/check_conformance_manifest.py — 32/32 consistent
  • tests/test_smoke.py — spec_version consistency (init / pyproject / submodule changelog) green

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.
Copilot AI review requested due to automatic review settings May 28, 2026 04:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_flatten and merge_all reducers, 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.

Comment thread docs/agent/non-obvious-shapes.md
Comment thread src/openarmature/AGENTS.md
Comment thread docs/agent/non-obvious-shapes.md
Comment thread src/openarmature/AGENTS.md
Comment thread docs/agent/non-obvious-shapes.md Outdated
Comment thread src/openarmature/AGENTS.md Outdated
- 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 chris-colinsky merged commit b4f54b6 into main May 28, 2026
6 checks passed
@chris-colinsky chris-colinsky deleted the feature/proposals-0035-0036-reducers branch May 28, 2026 04:20
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants