How Trace Context Propagation Works Across Firstmate Secondmates

Firstmate implements W3C trace-context propagation in a default-off mode, freezing the enablement decision at home-session start and injecting a single traceparent carrier into every spawned process—including nested and remote secondmates—via the TRACEPARENT environment variable.

Trace context propagation in the Firstmate orchestration system ensures distributed traces remain consistent across complex hierarchies of workers and secondmates. When enabled, the system resolves one traceparent carrier per task and propagates it through the entire execution chain, from the primary home session down to remote secondmates, while guaranteeing immutable configuration within each session boundary.

Enabling Trace Context Propagation in Firstmate

Firstmate treats trace-context propagation as an opt-in feature controlled by presence-based configuration and environment overrides.

Configuration Flags and Environment Variables

You activate the feature by creating a presence flag at config/trace-context within your Firstmate home directory. Alternatively, set the FM_TRACE_CONTEXT environment variable to override the configuration file.


# Enable via presence flag

mkdir -p "$HOME_DIR/config"
touch "$HOME_DIR/config/trace-context"

# Or enable via environment override

export FM_TRACE_CONTEXT=1

The Frozen Session Decision

At the start of every home session, fm_trace_context_session_start (defined in bin/fm-trace-context-lib.sh lines 59-71) reads the enablement state and writes a frozen decision to state/.trace-context-effective. This decision binds to the session lock pid, meaning any subsequent edits to config/trace-context or FM_TRACE_CONTEXT are ignored until the session releases its lock and restarts.


# The frozen decision is written once per locked session

bin/fm-trace-context-lib.sh fm_trace_context_session_start "$HOME_DIR/config" "$HOME_DIR/state/.trace-context-effective"

Trace Context Inheritance in Secondmates

Secondmates inherit trace-context configuration through a combination of launch-time prefix injection and the generic inheritable-config mechanism.

How Secondmates Inherit the Configuration

When spawning a secondmate, bin/fm-spawn.sh passes the primary home’s frozen decision via the launch prefix. The system also copies the configuration into the secondmate’s environment through FM_INHERITABLE_CONFIG, which ensures the config/trace-context flag persists into the child environment.

Independent Session Freezing

Each secondmate runs its own fm_trace_context_session_start logic upon initialization. It reads the inherited flag from its own config/trace-context and writes a separate frozen decision to its state/.trace-context-effective file. This guarantees that nested secondmates independently freeze the same enablement decision without referencing back to the parent after startup.

The inheritance mechanism is validated in tests/fm-secondmate-harness.test.sh (lines 295-309) and tests/fm-secondmate-safety.test.sh (lines 309-353).

Carrier Resolution and Task Injection

When Firstmate spawns any task—including workers and secondmates—it resolves the traceparent carrier through a deterministic resolution chain.

The fm_trace_context_resolve Function

Located in bin/fm-trace-context-lib.sh (lines 18-27), fm_trace_context_resolve implements the following logic:

  • If trace-context is disabled, the function returns nothing and the spawn proceeds without TRACEPARENT export.
  • If enabled, it first checks the task’s meta file at state/<id>.meta for an existing traceparent= entry (recovery path).
  • If absent, it calls fm_trace_context_mint (lines 5-12) to generate a fresh carrier using cryptographically-random entropy validated against the W3C format.

# Resolve or mint a carrier for a specific task

TRACEPARENT_VALUE=$(bin/fm-trace-context-lib.sh fm_trace_context_resolve "$HOME_DIR/config" "state/<task-id>.meta")

Task Metadata Persistence

The resolved carrier is injected into the spawned process environment as TRACEPARENT and simultaneously recorded in the task’s meta file. This dual recording ensures that task relaunches or crash recoveries reuse the exact same trace identifier, maintaining trace continuity across retries.

Remote Secondmate Propagation

For remote secondmates, propagation follows a strict command-line delegation pattern rather than environment inheritance. The primary home resolves the carrier using the standard resolution flow, then passes it explicitly via the --traceparent flag to fm-spawn.sh.


# Primary home resolves and transmits

TRACE=$(bin/fm-trace-context-lib.sh fm_trace_context_resolve "$HOME/config" "state/<task>.meta")
bin/fm-spawn.sh --remote secondmate-host --traceparent "$TRACE" ...

The remote host’s secondmate receives the carrier through the launch argument, records it in its own state/<id>.meta, and does not inherit any further trace-context flags from the parent environment. This isolation ensures remote workers have a single, unambiguous source of trace truth. The complete remote propagation flow is exercised in tests/fm-remote-secondmate-trace-context.test.sh (lines 140-272).

Session-Bound Immutability Guarantees

Firstmate protects against configuration drift by binding the trace-context decision to the session lifecycle. Because state/.trace-context-effective is tied to the specific session lock pid, only a full session restart (lock release and reacquisition) can re-evaluate the enablement flag. This immutability prevents stale or conflicting configurations when deeply nesting secondmates or when configuration files change mid-execution.

Verification of this session-bound behavior appears in tests/fm-trace-context-lib.test.sh (lines 31-38) and tests/fm-session-start.test.sh (lines 830-856).

Summary

  • Default-off architecture: Trace-context propagation requires explicit activation via config/trace-context presence flag or FM_TRACE_CONTEXT environment variable.
  • Frozen decisions: Each session computes an immutable enablement decision at startup, stored in state/.trace-context-effective and bound to the session lock.
  • Secondmate inheritance: Child secondmates receive configuration through FM_INHERITABLE_CONFIG and independently freeze their own decisions upon session start.
  • Single-carrier-per-task: The fm_trace_context_resolve function guarantees exactly one traceparent value per task, reused across relaunches via metadata storage in state/<id>.meta.
  • Remote delegation: Remote secondmates receive trace context exclusively through the --traceparent launch argument, not environment inheritance.

Frequently Asked Questions

How do I enable trace context propagation in Firstmate?

Create a presence flag file at config/trace-context in your Firstmate home directory, or set the FM_TRACE_CONTEXT environment variable. The system detects either condition during fm_trace_context_session_start and activates propagation for the duration of that session.

What happens if I change the config/trace-context file during a session?

Changes are ignored. Firstmate writes a frozen decision to state/.trace-context-effective at session start and binds it to the session lock pid. Only after releasing the session lock and starting a new session will the system re-read the configuration flag.

How does trace context work with remote secondmates?

For remote secondmates, the primary home resolves the traceparent carrier locally and passes it via the --traceparent flag to fm-spawn.sh. The remote secondmate records this value in its task meta and uses it directly, without inheriting any trace-context environment variables from the parent host.

Where is the traceparent value stored for task recovery?

Each task’s traceparent is stored in state/<task-id>.meta with the prefix traceparent=. When fm_trace_context_resolve runs for a task, it checks this file first; if a valid entry exists, it reuses that exact carrier rather than minting a new one, ensuring trace continuity across task restarts or crash recoveries.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →