Skip to content

feat: use BRAINTRUST_ prefix for tracing env vars - #165

Open
Abhijeet Prasad (AbhiPrasad) wants to merge 2 commits into
mainfrom
abhi/sdk-245-braintrust-env-prefix
Open

Abhijeet Prasad (AbhiPrasad) wants to merge 2 commits into
mainfrom
abhi/sdk-245-braintrust-env-prefix

Conversation

@AbhiPrasad

@AbhiPrasad Abhijeet Prasad (AbhiPrasad) commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Summary

Fixes SDK-245. This is the coding-agent counterpart to braintrustdata/bt#416.

bt trace env vars come from bt-daemon, and they all used the BT_* prefix. Everything else (bt after #416, and all the Braintrust SDKs) uses BRAINTRUST_*. This PR moves the user-facing tracing env vars to BRAINTRUST_*.

  • Rename (prefix only): BT_DAEMON_SOCKET, BT_DAEMON_DATA_DIR, BT_DAEMON_CONFIG, BT_ANTIGRAVITY_CONFIG_DIR, BT_CURSOR_PLUGIN_DIR, BT_CURSOR_CONFIG_DIR, BT_TRACE_PI_PLUGIN_SPEC, BT_TRACE_OPENCODE_PLUGIN_SPEC. For example, BT_DAEMON_SOCKET becomes BRAINTRUST_DAEMON_SOCKET.
  • Old names still work, without a warning. bt-daemon/src/env.rs reads the BRAINTRUST_* name and falls back to the BT_* name. If both are set, BRAINTRUST_* wins. To drop the old names in a future major release, delete DEPRECATED_BT_ENV_VARS.
  • Compatibility with already-installed plugins: bt trace run passes every resolved value to the child process under both the new and old names. That covers its own isolated daemon, an explicit BRAINTRUST_DAEMON_SOCKET, and a stale old value. The pi/opencode plugins already installed from npm only read BT_DAEMON_SOCKET, and this keeps them talking to the right daemon. The JS daemon client now reads BRAINTRUST_DAEMON_SOCKET first and falls back to BT_DAEMON_SOCKET, so new plugins also work with an older bt.
  • bt binary override: the Cursor hook launchers (BT_BIN) and the OpenCode bt tool (BT_EXECUTABLE) now both read BRAINTRUST_BT_BIN, and fall back to their old names. This is the one change that isn't prefix-only. Both old names meant "path to bt", so they now share one new name.
  • Internal protocol unchanged: bt trace run sets BT_TRACE_MANAGED_RUN_ID, BT_TRACE_INVOCATION_SETTINGS, and _BT_TRACE_MANAGED_RUN for its child process tree, and separately released plugins read them. They keep their names, the same exception bt#416 made for its runner protocol vars.
  • Guard test: env_vars_use_braintrust_prefix scans bt-daemon/src. It fails on any BT_* name that is neither a deprecated alias nor internal protocol. It also fails if a deprecated alias maps to a name nothing reads. AGENTS.md now states the prefix rule.

Not in this PR:

  • Test-only knobs (BT_AGENT_*, BT_CONSOLE_PROBE_*, BT_DAEMON_BIN in test wrappers) keep their names.
  • bt needs a bt-daemon SHA bump after this merges. Its tests set BT_DAEMON_CONFIG and will keep passing through the alias; they can switch to the new name in the same bump.

Testing

  • cargo fmt --check and cargo clippy --all-features --all-targets -D warnings are clean.
  • cargo test --all-features: 491 passed. I checked that the guard test fails when a new BT_ const is added, and when the deprecated list has a bogus entry.
    • dispatch::tests::terminal_grok_hydration_waits_for_a_stable_transcript_boundary failed in 2 early full runs. It then passed in 6 more full runs on this branch and 6 on main. This PR doesn't touch that file.
  • New integration test standalone_run_mirrors_an_explicit_socket_to_the_deprecated_name runs bt-daemon run pi with an explicit BRAINTRUST_DAEMON_SOCKET, once with BT_DAEMON_SOCKET missing and once stale. It checks that the child sees the explicit socket under both names. It failed before the fix (the child saw an empty BT_DAEMON_SOCKET).
  • New integration test standalone_hook_honors_deprecated_bt_env_names runs the real bt-daemon binary. It checks that the old name alone works with empty stderr, and that the new name wins when both are set.
  • JS daemon client (node --test, Node 24): 10/10 pass. The new socket-name tests fail on main (8 pass, 2 fail).
  • opencode (19) and pi (22) plugin test suites pass. make test passes.
  • I ran the Cursor trace.sh launcher with recording shims. It picks BRAINTRUST_BT_BIN, falls back to BT_BIN, and prefers the new name when both are set.

Before and after with the real binary, running bt-daemon hook --source codex against a disabled-tracing config:

Env main This branch
BRAINTRUST_DAEMON_CONFIG=ok.json ignored, fails: no settings at ~/.codex/braintrust.json uses ok.json
BT_DAEMON_CONFIG=ok.json uses ok.json uses ok.json
BT_DAEMON_CONFIG=ok.json BRAINTRUST_DAEMON_CONFIG=missing.json uses ok.json uses missing.json (BRAINTRUST_* wins)

Running bt-daemon run pi with a fake PI_BIN that prints its env: main gives the child only BT_DAEMON_SOCKET/BT_DAEMON_DATA_DIR. This branch gives the child both BRAINTRUST_DAEMON_* and BT_DAEMON_* with matching values. A deprecated BT_TRACE_PI_PLUGIN_SPEC is still honored.

🤖 Generated with Claude Code

Co-authored by StarfolkAI (@starfolkai)[bot]

Rename the user-facing bt-daemon env vars from BT_* to BRAINTRUST_*,
matching bt (braintrustdata/bt#416) and the Braintrust SDKs. Fixes SDK-245.

- bt-daemon/src/env.rs reads BRAINTRUST_<NAME> and silently falls back to
  the deprecated BT_<NAME>. The canonical name wins when both are set. The
  old names can be dropped in a future major release.
- bt trace run sets both socket/data-dir names on its children so plugins
  released before the rename still find the isolated daemon.
- The JS daemon client, Cursor hook launchers, and the OpenCode bt tool
  read the new names first and fall back to the old ones.
- BT_TRACE_MANAGED_RUN_ID / BT_TRACE_INVOCATION_SETTINGS stay unchanged as
  internal protocol between bt trace run and its child processes.
- A guard test fails on any new BT_* name in bt-daemon/src.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T17:53:47.062788Z 7432fa0 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8f4021740e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines 109 to +111
if let Some(runtime) = &isolated_runtime {
command
.env(paths::SOCKET_ENV, &runtime.socket)
.env(paths::DATA_DIR_ENV, runtime.temp_dir.path());
env::set_with_alias(&mut command, paths::SOCKET_ENV, &runtime.socket);
env::set_with_alias(&mut command, paths::DATA_DIR_ENV, runtime.temp_dir.path());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Mirror explicit sockets to the legacy child variable

When a non-default BRAINTRUST_DAEMON_SOCKET is supplied, isolate_daemon is false, so this block never mirrors the resolved socket into BT_DAEMON_SOCKET. An already-installed Pi or OpenCode plugin from before the rename reads only the legacy variable and therefore connects to the default or stale socket, while the managed runner flushes the explicitly configured socket, silently losing the run's trace. Mirror an inherited explicit socket into both names on the child just as this block does for an isolated runtime.

AGENTS.md reference: AGENTS.md:L53-L58

Useful? React with 👍 / 👎.

@AbhiPrasad Abhijeet Prasad (AbhiPrasad) Oct 9, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed in 7432fa0. bt trace run now passes every resolved BRAINTRUST_* value to the child under both names (env::mirror_aliases), so an explicit BRAINTRUST_DAEMON_SOCKET reaches pre-rename plugins as BT_DAEMON_SOCKET too, and a stale BT_DAEMON_SOCKET is overwritten. The isolated-daemon override still applies on top. New test standalone_run_mirrors_an_explicit_socket_to_the_deprecated_name covers both the missing and stale cases; it failed before the fix (child saw an empty BT_DAEMON_SOCKET).

With an explicit BRAINTRUST_DAEMON_SOCKET, bt trace run does not create
an isolated daemon, so the child only inherited the new name. Pi and
OpenCode plugins released before the rename read BT_DAEMON_SOCKET and
would connect to the default (or a stale) socket instead. Pass every
resolved value to the child under both names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant