Skip to content

Commit 3d500a4

Browse files
Wire 0087 within-node directive execution order (#225)
Ratify the conformance-adapter within-node directive execution-order rule: a node's sibling directives execute in fixture-document order. Python was already conformant. The fixture loader uses yaml.safe_load, which preserves mapping insertion order, and the metadata driver runs a node's directives in key order, so fixtures 043/045 already passed. Un-defer the dedicated pin fixture observability/135 onto the existing get_invocation_metadata driver, flip conformance.toml 0087 to implemented (since 0.17.0), and add a loader guard-comment pinning the safe_load order-preservation dependence. No src change.
1 parent 88bd721 commit 3d500a4

3 files changed

Lines changed: 19 additions & 9 deletions

File tree

conformance.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -846,10 +846,12 @@ note = "The SAVE-side enclosing_fan_out_lineage keying (pipeline-utilities §10.
846846
status = "not-yet"
847847

848848
# Spec v0.82.0 (proposal 0087). Conformance-adapter within-node
849-
# directive execution order (§8.3). Not-yet; observability fixture 135
850-
# defers with it.
849+
# directive execution order (§8.3). Implemented since 0.17.0;
850+
# observability fixture 135 pins it.
851851
[proposals."0087"]
852-
status = "not-yet"
852+
status = "implemented"
853+
since = "0.17.0"
854+
note = "Within-node directive execution order (conformance-adapter §8.3): a node's sibling directives execute in fixture-document order (mapping insertion order, not sorted-by-key). Python was already conformant -- the fixture loader uses yaml.safe_load, which preserves mapping insertion order, and the hand-built metadata driver (_apply_metadata_directives) iterates a node's directives in key order, so fixtures 043 / 045 (augment-then-capture vs capture-then-augment) already passed. This proposal ratifies that rule; the dedicated pin fixture observability/135 (the SAME two order-sensitive directives -- augment_metadata write + capture_invocation_metadata_into read -- in opposite document order across two cases, the captured snapshot diverging) is un-deferred and wired onto the existing metadata driver. No src change: the order-preserving load + key-order execution already satisfy §8.3, and a loader guard-comment pins the safe_load dependence per §8.2."
853855

854856
# Spec v0.83.0 (proposal 0088). Langfuse parallel-branches mapping
855857
# parity (observability §8.4.8). Not-yet; observability fixture 136

tests/conformance/harness/loader.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ def load_fixture(path: Path) -> Fixture:
6868
directives we haven't modelled yet.
6969
"""
7070
with path.open() as f:
71+
# yaml.safe_load preserves mapping insertion (document) order in
72+
# Python, so a node's sibling directives keep their fixture order.
73+
# Conformance-adapter §8.3 (proposal 0087) requires directives to
74+
# execute in document order, and observability/135 pins the
75+
# divergence -- do not swap in an order-losing loader.
7176
raw = yaml.safe_load(f)
7277
return _FIXTURE_ADAPTER.validate_python(raw)
7378

tests/conformance/test_observability.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ def _reset_otel_global_tracer_provider(restore_to: object) -> None:
100100
"044-get-invocation-metadata-fan-out-scoping",
101101
"045-get-invocation-metadata-retry-scoping",
102102
"046-get-invocation-metadata-outside-invocation",
103+
# proposal 0087 (within-node directive execution order, spec
104+
# v0.82.0). 135 places augment_metadata + capture_invocation_
105+
# metadata_into in opposite document order across two cases; the
106+
# captured snapshot diverges only if a node's sibling directives
107+
# run in fixture order. Reuses the 043/045 metadata driver, which
108+
# iterates node directives in key order -- see
109+
# _apply_metadata_directives.
110+
"135-within-node-directive-execution-order",
103111
"001-otel-basic-trace",
104112
"002-otel-subgraph-hierarchy",
105113
"003-otel-error-status",
@@ -384,12 +392,6 @@ def _reset_otel_global_tracer_provider(restore_to: object) -> None:
384392
"134-langfuse-nested-fan-out-parent-resolution",
385393
)
386394
},
387-
# Proposal 0087 (within-node directive execution order, spec v0.82.0).
388-
# The conformance-adapter document-order directive rule is unimplemented
389-
# until a later v0.16.0 PR.
390-
"135-within-node-directive-execution-order": (
391-
"within-node directive execution order (proposal 0087) not-yet implemented"
392-
),
393395
# Proposal 0088 (Langfuse parallel-branches mapping parity, spec
394396
# v0.83.0). The §8.4.8 per-branch dispatch-span Langfuse observation is
395397
# unimplemented until a later v0.16.0 PR.
@@ -735,6 +737,7 @@ async def test_observability_fixture(fixture_path: Path) -> None:
735737
"044-get-invocation-metadata-fan-out-scoping",
736738
"045-get-invocation-metadata-retry-scoping",
737739
"046-get-invocation-metadata-outside-invocation",
740+
"135-within-node-directive-execution-order",
738741
}:
739742
await _run_get_invocation_metadata_fixture(spec)
740743
else:

0 commit comments

Comments
 (0)