Conversation
Every open PR editing CHANGELOG.md's `## Pending` section directly meant any two concurrent PRs collided on the same lines, and each merge forced the next PR to redo the conflict resolution. Add changelog.d/, where each PR drops a new file instead of editing the shared section, so concurrent PRs can never conflict on this axis. scripts/assemble_changelog.py folds the fragments into a versioned CHANGELOG.md section at release time. See changelog.d/README.md for the fragment format and .claude/commands/release.md for the updated release process (not committed here — .claude/ isn't tracked in this repo yet). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BK3fzED9ksTWsvoPfsEwpS
The API populates a span's duration_ms and exclusive_duration_ms keys with values in seconds, not milliseconds. renderSpan formatted the raw value with FormatMs, so an 8-second span printed as "8ms", and the bar-fill ratio against the trace total was always ~0.001. Every bar collapsed to the 1-block minimum, the yellow/red color thresholds never fired, and the "slow" warning was unreachable. Rename the fields to DurationSeconds/ExclusiveDurationSeconds so the real unit is explicit, keeping the JSON tags on the API's wire names, and scale to milliseconds at the point of use. TOON output now shows the accurate field names; --json keys are unchanged. Closes #26 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BK3fzED9ksTWsvoPfsEwpS
Drop changelog.d/ and the assembly script — decided the fragment-file system was more process than this repo's PR concurrency warrants. Move this PR's changelog entry into CHANGELOG.md's Pending section directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BK3fzED9ksTWsvoPfsEwpS
quinnmil
force-pushed
the
26-traces-show-duration-units
branch
from
September 11, 2026 17:26
f7f50f1 to
d5e75ae
Compare
mitchh456
approved these changes
Sep 14, 2026
mitchh456
left a comment
There was a problem hiding this comment.
Verified against the API serializer — duration_ms is seconds, so the scaling direction is right; the bar-fill and slow-threshold paths now have direct test coverage.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #26
Summary
scout traces showrendered every span's duration ~1000x too small, which silenced the whole visualization: bars always collapsed to the 1-block minimum, the yellow/red color thresholds could never trigger, and the⚠ slowwarning was unreachable.Root cause: the API reports a span's
duration_ms/exclusive_duration_msin seconds, despite the key name.renderSpanformatted the raw value as milliseconds, so an 8-second span printed "8ms," and the bar-fill ratio against the trace total was always ≈0.001.Fix
Renamed
TraceSpan.DurationMs/ExclusiveDurationMstoDurationSeconds/ExclusiveDurationSecondsso the real unit is explicit in the Go types (JSON tags keep the API's wire names, so--jsonoutput is unchanged), and scale to milliseconds once at the point of use inrenderSpanfor both the printed label and the bar-fill ratio.Verified live
Checked against real trace data on an authenticated account: before the fix, a span's printed duration and the trace header's total duration disagreed by ~1000x; after, they agree, and a trace's
duration_in_secondsmatches the sum of its root-span durations to six decimal places across several traces. With the fix, a root span filling the whole trace renders fully red with the slow warning, a span at roughly half the trace's duration renders mostly-filled in yellow with the warning, and a small span renders a single filled block in green with no warning — all three color thresholds and the warning are reachable again.Tests
Test plan
gofmt -l cmd internal(clean, aside from a pre-existing unrelated file)go vet ./...go buildgo test -race ./...golangci-lint run ./...(0 issues)🤖 Generated with Claude Code
https://claude.ai/code/session_01BK3fzED9ksTWsvoPfsEwpS