Maintain Observability Surfaces
Use this skill when changing event fields, exporter behavior, subscriber config,
or binding parity for ATIF or the full, gen_ai, and openinference
OpenTelemetry projections.
Surfaces To Keep In Sync
- Core event model and emitted fields
crates/core/src/observability/atif.rscrates/core/src/observability/otel.rscrates/core/src/observability/openinference.rs- FFI and binding-native wrappers where the config or lifecycle is exposed
- Python, Go, and Node.js config objects and subscriber/exporter methods
- Observability config version 3, where one
opentelemetrysection contains typed endpoints and OpenInference has no standalone public surface - Docs under
docs/about-nemo-relay/concepts/subscribers.mdxanddocs/configure-plugins/observability/
Design Checklist
- Is this an event-model change, exporter-config change, or lifecycle change?
- Do all bindings expose the same logical knobs and semantics?
- Does every OpenTelemetry endpoint require a type and nonblank destination?
- Does each endpoint resolve
header_envvalues at activation and reject missing, blank, or duplicate headers? - Do layered ATOF sink, ATIF storage, and OpenTelemetry endpoint lists concatenate with higher-precedence entries first?
- Are OpenTelemetry and OpenInference dependencies unconditional rather than Cargo feature-gated?
- Does
gen_aiavoidnemo_relay.*, project sanitized LLM instructions and messages into the standard content attributes, and emit minimal spans for scopes without GenAI semantics so their parentage is preserved? - Does
enable_full_payloadspreserve complete sanitized LLM request input and annotations while leaving credential removal and sanitizers active? - Does Relay derive compliant trace and span IDs consistently across typed OpenTelemetry endpoints while preserving lifecycle parentage?
- Are mark events, start/end events, and orphan cases still handled correctly?
- Does a sanitized tool result annotation remain opaque under
category_profile.tool_result_annotation, ATIF observation-resultextra.tool_result_annotation, and the singlenemo_relay.tool.result.annotationattribute infullandopeninference, whilegen_aiomits it? - Do examples and docs use each exporter's documented flush/deregister order before shutdown?
- Are span or trajectory fields still derived from the intended event data?
Validation
- Run the affected Rust crate tests plus
just test-rustif event fields changed. - Run only the binding suites whose exposed configuration, lifecycle, event, or exporter contract changed.
- Update and validate docs or examples when the public workflow, documented observability contract, or emitted output changed.
References
docs/about-nemo-relay/concepts/subscribers.mdxdocs/configure-plugins/observability/about.mdxdocs/configure-plugins/observability/opentelemetry.mdxcrates/core/src/observability/atif.rscrates/core/src/observability/otel.rscrates/core/src/observability/openinference.rs