Add attributed exec process lifecycle telemetry (#42373)

## Why

Exec-server process and network-policy events need stable attribution to the
launching tool call and executor without recording process payloads.

## What changed

- Add optional `ExecMetadata` to `ExecParams` and propagate the thread and tool
  call IDs from unified exec.
- Emit bounded OpenTelemetry events for process start, spawn failure, sandbox
  denial, and exit. Correlate them with the launch trace and registry-issued
  executor identity while excluding arguments, paths, environment values,
  output, and error text.
- Preserve launch attribution across long-running processes and reconnects, and
  attach the same metadata to network-policy audit events.
- Keep the protocol backward compatible when metadata is omitted, and prevent
  invalid trace headers from inheriting an unrelated active span.

## Testing

Add coverage for metadata serialization and propagation, lifecycle event
fields, trace relationships, reconnect behavior, spawn failures, sandbox
denials, and network-policy attribution.

GitOrigin-RevId: 7aa480a7289c73cb95e2c124c35500bb6f0d5084
This commit is contained in:
viyatb-oai authored and copyberry committed 2026-09-02 21:58:58 +00:00
1 parent 5037919777
commit f53c91be2c
47 files changed
+1461 -178

No files matched your search

@@ -15,7 +15,8 @@ use super::MAX_SNAPSHOT_ATTEMPTS;
use super::SNAPSHOT_RETRY_BACKOFF;
use super::ShellSnapshotCache;
use super::parse_snapshot;
use crate::process_sandbox::prepare_exec_request;
use crate::process_sandbox::prepare_exec_request_with_telemetry;
use crate::process_telemetry::ProcessTelemetry;
use crate::protocol::ExecEnvPolicy;
use crate::protocol::ExecParams;
use crate::protocol::ProcessId;
@@ -40,6 +41,7 @@ async fn snapshot_failure_retries_are_bounded_and_single_flight(
let profile = home.path().join(".bashrc");
std::fs::write(&profile, "printf x >> \"$HOME/captures\"\nexit 7\n")?;
let params = ExecParams {
metadata: Default::default(),
process_id: ProcessId::from("snapshot-retry"),
argv: vec![
"/bin/bash".to_string(),
@@ -89,21 +91,23 @@ async fn snapshot_failure_retries_are_bounded_and_single_flight(
"printf x >> \"$HOME/captures\"\nprofile_helper() { printf recovered; }\n",
)?;
}
let mut prepared = prepare_exec_request(
let mut prepared = prepare_exec_request_with_telemetry(
&params,
params.env.clone(),
/*runtime_paths*/ None,
/*network_policy_decider*/ None,
/*network_policy_audit_observer*/ None,
&ProcessTelemetry::default(),
)
.await
.expect("prepare capture");
let mut concurrent = prepare_exec_request(
let mut concurrent = prepare_exec_request_with_telemetry(
&params,
params.env.clone(),
/*runtime_paths*/ None,
/*network_policy_decider*/ None,
/*network_policy_audit_observer*/ None,
&ProcessTelemetry::default(),
)
.await
.expect("prepare concurrent capture");