Skip to content

fix(bt-daemon): report trace permalinks in session status - #230

Open
Wolfie (wolfiesch) wants to merge 1 commit into
braintrustdata:mainfrom
wolfiesch:fix/bt-daemon-trace-permalink
Open

Wolfie (wolfiesch) wants to merge 1 commit into
braintrustdata:mainfrom
wolfiesch:fix/bt-daemon-trace-permalink

Conversation

@wolfiesch

Copy link
Copy Markdown

status.get documents a per-route permalink that powers Pi's trace-link widget, but BraintrustSink never overrode Sink::permalink, so the field was always null and the widget never appeared.

The sink now records the root span id of the trace that most recently received a row and builds {app_url}/app/{org}/p/{project}/logs?r={root}, percent-encoding each segment the same way bt builds app URLs. Root rows use their span id as the row id, so r opens that trace. The consumer already publishes sink.permalink() after each successful flush, so the link appears once the first batch is delivered. A provisional root held for work has no link yet. The link stays null when no logs URL can be built: experiment and parent-span destinations, project logs addressed only by project_id, or a route without an org name. protocol.md now states these rules.

Pi refreshes its widget on session start, compaction, and tree navigation. A new session's first refresh runs before any trace is delivered, so its link appears at the next refresh. This PR leaves the plugin unchanged.

Validation (Rust 1.99.1, in bt-daemon/):

  • cargo fmt --check
  • cargo clippy --all-targets --all-features -- -D warnings
  • cargo test --all-features
  • New tests in tests/braintrust_sink.rs cover a held root, encoding, and switching to a newer trace, plus the destinations without a link.
  • Built bt against this branch, traced a session through the Pi extension and bt trace daemon, and confirmed status.get returned a permalink that opens that trace in the project logs.

`status.get` documents a per-route `permalink` that powers Pi's trace-link widget, but `BraintrustSink` never overrode `Sink::permalink`, so the field was always `null` and the widget never appeared.

The sink now records the root span id of the trace that most recently received a row and builds `{app_url}/app/{org}/p/{project}/logs?r={root}`, percent-encoding each segment the same way `bt` builds app URLs. Root rows use their span id as the row id, so `r` opens that trace. The consumer already publishes `sink.permalink()` after each successful flush, so the link appears once the first batch is delivered. A provisional root held for work has no link yet. The link stays `null` when no logs URL can be built: experiment and parent-span destinations, project logs addressed only by `project_id`, or a route without an org name. `protocol.md` now states these rules.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 27, 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 ⚠️ Failed 2026-10-27T06:31:53.309493Z
We couldn’t complete this review. Comment @codex review to try again.
f586917 PR opened
ℹ️ 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.

@wolfiesch

Copy link
Copy Markdown
Author

CI passed on my fork at this PR's head (f586917): https://github.com/wolfiesch/braintrust-coding-agent-plugins/actions/runs/40469236280

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