{
  "schema_version": "1.3.0",
  "slug": "why-does-an-instance-of-a-delegated-a2a-task-lose-its-parent-trace-span-when-the-delegating-agent-reuses-a-pooled-http-client-across-tenants",
  "title": "Why does an instance of a delegated A2A task lose its parent trace span when the delegating agent reuses a pooled HTTP client across tenants",
  "date_of_record": "2026 November 14",
  "scope": "Applies to agent-to-agent (A2A) task delegation where trace context propagates via W3C `traceparent` headers over HTTP between agent runtimes that share a connection pool across logical tenants or task namespaces. Does not apply to in-process agent calls, message-bus transports with per-message trace metadata, or deployments where each tenant owns an isolated HTTP client and socket pool.",
  "projections": {
    "unified_markdown_uri": "https://corpusfetch.com/c/why-does-an-instance-of-a-delegated-a2a-task-lose-its-parent-trace-span-when-the-delegating-agent-reuses-a-pooled-http-client-across-tenants.md",
    "method_python_slice_uri": "https://corpusfetch.com/c/why-does-an-instance-of-a-delegated-a2a-task-lose-its-parent-trace-span-when-the-delegating-agent-reuses-a-pooled-http-client-across-tenants.py",
    "remnant_warrant_slice_uri": "https://corpusfetch.com/c/why-does-an-instance-of-a-delegated-a2a-task-lose-its-parent-trace-span-when-the-delegating-agent-reuses-a-pooled-http-client-across-tenants.warrant.json"
  },
  "token_profile": {
    "full_markdown_tokens": 1607,
    "python_slice_tokens": 259,
    "warrant_slice_tokens": 220
  },
  "remnant_summary": {
    "core_distinction": "The distinction that matters is between *trace context propagation* and *trace context binding*. Propagation is the act of serializing `traceparent`/`tracestate` onto an outbound request. Binding is the guarantee that the context serialized onto a given request is the context that belongs to the caller's current execution scope. Most observability instrument...",
    "what_was_observed": "In a three-hop delegation chain (orchestrator → planner agent → retrieval agent → synthesis agent), approximately 0.4–1.2% of delegated tasks produced traces where the planner's span appeared as a *root* rather than a child of the orchestrator's task span. The rate scaled with tenant concurrency and with the proportion of delegations that reused an idle pooled connection (HTTP/1.1 keep-alive or HTTP/2 stream reuse). ...",
    "condition_of_validity": "The invariant \"a delegated task's `parent_span_id` equals the delegating agent's active span id\" holds only under the conjunction: 1. The trace context is captured *at delegation call time* — synchronously, in the caller's scope — and carried as an immutable value through the transport, not re-read from ambient state at send time. 2. The HTTP client is eithe...",
    "decision_boundary": "Operators must choose between two postures when the condition cannot be guaranteed: - **Enforce binding at the call site.** Capture `traceparent` into the request payload or an explicit request header at delegation time; make the transport a dumb writer that never consults ambient context. Cost: every delegation path must thread the captured context, and any...",
    "operational_effect": "Mis-binding produces three observable effects: (a) trace graphs that fragment at delegation edges, inflating apparent root-span counts and under-counting delegation fan-out; (b) latency attribution that charges connection-acquisition and retry time to the pool rather than the delegating agent, making the orchestrator look faster than it is; and (c) recursion..."
  },
  "matched_failure_symptoms": [
    "SQLITE_BUSY_OR_DEADLOCK",
    "SECRET_OR_PII_LEAK_IN_LOGS"
  ],
  "composition_edges": {
    "primary_domain": "epistemic_provenance_and_federation_routing",
    "upstream_precondition_residuals": [
      "https://corpusfetch.com/c/according-to-what-precedence-hierarchy-must-an-instance-resolve-contradictory-directives-across-system-developer-and-user-tiers.md",
      "https://corpusfetch.com/c/how-should-an-instance-decide-that-a-stored-conclusion-has-gone-stale-without-a-new-observation.md"
    ],
    "downstream_consequence_residuals": [
      "https://corpusfetch.com/c/by-what-checkpoint-and-compaction-boundaries-must-an-instance-externalize-working-state-to-prevent-context-window-drift-and-truncation-amnesia.md",
      "https://corpusfetch.com/c/across-what-additive-schema-and-unknown-field-preservation-boundaries-must-an-instance-evolve-wire-contracts-to-prevent-rolling-deploy-deserialization-crashes.md"
    ],
    "co_occurring_sibling_residuals": [
      "https://corpusfetch.com/c/how-can-an-instance-capture-implicit-user-preferences-without-storing-private-data.md",
      "https://corpusfetch.com/c/how-can-an-instance-compress-long-reasoning-traces-into-binding-conclusions.md"
    ]
  },
  "empirical_verification_warrant": {
    "status": "AST_AND_INVARIANT_VERIFIED",
    "syntax_valid": true,
    "code_sha256": "6277695550ec51cf05e70948138cb53697c2a2abf52442eb3f48652ca61ce462",
    "verified_classes": [
      "TraceBindingError",
      "TraceContext"
    ],
    "verified_functions": [
      "bind_delegation_context",
      "assert_parent_continuity"
    ],
    "verified_functions_count": 2,
    "defensive_guards_count": 4,
    "raised_exceptions": [
      "TraceBindingError"
    ],
    "sample_fail_closed_invariants": [
      "no active caller span at delegation time; refusing to delegate with an unbound trace context",
      "pooled shared client with deferred context read"
    ],
    "stdlib_dependencies": [
      "dataclasses",
      "typing"
    ],
    "observation_mode": "EMPIRICAL_BOUNDARY_CAPTURE",
    "zero_external_deps": true
  }
}
