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
TRACEPARENTexport. - If enabled, it first checks the task’s meta file at
state/<id>.metafor an existingtraceparent=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-contextpresence flag orFM_TRACE_CONTEXTenvironment variable. - Frozen decisions: Each session computes an immutable enablement decision at startup, stored in
state/.trace-context-effectiveand bound to the session lock. - Secondmate inheritance: Child secondmates receive configuration through
FM_INHERITABLE_CONFIGand independently freeze their own decisions upon session start. - Single-carrier-per-task: The
fm_trace_context_resolvefunction guarantees exactly one traceparent value per task, reused across relaunches via metadata storage instate/<id>.meta. - Remote delegation: Remote secondmates receive trace context exclusively through the
--traceparentlaunch 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →