This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
devopscritical PriorityID: opentelemetry-w3c-batch-context-propagation-standard

OpenTelemetry W3C Distributed Context Propagation Across Async Queue Batches

Enforces strict extraction and propagation of W3C TraceContext metadata across asynchronous batch messaging architectures (Kafka, SQS, RabbitMQ). Guarantees that batch-consuming workers link each individual processing span to its distinct remote traceparent via OpenTelemetry SpanLinks or isolated context executions, preventing context detachment and cross-tenant trace pollution.

Prohibited Anti-Pattern: Executing Batch Item Processing Inside a Single Ambient Trace Context Inheriting Only One Traceparent or Rooting to Undefined

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: OpenTelemetry W3C Distributed Context Propagation Across Async Queue Batches - Enforces strict extraction and propagation of W3C TraceContext metadata across asynchronous batch messaging architectures (Kafka, SQS, RabbitMQ). Guarantees that batch-consuming workers link each individual processing span to its distinct remote traceparent via OpenTelemetry SpanLinks or isolated context executions, preventing context detachment and cross-tenant trace pollution.
globs: src/consumers/**/*.{ts,js,py,go}, src/queues/**/*.{ts,js,py,go}, src/workers/**/*.{ts,js,py,go}, src/messaging/**/*.{ts,js,py,go}
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/opentelemetry-w3c-batch-context-propagation-standard"
---

# OpenTelemetry W3C Distributed Context Propagation Across Async Queue Batches

> **Severity**: CRITICAL | **Category**: devops
> **Anti-Pattern Warning**: Executing Batch Item Processing Inside a Single Ambient Trace Context Inheriting Only One Traceparent or Rooting to Undefined

## System Constraints
You are a Principal Observability and Infrastructure Engineer enforcing OpenTelemetry W3C Distributed Context Propagation Across Async Queue Batches. Mandate strict boundary separation between batch ingestion and individual message processing spans. Reject any code where a batch worker evaluates multiple items within an ambient span derived from only the first message header or a single generic consumer span without SpanLinks. Ensure every item extracts its remote traceparent using OpenTelemetry context propagation APIs and runs in an explicit context boundary.

## Strict Guidelines
- Engineers MUST ALWAYS extract the W3C TraceContext (`traceparent`, `tracestate`) from each message's individual headers using `propagation.extract(ROOT_CONTEXT, message.headers, defaultTextMapGetter)`.
- Engineers MUST NOT allow an active consumer span to leak across iteration boundaries when processing a batch array of messages.
- Services MUST create an independent span per message item, either setting the extracted remote context as the item span's parent or linking to the remote context via `SpanLink` if maintaining a batch orchestration parent.
- Engineers MUST ALWAYS wrap the item execution within `context.with(extractedContext, () => ...)` to ensure downstream synchronous and asynchronous calls preserve that specific item's trace tree.
- Workers NEVER discard unparseable or absent traceparent headers; they MUST fallback to creating a valid new root span while recording a correlation warning attribute.

## Bad vs Good Implementations
### Batch Consumer Context Propagation in TypeScript (Kafka/SQS)

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The consumer creates a single ambient span for the entire batch and fails to extract W3C headers from individual messages. The sender spans for all messages are disconnected, breaking distributed tracing across the queue boundary and conflating unrelated workflows under one trace.
```typescript
import { trace } from '@opentelemetry/api';

interface QueueMessage {
  id: string;
  headers: Record<string, string>;
  body: string;
}

export async function processBatch(messages: QueueMessage[]): Promise<void> {
  const tracer = trace.getTracer('queue-consumer');
  // ANTI-PATTERN: Single consumer span wrapping all messages.
  // Individual messages lose their origin traceparent, leading to broken downstream traces.
  return tracer.startActiveSpan('processBatch', async (batchSpan) => {
    try {
      for (const message of messages) {
        // All downstream calls incorrectly attach to batchSpan instead of message origin
        await handleMessage(message);
      }
    } finally {
      batchSpan.end();
    }
  });
}

async function handleMessage(message: QueueMessage) {
  // Processing logic detached from sender's trace context
}
```

#### Production Standard (Correct)
> **Standard**: Every message extracts its own W3C traceparent context into an isolated context using `context.with`. The batch consumer creates explicit `SpanLink` references for the batch level, while each message maintains end-to-end parent continuity to its exact upstream producer span.
```typescript
import { trace, context, propagation, defaultTextMapGetter, SpanKind, Link } from '@opentelemetry/api';

interface QueueMessage {
  id: string;
  headers: Record<string, string>;
  body: string;
}

export async function processBatch(messages: QueueMessage[]): Promise<void> {
  const tracer = trace.getTracer('queue-consumer');

  // 1. Collect SpanLinks from each message in the batch for the orchestrator span
  const links: Link[] = messages
    .map(msg => {
      const extractedContext = propagation.extract(context.active(), msg.headers, defaultTextMapGetter);
      const spanContext = trace.getSpanContext(extractedContext);
      return spanContext && spanContext.isValid ? { context: spanContext } : null;
    })
    .filter((link): link is Link => link !== null);

  // 2. Start batch envelope span with links to all batch items
  await tracer.startActiveSpan('batch.consume', { kind: SpanKind.CONSUMER, links }, async (batchSpan) => {
    try {
      for (const message of messages) {
        // 3. Extract individual trace context per message
        const itemContext = propagation.extract(context.active(), message.headers, defaultTextMapGetter);
        
        // 4. Execute message handler inside its isolated, extracted context boundary
        await context.with(itemContext, async () => {
          const itemSpan = tracer.startSpan(`process.message.${message.id}`, {
            kind: SpanKind.CONSUMER,
            attributes: { 'messaging.message.id': message.id },
          });

          await context.with(trace.setSpan(context.active(), itemSpan), async () => {
            try {
              await handleMessage(message);
            } catch (err) {
              itemSpan.recordException(err as Error);
              throw err;
            } finally {
              itemSpan.end();
            }
          });
        });
      }
    } finally {
      batchSpan.end();
    }
  });
}

async function handleMessage(message: QueueMessage) {
  // Correctly bound to message-specific trace parent
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: OpenTelemetry W3C Distributed Context Propagation Across Async Queue Batches

OpenTelemetry W3C Distributed Context Propagation Across Async Queue Batches defines an industrial-grade behavioral standard for devops engineering. Enforces strict extraction and propagation of W3C TraceContext metadata across asynchronous batch messaging architectures (Kafka, SQS, RabbitMQ). Guarantees that batch-consuming workers link each individual processing span to its distinct remote traceparent via OpenTelemetry SpanLinks or isolated context executions, preventing context detachment and cross-tenant trace pollution. 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: Executing Batch Item Processing Inside a Single Ambient Trace Context Inheriting Only One Traceparent or Rooting to Undefined 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 DriftExecuting Batch Item Processing Inside a Single Ambient Trace Context Inheriting Only One Traceparent or Rooting to UndefinedCritical
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 extract the W3C TraceContext (`traceparent`, `tracestate`) from each message's individual headers using `propagation.extract(ROOT_CONTEXT, message.headers, defaultTextMapGetter)`.

Engineers MUST ALWAYS extract the W3C TraceContext (`traceparent`, `tracestate`) from each message's individual headers using `propagation.extract(ROOT_CONTEXT, message.headers, defaultTextMapGetter)`.

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 allow an active consumer span to leak across iteration boundaries when processing a batch array of messages.

Engineers MUST NOT allow an active consumer span to leak across iteration boundaries when processing a batch array of messages.

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

Services MUST create an independent span per message item, either setting the extracted remote context as the item span's parent or linking to the remote context via `SpanLink` if maintaining a batch orchestration parent.

Services MUST create an independent span per message item, either setting the extracted remote context as the item span's parent or linking to the remote context via `SpanLink` if maintaining a batch orchestration parent.

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

Engineers MUST ALWAYS wrap the item execution within `context.with(extractedContext, () => ...)` to ensure downstream synchronous and asynchronous calls preserve that specific item's trace tree.

Engineers MUST ALWAYS wrap the item execution within `context.with(extractedContext, () => ...)` to ensure downstream synchronous and asynchronous calls preserve that specific item's trace tree.

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

Workers NEVER discard unparseable or absent traceparent headers

Workers NEVER discard unparseable or absent traceparent headers; they MUST fallback to creating a valid new root span while recording a correlation warning attribute.

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 Distributed Context Propagation Across Async Queue Batches critical for AI coding assistants?

Enforces strict extraction and propagation of W3C TraceContext metadata across asynchronous batch messaging architectures (Kafka, SQS, RabbitMQ). Guarantees that batch-consuming workers link each individual processing span to its distinct remote traceparent via OpenTelemetry SpanLinks or isolated context executions, preventing context detachment and cross-tenant trace pollution. 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 (Executing Batch Item Processing Inside a Single Ambient Trace Context Inheriting Only One Traceparent or Rooting to Undefined) 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