Skip to content

Commit 254dce1

Browse files
Bump spec pin to v0.31.0 + 0039/0041 fixtures (#95)
* 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.
1 parent e2abe86 commit 254dce1

9 files changed

Lines changed: 129 additions & 15 deletions

File tree

conformance.toml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,17 @@
2222
# between pinned-spec and spec-head is the consumer's job (e.g., the
2323
# spec docs site computes the difference and renders accordingly).
2424
#
25-
# Convention: this file is only updated as part of release PRs. Between
26-
# releases, the manifest reflects the most-recently-published version
27-
# so external readers never see a `since` referring to an unreleased
28-
# pre-tag commit.
25+
# Convention: this file is updated as part of release PRs AND as part
26+
# of feature PRs that bump the spec submodule pin (the manifest guard
27+
# requires entries for every Accepted proposal in the pinned spec, so
28+
# a submodule bump forces this file to update too). Such bump PRs set
29+
# `since` to the upcoming release version; between the bump PR and the
30+
# matching tag, external readers will see a `since` referring to the
31+
# upcoming, unreleased version.
2932

3033
[manifest]
3134
implementation = "openarmature-python"
32-
spec_pin = "v0.27.1"
35+
spec_pin = "v0.31.0"
3336

3437
# Status values:
3538
# implemented — shipped behavior matches the proposal's contract
@@ -175,3 +178,19 @@ since = "0.10.0"
175178
[proposals."0036"]
176179
status = "implemented"
177180
since = "0.10.0"
181+
182+
# Spec v0.28.0-v0.31.0 (proposals 0037, 0039, 0040, 0041). 0038
183+
# (Gemini) is mid-accept on spec side and not in v0.31.0 yet.
184+
[proposals."0037"]
185+
status = "not-yet"
186+
187+
[proposals."0039"]
188+
status = "implemented"
189+
since = "0.11.0"
190+
191+
[proposals."0040"]
192+
status = "not-yet"
193+
194+
[proposals."0041"]
195+
status = "implemented"
196+
since = "0.11.0"

openarmature-spec

Submodule openarmature-spec updated 56 files

pyproject.toml

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

6060
[tool.openarmature]
61-
spec_version = "0.27.1"
61+
spec_version = "0.31.0"
6262

6363
[dependency-groups]
6464
dev = [

src/openarmature/AGENTS.md

Lines changed: 5 additions & 4 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.10.0 (spec v0.27.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`.*
3+
*This is the agent guide bundled with the openarmature Python package, version 0.10.0 (spec v0.31.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`.*
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.27.1. Each entry below reproduces §1 (Purpose) and §2 (Concepts) of the capability's `spec.md`. For the full spec text (execution model, error semantics, determinism, observer hooks, etc.) see the linked docs site._
13+
_Sourced from openarmature-spec v0.31.0. Each entry below reproduces §1 (Purpose) and §2 (Concepts) of the capability's `spec.md`. For the full spec text (execution model, error semantics, determinism, observer hooks, etc.) see the linked docs site._
1414

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

@@ -327,8 +327,9 @@ parent invocation's trace as nested spans. Implementations MUST also support an
327327
its own trace and the parent's dispatch span carries an OTel `Link` to that new trace.
328328

329329
**Correlation ID.** A per-invocation identifier that flows across observability backends.
330-
Distinct from `invocation_id` — the framework-generated `invocation_id` correlates spans within
331-
a single backend, while `correlation_id` is application-supplied (or auto-generated when absent)
330+
Distinct from `invocation_id` — the `invocation_id` (caller-supplied or framework-generated, per
331+
§5.1) correlates spans within a single backend, while `correlation_id` is application-supplied
332+
(or auto-generated when absent)
332333
and is intended to be visible in every backend the implementation emits to. A user running an
333334
LLM workflow with both an OTel backend (system traces, logs) and a Langfuse backend
334335
(LLM-specific traces) uses the `correlation_id` as a join key between them: find a slow request

src/openarmature/__init__.py

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

2727
__version__ = "0.10.0"
28-
__spec_version__ = "0.27.1"
28+
__spec_version__ = "0.31.0"

tests/conformance/test_fixture_parsing.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,61 @@ def _id(case: tuple[str, Path]) -> str:
115115
"prompt-management/016-prompt-observability-entities-propagation": (
116116
"Cases shape models live in the PM-specific capability harness"
117117
),
118+
# Proposal 0037 (Anthropic Messages mapping) shipped in spec v0.28.0
119+
# but python marks it not-yet in conformance.toml — the Anthropic
120+
# provider isn't implemented in this release. Defer the
121+
# cross-capability parse tests for the 033-042 fixtures until that
122+
# lands; the openai-strips-thinking-blocks side (043) is in
123+
# test_llm_provider.py's own deferral.
124+
"llm-provider/033-anthropic-basic-message-round-trip": (
125+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
126+
),
127+
"llm-provider/034-anthropic-tool-call-flow": (
128+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
129+
),
130+
"llm-provider/035-anthropic-image-content-blocks": (
131+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
132+
),
133+
"llm-provider/036-anthropic-tool-choice-modes": (
134+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
135+
),
136+
"llm-provider/037-anthropic-runtime-config-mapping": (
137+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
138+
),
139+
"llm-provider/038-anthropic-max-tokens-required": (
140+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
141+
),
142+
"llm-provider/039-anthropic-error-mapping": (
143+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
144+
),
145+
"llm-provider/040-anthropic-structured-output-native": (
146+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
147+
),
148+
"llm-provider/041-anthropic-structured-output-fallback": (
149+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
150+
),
151+
"llm-provider/042-anthropic-thinking-block-round-trip": (
152+
"Anthropic provider not implemented (0037 not-yet in conformance.toml)"
153+
),
154+
# Proposal 0040 (open-span metadata update) — task #22 implements
155+
# the §6 augmentation-event mechanism + un-defers 029/030 + 034.
156+
"observability/034-caller-metadata-open-span-update-serial": (
157+
"Open-span augmentation-event mechanism lands with #22 (0040 not-yet)"
158+
),
159+
# Proposal 0039 (caller-supplied invocation_id) Langfuse trace.id
160+
# derivation fixtures use the langfuse_trace expected shape the
161+
# cross-capability parser doesn't model. The derivation itself is
162+
# pinned by unit tests in test_observability_langfuse_adapter.py
163+
# against the same spec vector fixture 036 uses
164+
# (sha256("run_abc123")[:16].hex == 29b50a6c08dabfeaeb1696301f4fabe1);
165+
# wiring into the langfuse-specific conformance harness is a
166+
# follow-up.
167+
"observability/035-caller-invocation-id-uuid": (
168+
"Cross-capability parser doesn't model langfuse_trace; derivation pinned by unit tests"
169+
),
170+
"observability/036-caller-invocation-id-non-uuid": (
171+
"Cross-capability parser doesn't model langfuse_trace; derivation pinned by unit tests"
172+
),
118173
}
119174

120175

tests/conformance/test_llm_provider.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,23 @@
6565
# Skip-marked here so a green test run at this commit means "everything we
6666
# claim to implement passes." Each subsequent PR drops its own rows as it
6767
# lands the underlying support.
68-
_DEFERRED_FIXTURES: dict[str, str] = {}
68+
_DEFERRED_FIXTURES: dict[str, str] = {
69+
# Proposal 0037 (Anthropic Messages mapping) shipped in spec v0.28.0
70+
# but python marks it not-yet in conformance.toml — the Anthropic
71+
# provider isn't implemented in this release. 043 (the OpenAI side
72+
# stripping anthropic thinking-block content) waits with it.
73+
"033-anthropic-basic-message-round-trip": "Anthropic provider not implemented (0037 not-yet)",
74+
"034-anthropic-tool-call-flow": "Anthropic provider not implemented (0037 not-yet)",
75+
"035-anthropic-image-content-blocks": "Anthropic provider not implemented (0037 not-yet)",
76+
"036-anthropic-tool-choice-modes": "Anthropic provider not implemented (0037 not-yet)",
77+
"037-anthropic-runtime-config-mapping": "Anthropic provider not implemented (0037 not-yet)",
78+
"038-anthropic-max-tokens-required": "Anthropic provider not implemented (0037 not-yet)",
79+
"039-anthropic-error-mapping": "Anthropic provider not implemented (0037 not-yet)",
80+
"040-anthropic-structured-output-native": "Anthropic provider not implemented (0037 not-yet)",
81+
"041-anthropic-structured-output-fallback": "Anthropic provider not implemented (0037 not-yet)",
82+
"042-anthropic-thinking-block-round-trip": "Anthropic provider not implemented (0037 not-yet)",
83+
"043-openai-strips-thinking-blocks": "Anthropic provider not implemented (0037 not-yet)",
84+
}
6985

7086

7187
def _fixture_paths() -> list[Path]:

tests/conformance/test_observability.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,25 @@ async def _run_fixture_028(spec: Mapping[str, Any]) -> None:
884884
cases = cast("list[dict[str, Any]]", spec["cases"])
885885
for case in cases:
886886
case_name = cast("str", case["name"])
887+
# Cases using the `augment_metadata` directive exercise §3.4
888+
# mid-invocation rejection at set_invocation_metadata. The
889+
# augment_metadata harness primitive (per fixture 034) lands
890+
# with proposal 0040 / task #22; surface the deferral via
891+
# warnings.warn so pytest's end-of-run summary lists it (rather
892+
# than silently passing) and continue to the other cases.
893+
nodes_check = cast("dict[str, Any]", case.get("nodes", {}))
894+
if any(
895+
isinstance(n, dict) and "augment_metadata" in cast("dict[str, Any]", n)
896+
for n in nodes_check.values()
897+
):
898+
import warnings # noqa: PLC0415
899+
900+
warnings.warn(
901+
f"028 case {case_name!r} deferred: augment_metadata harness primitive "
902+
f"lands with proposal 0040 / #22",
903+
stacklevel=2,
904+
)
905+
continue
887906
try:
888907
# Build a minimal graph from the case's nodes/edges. The
889908
# fixture's node is a noop update — we never expect it to
@@ -921,7 +940,11 @@ async def _body(_s: Any) -> dict[str, Any]:
921940

922941
caller_metadata = cast("dict[str, Any]", case["caller_metadata"])
923942
try:
924-
with pytest.raises(ValueError, match="reserved namespace prefix"):
943+
# Covers both rejection paths: the prefix-namespace
944+
# rejection (openarmature.* / gen_ai.*, from 0034) and
945+
# the exact-key-name rejection (0041's §8.4 reserved
946+
# set). Both error messages contain "reserved".
947+
with pytest.raises(ValueError, match="reserved"):
925948
await graph.invoke(state_cls(), metadata=caller_metadata)
926949
finally:
927950
otel_observer.shutdown()

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.10.0"
12-
assert openarmature.__spec_version__ == "0.27.1"
12+
assert openarmature.__spec_version__ == "0.31.0"
1313

1414

1515
def test_spec_version_matches_pyproject() -> None:

0 commit comments

Comments
 (0)