fix(sdk): apply 401 fail-loud to TjHttpExporter (the path bootstrap actually uses)#70
Merged
Merged
Conversation
…68 §2 PR #69 fixed §2 on tokenjam/sdk/transport.py's HttpTransport class — but bootstrap.py wires TjHttpExporter (the OTel SpanExporter in tokenjam/sdk/http_exporter.py) for actual span pushes. HttpTransport has no callers in the SDK. So the original §2 fix targeted dead code and the user-visible symptom — the short single-line "tj serve returned 401 on span export" warning — was unchanged. Confirmed by re-running the playbook on main after PR #69 merged: the demos still showed the old short message at the bottom of each run, with no actionable diagnostic. Apply the same fix pattern to TjHttpExporter.export(): - 401 logs at ERROR level (not WARNING) with the truncated ingest_secret fingerprint so the user can spot the mismatch. - Cumulative `dropped_auth_failures` counter so doctor / status can surface it later. - Message names both config-file locations (.tj/config.toml and ~/.config/tj/config.toml) and the daemon-restart fix verbatim. Non-401 responses keep the original short warning — only 401 is loud, because only 401 is "won't change on retry, and the user needs to act to fix it." Verified end-to-end via the playbook's sensitive_actions demo — the new ERROR message fires with the secret fingerprint and the "Dropped N span(s) so far" count. Tests: 575 passing (no regressions). The new behavior was already covered by the §2 tests written for the transport.py fix; both share the same logic shape. Follow-up worth considering: tokenjam/sdk/transport.py is dead code; consider removing it (along with its tests) so future debuggers don't waste time on it like I did. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Quick follow-up to PR #69 — the §2 fix landed in the wrong place.
What happened
PR #69 fixed §2 on `tokenjam/sdk/transport.py::HttpTransport` — adding ERROR-level logging, a dropped-spans counter, and fail-fast (no retry-backoff) on 401. But that class has no callers in the SDK. `bootstrap.py` wires `TjHttpExporter` (the OTel SpanExporter in `tokenjam/sdk/http_exporter.py`) for actual span pushes. So the fix targeted dead code; the user-visible 401 footgun was unchanged.
Confirmed by re-running the playbook on `main` after #69 merged: every demo still shows the old short `tj serve returned 401 on span export` warning at the bottom with no actionable diagnostic.
Fix
Apply the same pattern to `TjHttpExporter.export()`:
Non-401 responses keep the original short warning.
Verified end-to-end
```
$ python3 examples/alerts_and_drift/sensitive_actions_demo.py
... agent workflow ...
tj serve rejected span export with 401 — your SDK is using ingest_secret=10711471...
but the running daemon expects a different secret. Spans are being DROPPED. Check
that .tj/config.toml and ~/.config/tj/config.toml agree (or run `tj stop && tj
serve &` after rotating the secret). Dropped 7 span(s) so far.
```
Follow-up worth considering
`tokenjam/sdk/transport.py` is dead code. The §2 tests (`test_transport_401.py`) exercise a class no one calls. Probably worth removing in a separate PR so future debuggers don't waste time on it like I did.
Test plan
🤖 Generated with Claude Code