Skip to content

Commit 418fec4

Browse files
Pin spec v0.70.1; wire 110, defer rerank fixtures
Advance the spec pin v0.69.0 -> v0.70.1 (submodule + the four sync points). v0.70.0 adds proposal 0060 (rerank); v0.70.1 adds observability fixture 110. Wire fixture 110 (proposal 0075 callable-branch span shape) via a new _run_fixture_110 runner. This is the ORIGINAL fixture (span shape + skip-emits-no-span); the branch_count assertion arrives at v0.16.0 with the v0.73.1 pin. Mark 0060 not-yet (rerank is unimplemented until v0.16.0) and defer the 11 rerank observability fixtures (099-109) in both the coverage guard's accounting and the cross-capability fixture parser. Fixture 110 also defers in the parser (it mixes a graph final_state with the span_tree). Regenerate the bundled AGENTS.md for the new pin. No version/CHANGELOG change; both land at the v0.15.0 release.
1 parent d29c6b9 commit 418fec4

8 files changed

Lines changed: 131 additions & 7 deletions

File tree

conformance.toml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
[manifest]
3434
implementation = "openarmature-python"
35-
spec_pin = "v0.69.0"
35+
spec_pin = "v0.70.1"
3636

3737
# Status values:
3838
# implemented — shipped behavior matches the proposal's contract
@@ -610,6 +610,16 @@ since = "0.13.0"
610610
[proposals."0059"]
611611
status = "not-yet"
612612

613+
# Spec v0.70.0 (proposal 0060). Retrieval-provider rerank protocol — the
614+
# ``RerankProvider`` surface + ``RerankEvent`` / ``RerankFailedEvent`` typed
615+
# variants + OTel ``openarmature.rerank.complete`` span / Langfuse Retriever
616+
# observation / rerank metrics. Sibling to the embedding surface (0059);
617+
# python has not shipped retrieval-provider, so rerank is not-yet. Crossed by
618+
# the v0.70.1 pin (adopted for fixture 110 / 0075); the 11 rerank observability
619+
# fixtures (099-109) defer with it.
620+
[proposals."0060"]
621+
status = "not-yet"
622+
613623
# Spec v0.55.0 (proposal 0065; repo pins v0.55.1). Failure-isolation
614624
# cause fidelity at non-node placements (pipeline-utilities §6.3 /
615625
# §11.7). At instance (§9.7), branch (§11.7), and parent-node

openarmature-spec

Submodule openarmature-spec updated 50 files

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Specification = "https://github.com/LunarCommand/openarmature-spec"
6363
openarmature = "openarmature.cli:main"
6464

6565
[tool.openarmature]
66-
spec_version = "0.69.0"
66+
spec_version = "0.70.1"
6767

6868
[dependency-groups]
6969
dev = [

src/openarmature/AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# OpenArmature — Agent documentation
22

3-
*This is the agent guide bundled with the openarmature Python package, version 0.14.0 (spec v0.69.0). For the full docs site see [openarmature.ai](https://openarmature.ai). For the canonical spec text see [openarmature.org/capabilities](https://openarmature.org/capabilities/). For project-specific conventions for the code you're editing, see the host project's `AGENTS.md` or `CLAUDE.md`.*
3+
*This is the agent guide bundled with the openarmature Python package, version 0.14.0 (spec v0.70.1). For the full docs site see [openarmature.ai](https://openarmature.ai). For the canonical spec text see [openarmature.org/capabilities](https://openarmature.org/capabilities/). For project-specific conventions for the code you're editing, see the host project's `AGENTS.md` or `CLAUDE.md`.*
44

55
## TL;DR
66

@@ -10,7 +10,7 @@ OpenArmature is a workflow framework for LLM pipelines and tool-calling agents:
1010

1111
## Capability contracts
1212

13-
_Sourced from openarmature-spec v0.69.0. Each entry below reproduces §1 (Purpose) and §2 (Concepts) of the capability's `spec.md` verbatim — including additions from accepted proposals that this Python implementation may not yet ship. For per-proposal implementation status (implemented / partial / textual-only / not-yet), see the `conformance.toml` manifest at the repo root. For the full spec text (execution model, error semantics, determinism, observer hooks, etc.) see the linked docs site._
13+
_Sourced from openarmature-spec v0.70.1. Each entry below reproduces §1 (Purpose) and §2 (Concepts) of the capability's `spec.md` verbatim — including additions from accepted proposals that this Python implementation may not yet ship. For per-proposal implementation status (implemented / partial / textual-only / not-yet), see the `conformance.toml` manifest at the repo root. For the full spec text (execution model, error semantics, determinism, observer hooks, etc.) see the linked docs site._
1414

1515
### Capability: `graph-engine`
1616

src/openarmature/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"""
2626

2727
__version__ = "0.14.0"
28-
__spec_version__ = "0.69.0"
28+
__spec_version__ = "0.70.1"
2929
# Proposal 0052 (spec observability §5.1 / §8.4.1): canonical
3030
# package-registry name for this implementation. Surfaces on every
3131
# OTel invocation span as ``openarmature.implementation.name`` and on

tests/conformance/test_fixture_parsing.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,40 @@ def _id(case: tuple[str, Path]) -> str:
523523
),
524524
"observability/082-otel-embedding-span-attributes": "Proposal 0059 embedding events; not implemented",
525525
"observability/083-langfuse-embedding-observation": "Proposal 0059 embedding events; not implemented",
526+
# Proposal 0060 (retrieval-provider rerank, v0.70.0): the rerank
527+
# observability fixtures (099-109) model the RerankEvent /
528+
# RerankFailedEvent + rerank span / Langfuse Retriever / rerank-metrics
529+
# surface, which python does not implement (0060 is not-yet; rerank lands
530+
# with the embedding capability in v0.16.0). Sibling to embeddings (074-083).
531+
"observability/099-rerank-event-dispatch": "Proposal 0060 rerank events; not implemented",
532+
"observability/100-rerank-failure-event-dispatch-on-provider-unavailable": (
533+
"Proposal 0060 rerank events; not implemented"
534+
),
535+
"observability/101-rerank-event-mutual-exclusion": "Proposal 0060 rerank events; not implemented",
536+
"observability/102-rerank-event-call-id-distinct": "Proposal 0060 rerank events; not implemented",
537+
"observability/103-rerank-event-query-and-documents-populated": (
538+
"Proposal 0060 rerank events; not implemented"
539+
),
540+
"observability/104-rerank-event-request-params-populated": (
541+
"Proposal 0060 rerank events; not implemented"
542+
),
543+
"observability/105-rerank-event-top-k-and-result-count-populated": (
544+
"Proposal 0060 rerank events; not implemented"
545+
),
546+
"observability/106-rerank-event-active-prompt-populated": (
547+
"Proposal 0060 rerank events; not implemented"
548+
),
549+
"observability/107-otel-rerank-span-attributes": "Proposal 0060 rerank events; not implemented",
550+
"observability/108-langfuse-rerank-observation": "Proposal 0060 rerank events; not implemented",
551+
"observability/109-rerank-metrics-token-and-duration": "Proposal 0060 rerank events; not implemented",
552+
# Proposal 0075 (callable-branch span, fixture 110 added v0.70.1): the case
553+
# mixes a graph-style ``expected.final_state`` with the observability
554+
# ``span_tree``; the cross-capability parser's ObservabilityExpected model
555+
# forbids final_state. RUNS via _run_fixture_110 in test_observability (the
556+
# same defer-from-parse-but-runs pattern as fixture 038).
557+
"observability/110-otel-callable-branch-span": (
558+
"Cross-capability parser doesn't model final_state + span_tree together; runs in test_observability"
559+
),
526560
}
527561

528562

tests/conformance/test_observability.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ def _reset_otel_global_tracer_provider(restore_to: object) -> None:
185185
"096-tool-call-payload-gating",
186186
"097-otel-tool-span-attributes",
187187
"098-langfuse-tool-observation",
188+
# v0.70.1 — proposal 0075 callable-branch span shape (observability
189+
# §5.7). The ORIGINAL fixture 110 (span shape + skip-emits-no-span);
190+
# the branch_count assertion arrives with the v0.73.1 pin (v0.16.0).
191+
"110-otel-callable-branch-span",
188192
}
189193
)
190194

@@ -194,6 +198,10 @@ def _reset_otel_global_tracer_provider(restore_to: object) -> None:
194198
"no embedding event/provider to record from"
195199
)
196200

201+
_RERANK_DEFER = (
202+
"rerank capability (proposal 0060) unimplemented until v0.16.0; no rerank event/provider to record from"
203+
)
204+
197205

198206
# Pinned observability fixtures NOT run by this YAML harness, each with an
199207
# explicit reason. The coverage guard (test_observability_fixture_coverage_
@@ -228,6 +236,24 @@ def _reset_otel_global_tracer_provider(restore_to: object) -> None:
228236
"089-embedding-metrics-token-and-duration",
229237
)
230238
},
239+
# Rerank observability (proposal 0060, v0.70.0). The rerank protocol is
240+
# unshipped in python until v0.16.0; no rerank provider/event exists.
241+
**{
242+
fixture_id: _RERANK_DEFER
243+
for fixture_id in (
244+
"099-rerank-event-dispatch",
245+
"100-rerank-failure-event-dispatch-on-provider-unavailable",
246+
"101-rerank-event-mutual-exclusion",
247+
"102-rerank-event-call-id-distinct",
248+
"103-rerank-event-query-and-documents-populated",
249+
"104-rerank-event-request-params-populated",
250+
"105-rerank-event-top-k-and-result-count-populated",
251+
"106-rerank-event-active-prompt-populated",
252+
"107-otel-rerank-span-attributes",
253+
"108-langfuse-rerank-observation",
254+
"109-rerank-metrics-token-and-duration",
255+
)
256+
},
231257
}
232258

233259

@@ -429,6 +455,8 @@ async def test_observability_fixture(fixture_path: Path) -> None:
429455
await _run_fixture_028(spec)
430456
elif fixture_id == "038-otel-parallel-branches-dispatch-span":
431457
await _run_fixture_038(spec)
458+
elif fixture_id == "110-otel-callable-branch-span":
459+
await _run_fixture_110(spec)
432460
elif fixture_id in {
433461
"040-llm-cache-attribute-emission",
434462
"041-llm-cache-attribute-absence",
@@ -1923,6 +1951,58 @@ def _matches(span: Any, eattrs: dict[str, Any] = expected_attrs) -> bool:
19231951
_assert_span_tree_matches(all_spans, actual_children, expected_children)
19241952

19251953

1954+
async def _run_fixture_110(spec: Mapping[str, Any]) -> None:
1955+
# Proposal 0075 callable-branch span shape (observability §5.7): an
1956+
# inline-callable parallel branch renders as ONE per-branch dispatch span
1957+
# keyed by openarmature.node.branch_name with NO inner-node spans; a
1958+
# when-skipped branch emits no span. Bundled OTel observer (default config),
1959+
# as for fixtures 038 / 082.
1960+
for case in cast("list[dict[str, Any]]", spec["cases"]):
1961+
case_name = cast("str", case["name"])
1962+
try:
1963+
await _run_fixture_110_case(case)
1964+
except AssertionError as e:
1965+
raise AssertionError(f"case {case_name!r}: {e}") from e
1966+
1967+
1968+
async def _run_fixture_110_case(case: Mapping[str, Any]) -> None:
1969+
observer, exporter = _build_observer()
1970+
final = await _run_graph(case, observer)
1971+
observer.shutdown()
1972+
1973+
# ---- final_state: the dispatched callable branches applied their
1974+
# updates; the when-skipped branch contributed nothing.
1975+
expected_final = cast("dict[str, Any]", case["expected"].get("final_state") or {})
1976+
for field_name, expected_value in expected_final.items():
1977+
actual = getattr(final, field_name)
1978+
assert actual == expected_value, f"final_state.{field_name}: {actual!r} != {expected_value!r}"
1979+
1980+
spans = exporter.get_finished_spans()
1981+
expected_tree = cast("list[dict[str, Any]]", case["expected"]["span_tree"])
1982+
inv_root = next(s for s in spans if s.name == "openarmature.invocation" and s.parent is None)
1983+
_assert_span_tree_matches(spans, [inv_root], expected_tree)
1984+
1985+
# ---- when-skipped branches emit NO span. The span_tree match is
1986+
# subset-based, so assert the skip explicitly: any declared branch absent
1987+
# from the (dispatched) span_tree must have produced no span.
1988+
def _names(nodes: list[dict[str, Any]]) -> set[str]:
1989+
out: set[str] = set()
1990+
for n in nodes:
1991+
out.add(cast("str", n["name"]))
1992+
out |= _names(cast("list[dict[str, Any]]", n.get("children") or []))
1993+
return out
1994+
1995+
dispatched = _names(expected_tree)
1996+
nodes = cast("dict[str, Any]", case["nodes"])
1997+
pb_node = next((ns for ns in nodes.values() if "parallel_branches" in ns), None)
1998+
if pb_node is not None:
1999+
declared = set(cast("dict[str, Any]", pb_node["parallel_branches"]["branches"]).keys())
2000+
for branch in declared - dispatched:
2001+
assert [s for s in spans if s.name == branch] == [], (
2002+
f"when-skipped branch {branch!r} MUST emit no span"
2003+
)
2004+
2005+
19262006
async def _run_fixture_008(spec: Mapping[str, Any]) -> None:
19272007
"""Two sub-cases: detached subgraph (one Link, two traces, shared
19282008
correlation_id) and detached fan-out (one trace per instance,

tests/test_smoke.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
def test_package_versions() -> None:
1111
assert openarmature.__version__ == "0.14.0"
12-
assert openarmature.__spec_version__ == "0.69.0"
12+
assert openarmature.__spec_version__ == "0.70.1"
1313

1414

1515
def test_spec_version_matches_pyproject() -> None:

0 commit comments

Comments
 (0)