Skip to content

Commit be2c502

Browse files
Add detached-trace invocation span (0061) (#168)
* Add detached-trace invocation span (0061) The OTel observer now synthesizes an openarmature.invocation span at the root of each detached trace (a detached subgraph and each detached fan-out instance), carrying the parent's shared invocation_id and the detached unit's own entry_node, with the detached subgraph/instance span nested beneath it. A raising detached subgraph surfaces ERROR plus the error category and an exception event on both the parent dispatch span and the detached invocation span. Observer-side only: no graph-engine change, and the Langfuse observer is unchanged. Pins the spec submodule to v0.61.0 and brings conformance fixtures 008 (rewritten) and 058 (newly covered) live. * Clear stale detached-error marker on span open errored_detached_keys gates the synthetic close paths' default set_status(OK) so a detached-trace ERROR survives export. The set is invocation-scoped but never cleared mid-invocation, so a detached prefix that errors and then re-runs successfully within the same invocation (cyclic or fire-and-forget re-entry) could leave the later success span UNSET instead of OK. Discard the key when a fresh detached invocation span opens at it (the only point keys are introduced), so each generation's close reflects only its own status. Reading the live span status was rejected as it depends on _Span.status, which is not part of the public OTel Span interface.
1 parent 9342e3a commit be2c502

10 files changed

Lines changed: 437 additions & 46 deletions

File tree

conformance.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,3 +687,10 @@ since = "0.14.0"
687687
status = "textual-only"
688688
since = "0.14.0"
689689
note = "Descriptive catalog of the failure-mock family (flaky + failure_sequence, flaky_by_index, flaky_per_index, flaky_instance_only, flaky_resume_aware) that the adapter already implements and the existing retry / failure-isolation / checkpoint-resume fixtures exercise; no new behavior, no new fixtures, no code change. Mirrors 0055's textual-only treatment of the conformance-adapter capability. The success-state naming drift (success_update / on_success / success_compute) is documented as-is by the proposal and left unchanged."
690+
691+
# Spec v0.61.0 (proposal 0061). Detached-trace invocation span
692+
# (observability §4.4 / §4.3 / §4.1 / §4.2 / §5.1).
693+
[proposals."0061"]
694+
status = "implemented"
695+
since = "0.15.0"
696+
note = "The OTel observer synthesizes an openarmature.invocation span at the root of each detached trace (a detached subgraph + each detached fan-out instance), carrying the parent's SHARED invocation_id (detached mode is observer-side trace rendering, not a new run) and the detached unit's own entry_node; the detached subgraph / instance span nests under it. A raising detached subgraph surfaces ERROR + the category + an OTel exception event on BOTH the parent dispatch span and the detached invocation span. Observer-side only -- no graph-engine change; the Langfuse observer is unchanged (its Trace entity already plays the invocation-level-container role). Fixtures 008 (rewritten) and 058 (newly wired) run in test_observability."

docs/concepts/observability.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,8 +644,11 @@ obs = OTelObserver(
644644
)
645645
```
646646

647-
A detached subgraph or fan-out gets a fresh trace root (new
648-
`trace_id`); the `correlation_id` still propagates through, so
647+
A detached subgraph or fan-out renders into a fresh trace, rooted in
648+
its own `openarmature.invocation` span that carries the same
649+
`invocation_id` as the parent (detached mode is an observer-side
650+
rendering choice, not a separate run). The new trace has a fresh
651+
`trace_id`, and the `correlation_id` still propagates through, so
649652
join semantics survive even when trace boundaries don't.
650653

651654
The non-detached default is what you want most of the time: one

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.60.0"
66+
spec_version = "0.61.0"
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.60.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.61.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.60.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.61.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._
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.60.0"
28+
__spec_version__ = "0.61.0"
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

0 commit comments

Comments
 (0)