You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Smoke-test playbook (tests/manual-new-release-tests.md):
- #3 (and #8/#9/#11/#12/#14/#16 — same root cause): code blocks are now
command-only; the inline "# comments" and "# [ ]" checklists that the markdown
copy button was pulling into copied commands moved to prose / "- [ ]" lists
around each block. Added a note explaining the convention.
- #10: corrected the Section 4 trim expectation — with [capture] prompts=false
(default), trim checks the capture prereq first and prints the capture hint,
NOT the tokenjam[bloat] install hint (only reachable once capture is on).
- #13: export file is "claude-code-<date>.jsonc", not ".json".
Doc-only; no code changes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: tests/manual-new-release-tests.md
+89-79Lines changed: 89 additions & 79 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,50 +2,43 @@
2
2
3
3
Run this after a new release publishes to PyPI to verify it works end-to-end. This is intentionally lighter than `manual-pre-release-testing.md` — the multi-project / secret-rotation / theme-toggle detail lives there and was exercised on the branch before merge. Here we're confirming the published artifact actually installs and the core surfaces are alive.
4
4
5
+
> **Code blocks are command-only on purpose.** Explanations and checklists live in
6
+
> prose around each block so the markdown "copy" button copies a runnable command,
7
+
> not a comment (smoke-test finding #3).
8
+
5
9
## Prerequisites
6
10
7
-
-`ANTHROPIC_API_KEY` and `OPENAI_API_KEY` in `~/tokenjam/.env.local`
8
-
-Sourced before running
11
+
-`ANTHROPIC_API_KEY` and `OPENAI_API_KEY` in `~/tokenjam/.env.local`, sourced before running.
12
+
-The example scripts import provider SDKs (`anthropic`, `openai`, `litellm`) that are **not** tokenjam dependencies. A `pipx install` isolates tokenjam in its own venv, so those SDKs must be injected into that venv and the examples run with its interpreter (Steps 3 and 8 do this).
9
13
10
14
## 1. Install the published release
11
15
16
+
`tj uninstall` removes data/config/daemon but **not** the package; `pipx uninstall` then removes the venv so `pipx install --force` rebuilds it pristine. The bare `pip3 install --upgrade tokenjam` path fails on system Python (PEP 668) — pipx is the path we ship docs telling users to use, so it's what we verify.
pipx uninstall tokenjam 2>/dev/null# remove the pipx venv so --force gets a pristine one
19
+
tj uninstall --yes 2>/dev/null
20
+
pipx uninstall tokenjam 2>/dev/null
15
21
rm -rf ~/.tj ~/.config/tj .tj
16
-
17
-
# Recommended install path (PEP 668-safe on Homebrew Python and
18
-
# Debian 12+/Ubuntu 24+). `--force` so we reinstall even if a prior
19
-
# version somehow survived above.
20
22
pipx install --force tokenjam
21
23
tj --version
22
-
23
-
# Older `pip3 install --upgrade tokenjam` path still works inside
24
-
# a clean venv but fails on system Python — that's the bug pipx
25
-
# solves, and verifying pipx is what we ship docs telling users to do.
26
24
```
27
25
28
26
**Pass criteria:** version matches the release being tested. `pipx install` reports a fresh venv (not "Installing to existing venv 'tokenjam'") thanks to the `pipx uninstall` step.
29
27
30
-
## 2. Onboard (sets plan tier via the integration flow)
28
+
## 2. Onboard
31
29
32
-
Bare `tj onboard`only prompts for daily budget — plan tier is set by the integration onboarding flows (`--claude-code` / `--codex`) per the v0.3.x design. For the smoke pass we onboard against Claude Code to write the `plan` field:
30
+
`tj onboard` prompts for daily budget and plan tier; `--plan api` sets the plan non-interactively (so plan-aware dollar rendering kicks in for the rest of the smoke), and `--no-daemon` skips the launchd/systemd install for this pass. We onboard against Claude Code here so the plan lands in the global config.
33
31
34
32
```bash
35
33
tj onboard --claude-code --plan api --no-daemon
36
-
# --plan api → writes `plan = "api"` non-interactively (so dollar rendering
37
-
# kicks in for the rest of the smoke)
38
-
# --no-daemon → skip launchd/systemd install for this smoke pass
39
-
```
40
-
41
-
```bash
42
34
grep '^plan = '~/.config/tj/config.toml
43
-
# [ ] plan field is set under [budget.anthropic]; no auto-written usd = 200
44
35
```
45
36
37
+
**Pass criteria:** the `plan` field is set under `[budget.anthropic]`; no auto-written `usd = 200`.
38
+
46
39
## 3. Drive an example + verify CLI
47
40
48
-
The example scripts import provider SDKs (`anthropic`, `openai`, ...) that are not tokenjam dependencies. `pipx install tokenjam` isolates tokenjam in its own venv, so the SDKs aren't importable from system Python either. Inject them into the pipx venv and run via that interpreter:
41
+
Inject the provider SDK into the pipx venv and run the example with that interpreter (see Prerequisites).
## 4. Cost-optimization analyzers (smoke — verify each runs)
65
65
66
66
```bash
67
-
tj optimize # all analyzers
68
-
tj optimize downsize # Downsize
69
-
tj optimize cache # Cache (efficacy)
70
-
tj optimize cache-recommend # Cache (recommend) — surfaces "enable capture.prompts" if not set
71
-
tj optimize script # Script — likely no candidates on a fresh DB
72
-
tj optimize trim # Trim — should print install hint without [bloat] extra
73
-
74
-
# Caveat enforcement on the downgrade finding
67
+
tj optimize
68
+
tj optimize downsize
69
+
tj optimize cache
70
+
tj optimize cache-recommend
71
+
tj optimize script
72
+
tj optimize trim
73
+
75
74
tj optimize --json | python3 -c \
76
75
"import json,sys;r=json.load(sys.stdin);d=r.get('downgrade');assert d is None or 'Candidate-flagging heuristic' in d['caveat'];print('ok: caveat enforced')"
77
76
78
-
# Plan-tier metadata in JSON
79
77
tj optimize --json | python3 -c \
80
78
"import json,sys;d=json.load(sys.stdin);assert 'plan' in d and 'pricing_mode' in d;print('ok')"
81
79
```
82
80
83
-
**Pass criteria:** every positional analyzer name runs without crashing. Optional analyzers (`cache-recommend`, `trim`) surface clear hints when their prereqs aren't met instead of erroring.
81
+
**Pass criteria:** every positional analyzer name runs without crashing, and the two JSON checks print `ok`. Optional analyzers surface a clear hint rather than erroring when a prereq isn't met:
82
+
83
+
-`cache-recommend` and `trim` both require `[capture] prompts = true`. With capture off (the default), each checks that prereq **first**, so `trim` prints the capture hint — **not** the `tokenjam[bloat]` install hint (you only reach the `[bloat]` hint once capture is on but the extra is missing). `script` likely reports no candidates on a fresh DB.
# [ ] On api plan: shows absolute spend; no multiplier line
91
-
# [ ] Action line surfaces either downsize savings or "no obvious
92
-
# savings flagged yet" (both are valid)
93
89
94
-
# Verify the JSON tier label is one of the six valid v0.3.4 tiers.
95
90
tj tokenmaxx --json | python3 -c \
96
91
"import json,sys;d=json.load(sys.stdin);ok={'TokenSipper','TokenModerator','TokenMaxxer','TokenSuperMaxxer','TokenMegaMaxxer','TokenGigaMaxxer'};assert d['tier'] in ok,d['tier'];print('ok:',d['tier'])"
92
+
```
93
+
94
+
Check the rendered report:
97
95
98
-
# Reconfigure to a subscription plan and re-run — the multiplier line
99
-
# should appear. Pick whichever plan matches your test config.
-[ ] On the `api` plan: shows absolute spend, no multiplier line
98
+
-[ ] Action line surfaces either the downsize savings or "no obvious savings flagged yet" (both valid)
99
+
100
+
Then reconfigure to a subscription plan and re-run to confirm the multiplier line appears (use whichever plan matches your test config), then flip back to `api` so later steps render dollar figures:
# [ ] Multiplier line "That's N× your Max 5x plan cost ($100/mo flat)."
103
-
# [ ] Tier may shift if the multiplier crosses a boundary
104
-
105
-
# Flip back to api so subsequent steps render dollar figures.
106
105
tj onboard --claude-code --reconfigure --plan api
107
106
```
108
107
109
-
**Pass criteria:** the report renders without crashing, the JSON `tier` field carries one of the 6 v0.3.4 tier names, and the multiplier line appears under a subscription plan.
108
+
-[ ] Multiplier line "That's N× your Max 5x plan cost ($100/mo flat)."
109
+
-[ ] Tier may shift if the multiplier crosses a boundary
110
+
111
+
**Pass criteria:** the report renders without crashing, the JSON `tier` field carries one of the 6 tier names, and the multiplier line appears under a subscription plan.
110
112
111
113
## 5. Backfill adapters (smoke against committed fixtures)
Start the server, inject `litellm` into the pipx venv (one-time per smoke run), drive the litellm example over the HTTP transport, and confirm `tj cost` works via the API fallback while the server holds the DB lock:
157
+
150
158
```bash
151
159
tj serve &
152
160
sleep 2
153
161
154
-
# HTTP fallback while server holds the lock.
155
-
# Inject litellm into the pipx venv first (one-time per smoke run):
Open Chrome DevTools (or your browser's equivalent) → **Network tab** → reload `http://127.0.0.1:7391/`.
173
179
174
180
-[ ]**Zero failed requests** to `fonts.googleapis.com`, `fonts.gstatic.com`, `esm.sh`, or `tokenjam.dev`
175
-
-[ ] Dashboard interactivity works (sidebar nav, tab switches) — proves the vendored Preact / htm under `/ui/vendor/` is being served, not loading from the CDN
181
+
-[ ] Dashboard interactivity works (sidebar nav, tab switches) — proves the vendored Preact / htm / uPlot under `/ui/vendor/` is being served, not loading from a CDN
176
182
-[ ] Favicon renders (data: URL, no external fetch)
177
183
178
184
Bonus: turn off wifi entirely, hard-refresh, and confirm the page still renders + the JS still hydrates. The whole dashboard must work air-gapped.
@@ -181,47 +187,49 @@ Bonus: turn off wifi entirely, hard-refresh, and confirm the page still renders
Cache-only spans (cache_read > 0, input/output = 0) used to be costed at $0. Cache-creation tokens on the live OTLP path used to be silently dropped. Both fixedin v0.3.4.
192
+
Cache-only spans (cache_read > 0, input/output = 0) used to be costed at $0, and cache-creation tokens on the live OTLP path used to be silently dropped — both fixed. The spans table gained `cache_write_tokens`in migration 5.
187
193
188
194
```bash
189
-
# Spans table now has cache_write_tokens (migration 5).
# Any captured Anthropic cache-hit span should have non-zero cost_usd.
195
199
duckdb ~/.tj/telemetry.duckdb "
196
-
SELECT COUNT(*) AS hits,
197
-
MIN(cost_usd) AS min_cost
200
+
SELECT COUNT(*) AS hits, MIN(cost_usd) AS min_cost
198
201
FROM spans
199
202
WHERE cache_tokens > 0
200
203
AND (input_tokens = 0 OR input_tokens IS NULL)
201
204
AND (output_tokens = 0 OR output_tokens IS NULL)
202
205
"2>/dev/null
203
-
# [ ] If hits > 0: min_cost > 0 (cache hits ARE being costed; was $0 pre-0.3.4)
204
-
# [ ] If hits = 0: this release's runs didn't trigger a pure cache-only span — fine, unit tests cover the path
205
206
```
206
207
207
-
If you don't have `duckdb` CLI installed, skip the SQL checks — the unit + synthetic tests covering these paths run in CI and are the canonical verification.
208
+
-[ ]`cache_write_tokens` column is present on the spans table
209
+
-[ ] If `hits > 0`: `min_cost > 0` (cache hits ARE costed; was $0 pre-fix)
210
+
-[ ] If `hits = 0`: this release's runs didn't trigger a pure cache-only span — fine; unit tests cover the path
211
+
212
+
If you don't have the `duckdb` CLI installed, skip the SQL checks — the unit + synthetic tests covering these paths run in CI and are the canonical verification.
208
213
209
214
---
210
215
211
216
## Claude Code integration (smoke)
212
217
218
+
Onboard against Claude Code (substitute your actual plan), confirm the OTEL env + project tracking landed, and that a re-run is a quiet no-op. Backfill runs automatically during onboard, so history should be queryable afterward.
219
+
213
220
```bash
214
-
tj onboard --claude-code --plan max_5x# substitute your actual plan
| 2 | Onboard prompts for plan tier; config records it; no auto `usd = 200` written |
259
+
| 2 | Onboard records the plan tier; no auto `usd = 200` written |
250
260
| 3 | Example runs without DB-lock errors; CLI shows real USD values |
251
261
| 4 | All optimize analyzers run; caveat appears in downgrade JSON; `plan` + `pricing_mode` in JSON output |
252
-
| 4b |`tj tokenmaxx` renders the bordered report panel; JSON `tier` is one of the 6 v0.3.4 tier names; subscription plan shows multiplier line |
262
+
| 4b |`tj tokenmaxx` renders the bordered report panel; JSON `tier` is one of the 6 tier names; subscription plan shows multiplier line |
253
263
| 5 | All three backfill adapters ingest from fixtures; re-runs are idempotent |
254
-
| 6 |`--compare previous` produces a diff report; `--export-config` writes a snippet with caveat comments |
264
+
| 6 |`--compare previous` produces a diff report; `--export-config` writes a `.jsonc`snippet with caveat comments |
255
265
| 7 |`tj policy list` renders the unified table |
256
-
| 8 |`tj serve` starts, web UI loads, HTTP fallback works while server holds lock; **zero external requests in DevTools Network tab**(offline-UI fix shipped in v0.3.4) |
266
+
| 8 |`tj serve` starts, web UI loads, HTTP fallback works while server holds lock; **zero external requests in DevTools Network tab**|
257
267
| 9 |`cache_write_tokens` column present on the spans table (migration 5); cache-hit spans show non-zero cost_usd |
258
268
| Claude Code | Onboard writes settings.json + projects.json; re-run is a no-op |
0 commit comments