Skip to content

platform: define a run-identity and trace-context propagation contract #389

Description

@codeforester

Goal

Define a standard, language-neutral environment contract so a CLI invocation can be correlated with
the process that launched it — including when either side is not a base-cli application.

Background

The data model for parent/child correlation already exists in the Context and in run.json:
RuntimeBinding.inherited_path, RuntimeBinding.history_parent_run_id,
Context.history_scope (primary / internal), and Context.history_parent_run_id. A child
invocation that inherits a run root is deliberately excluded from owning run metadata
(owns_run_metadata = inherited_path is None and ..., lib/python/base_cli/_app_core.py:1175).

What is missing is the transport. Those values reach the framework only from a
consumer-supplied RuntimeResolver. base-cli defines no environment variable for them, so every
consumer must invent its own convention, and two base-cli CLIs from different teams cannot correlate
at all. The framework's own environment surface confirms the gap:

$ grep -rhoE "BASE_CLI_[A-Z_]+" lib/python/base_cli/ docs/*.md | sort -u
BASE_CLI_BENCHMARK_PLATFORM
BASE_CLI_CACHE_DIR
BASE_CLI_COLOR
BASE_CLI_CONFIG_DIR
BASE_CLI_DISPLAY_COMMAND
BASE_CLI_VALIDATION_RESULT

Nothing for run identity. For the ops/platform/SRE audience this is a core capability, not a nicety:
CLIs calling CLIs, wrapped by shell scripts, driven by CI, is the normal topology, and "which run
produced this artifact" is the first question during an incident.

This is also the cheapest possible increment toward the language-neutral platform in #274-#277: an
environment-variable contract needs no SDK in any language. A Bash wrapper, a Go binary, or a
Makefile can participate by reading and forwarding variables.

Scope

  • Define and document the variables: run ID, parent run ID, run root, and history scope — for
    example BASE_CLI_RUN_ID, BASE_CLI_PARENT_RUN_ID, BASE_CLI_RUN_ROOT, BASE_CLI_RUN_SCOPE.
  • Define W3C trace-context interop: read an inbound traceparent/tracestate and export them for
    children, so the OpenTelemetry integration produces connected traces across process boundaries
    instead of isolated per-process spans.
  • Make the generic runtime resolver honour the inbound variables by default, producing an inherited
    binding rather than a new owning run.
  • Export the variables into the child environment for subprocesses the command launches, with a
    documented opt-out.
  • Specify precedence against an explicit RuntimeResolver, and validation rules (a malformed or
    hostile inbound run ID must not become a path component — runtime_run_directory_name() and the
    cleanup guards depend on run IDs being single safe components).
  • Define the trust boundary: inbound values come from the environment and must be validated, never
    trusted as paths.

Acceptance criteria

  • Two base-cli CLIs, one invoking the other with no custom profile, produce correlated records: the
    child's run.json carries the parent run ID and scope: internal, and only the parent owns the bundle.
  • A shell script or non-Python process can set the documented variables and achieve the same
    correlation with no Python involvement.
  • An inbound run ID that is not a single safe path component is rejected with an actionable error and
    cannot influence any filesystem path.
  • With telemetry enabled, a child span is a child of the parent span via inbound traceparent.
  • The variables, precedence, validation, opt-out, and trust boundary are documented in
    docs/integrations.md and docs/security-threat-model.md.

Validation

End-to-end test with a base-cli parent invoking a base-cli child, and a second test with a shell
wrapper setting the variables directly. Negative tests for ../, absolute paths, and NUL in the
inbound run ID.

Non-goals

  • Do not add a daemon or shared state beyond the environment and the existing run bundle.
  • Do not make OpenTelemetry a required dependency.
  • Do not change the existing RuntimeResolver protocol shape.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or product improvement

Type

No type

Projects

  • Status
    Backlog

Relationships

None yet

Development

No branches or pull requests

Issue actions