This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
devopscritical PriorityID: opentelemetry-baggage-exemplar-invariants

OpenTelemetry W3C Baggage Propagation & High-Cardinality Exemplar Invariants

Enforces deterministic W3C tracecontext and baggage extraction/injection across asynchronous message queues, preventing context fragmentation in event-driven architectures. Mandates explicit high-cardinality metadata containment within baggage and exemplar attachments to prevent metric label explosions while preserving sub-millisecond trace-to-metric correlatability.

Prohibited Anti-Pattern: Context Leakage Across Message Brokers and Unbounded High-Cardinality Dimensional Metric Poisoning

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenTelemetry W3C Baggage Propagation & High-Cardinality Exemplar Invariants - Enforces deterministic W3C tracecontext and baggage extraction/injection across asynchronous message queues, preventing context fragmentation in event-driven architectures. Mandates explicit high-cardinality metadata containment within baggage and exemplar attachments to prevent metric label explosions while preserving sub-millisecond trace-to-metric correlatability.
globs: src/**/*.ts, src/**/*.js, src/telemetry/**/*.ts, src/messaging/**/*.ts, src/queues/**/*.ts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/opentelemetry-baggage-exemplar-invariants"
---

# OpenTelemetry W3C Baggage Propagation & High-Cardinality Exemplar Invariants

> **Severity**: CRITICAL | **Category**: devops
> **Anti-Pattern Warning**: Context Leakage Across Message Brokers and Unbounded High-Cardinality Dimensional Metric Poisoning

## System Constraints
You are a Principal Observability Architect enforcing strict OpenTelemetry W3C Baggage Propagation and High-Cardinality Exemplar Invariants. In distributed asynchronous topologies (Kafka, RabbitMQ, SQS), developers frequently break trace context by serializing messages without standard traceparent and baggage headers, or they commit cardinality explosion by pushing dynamic identifiers (tenant_id, user_id, order_id) into metric attributes instead of trace exemplars and baggage. You must strictly enforce: (1) Deterministic injection and extraction using propagation.inject/extract with standard W3C text map propagators; (2) Zero dynamic business identifiers in metric label dimensions—enforce passing them as W3C Baggage and Prometheus/OTel Exemplars; (3) Explicit span linkage when consumer processing operates in batch mode or triggers detached transactional lifecycles.

## Strict Guidelines
- Engineers MUST ALWAYS use the OpenTelemetry TextMapPropagator API (`propagation.inject` and `propagation.extract`) with the active `Context` when producing to or consuming from asynchronous message queues.
- Engineers MUST NOT inject high-cardinality attributes (e.g., `user_id`, `order_id`, `uuid`, `session_token`) as static Prometheus/OTel metric labels or counter attributes; high-cardinality values MUST be attached to Exemplars or encoded via W3C Baggage.
- Message consumers MUST extract the trace context from message metadata and bind it to the execution context using `context.with(extractedContext, () => ...)` prior to creating consumer spans.
- Batch consumers processing multiple parent contexts MUST create a consumer span with explicit `links` referencing each message's extracted `SpanContext`, rather than arbitrarily choosing a single parent or dropping parents.
- Telemetry interceptors MUST validate that W3C Baggage entries conform to RFC 7230 character restrictions and enforce payload size limits (maximum 8192 bytes total, 4096 bytes per entry) before propagation to avoid header rejection upstream.

## Bad vs Good Implementations
### Asynchronous Message Queue Trace & Baggage Propagation with Exemplar Metrics

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Publishing messages without invoking `propagation.inject` strips traceparent and baggage across broker boundaries, creating disconnected orphan traces in downstream consumers. Concurrently, logging `orderId` and `tenantId` into metric attributes causes catastrophic time-series cardinality explosions in TSDBs like Prometheus or Mimir.
```typescript
import { trace } from '@opentelemetry/api';
import { Meter } from '@opentelemetry/api';

interface MessagePayload {
  orderId: string;
  tenantId: string;
  data: unknown;
}

export async function publishMessage(broker: any, topic: string, payload: MessagePayload, meter: Meter) {
  const messageCount = meter.createCounter('messages_published_total');

  // ANTI-PATTERN: High-cardinality values injected into metric labels causing TSDB explosion
  messageCount.add(1, { tenantId: payload.tenantId, orderId: payload.orderId });

  // ANTI-PATTERN: Raw payload sent without standard W3C traceparent or baggage injection
  await broker.send({
    topic,
    messages: [{ value: JSON.stringify(payload) }]
  });
}

export async function handleMessage(brokerMessage: any, meter: Meter) {
  const tracer = trace.getTracer('worker');
  // ANTI-PATTERN: Creates orphan root span; parent context ignored from broker headers
  const span = tracer.startSpan('process_message');
  try {
    const payload = JSON.parse(brokerMessage.value);
    // processing logic...
  } finally {
    span.end();
  }
}
```

#### Production Standard (Correct)
> **Standard**: Adheres to W3C propagation invariants: headers are serialized via `propagation.inject` and hydrated via `propagation.extract` using formal `TextMap` semantics. Dynamic metadata remains inside the trace span and exemplars (`context.active()` passed to `counter.add()`), completely preventing high-cardinality metric degradation.
```typescript
import {
  trace,
  context,
  propagation,
  Meter,
  ROOT_CONTEXT,
  SpanKind,
  TextMapSetter,
  TextMapGetter,
  propagation as globalPropagation
} from '@opentelemetry/api';

interface MessagePayload {
  orderId: string;
  tenantId: string;
  data: unknown;
}

interface BrokerRecord {
  headers: Record<string, string>;
  value: string;
}

const recordSetter: TextMapSetter<Record<string, string>> = {
  set(carrier, key, value) { carrier[key] = value; }
};

const recordGetter: TextMapGetter<Record<string, string>> = {
  get(carrier, key) { return carrier[key]; },
  keys(carrier) { return Object.keys(carrier); }
};

export async function publishMessage(broker: any, topic: string, payload: MessagePayload, meter: Meter) {
  const tracer = trace.getTracer('producer');
  const messageCount = meter.createCounter('messages_published_total');

  await tracer.startActiveSpan(`produce_${topic}`, { kind: SpanKind.PRODUCER }, async (span) => {
    try {
      const headers: Record<string, string> = {};
      // Propagate active trace context & baggage into headers compliant with W3C TraceContext/Baggage specs
      propagation.inject(context.active(), headers, recordSetter);

      // Safe metric emission: Low-cardinality labels only. Trace & baggage correlate via active Exemplar automatically
      messageCount.add(1, { topic, environment: 'production' }, context.active());

      await broker.send({
        topic,
        messages: [{ headers, value: JSON.stringify(payload) }]
      });
    } finally {
      span.end();
    }
  });
}

export async function handleMessage(record: BrokerRecord, topic: string) {
  const tracer = trace.getTracer('consumer');
  // Extract inbound W3C trace context and baggage
  const extractedContext = propagation.extract(ROOT_CONTEXT, record.headers, recordGetter);

  // Bind extracted context deterministically to downstream consumer span
  await context.with(extractedContext, async () => {
    await tracer.startActiveSpan(
      `consume_${topic}`,
      { kind: SpanKind.CONSUMER },
      async (span) => {
        try {
          const payload: MessagePayload = JSON.parse(record.value);
          span.setAttribute('messaging.system', 'kafka');
          span.setAttribute('messaging.destination.name', topic);
          // Trace continuity preserved; baggage available without TSDB metric pollution
        } finally {
          span.end();
        }
      }
    );
  });
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: OpenTelemetry W3C Baggage Propagation & High-Cardinality Exemplar Invariants

OpenTelemetry W3C Baggage Propagation & High-Cardinality Exemplar Invariants defines an industrial-grade behavioral standard for devops engineering. Enforces deterministic W3C tracecontext and baggage extraction/injection across asynchronous message queues, preventing context fragmentation in event-driven architectures. Mandates explicit high-cardinality metadata containment within baggage and exemplar attachments to prevent metric label explosions while preserving sub-millisecond trace-to-metric correlatability. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Context Leakage Across Message Brokers and Unbounded High-Cardinality Dimensional Metric Poisoning Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftContext Leakage Across Message Brokers and Unbounded High-Cardinality Dimensional Metric PoisoningCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS use the OpenTelemetry TextMapPropagator API (`propagation.inject` and `propagation.extract`) with the active `Context` when producing to or consuming from asynchronous message queues.

Engineers MUST ALWAYS use the OpenTelemetry TextMapPropagator API (`propagation.inject` and `propagation.extract`) with the active `Context` when producing to or consuming from asynchronous message queues.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT inject high-cardinality attributes (e.g., `user_id`, `order_id`, `uuid`, `session_token`) as static Prometheus/OTel metric labels or counter attributes

Engineers MUST NOT inject high-cardinality attributes (e.g., `user_id`, `order_id`, `uuid`, `session_token`) as static Prometheus/OTel metric labels or counter attributes; high-cardinality values MUST be attached to Exemplars or encoded via W3C Baggage.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Message consumers MUST extract the trace context from message metadata and bind it to the execution context using `context.with(extractedContext, () => ...)` prior to creating consumer spans.

Message consumers MUST extract the trace context from message metadata and bind it to the execution context using `context.with(extractedContext, () => ...)` prior to creating consumer spans.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Batch consumers processing multiple parent contexts MUST create a consumer span with explicit `links` referencing each message's extracted `SpanContext`, rather than arbitrarily choosing a single parent or dropping parents.

Batch consumers processing multiple parent contexts MUST create a consumer span with explicit `links` referencing each message's extracted `SpanContext`, rather than arbitrarily choosing a single parent or dropping parents.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Telemetry interceptors MUST validate that W3C Baggage entries conform to RFC 7230 character restrictions and enforce payload size limits (maximum 8192 bytes total, 4096 bytes per entry) before propagation to avoid header rejection upstream.

Telemetry interceptors MUST validate that W3C Baggage entries conform to RFC 7230 character restrictions and enforce payload size limits (maximum 8192 bytes total, 4096 bytes per entry) before propagation to avoid header rejection upstream.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is OpenTelemetry W3C Baggage Propagation & High-Cardinality Exemplar Invariants critical for AI coding assistants?

Enforces deterministic W3C tracecontext and baggage extraction/injection across asynchronous message queues, preventing context fragmentation in event-driven architectures. Mandates explicit high-cardinality metadata containment within baggage and exemplar attachments to prevent metric label explosions while preserving sub-millisecond trace-to-metric correlatability. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Context Leakage Across Message Brokers and Unbounded High-Cardinality Dimensional Metric Poisoning) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

1 Rule in Stack

OpenTelemetry