Skip to content

Commit e02038e

Browse files
anilmurtyclaude
andcommitted
docs: command-only smoke-test blocks + fix trim/jsonc expectations (#3,#10,#13)
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>
1 parent ae1eb52 commit e02038e

1 file changed

Lines changed: 89 additions & 79 deletions

File tree

tests/manual-new-release-tests.md

Lines changed: 89 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,43 @@
22

33
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.
44

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+
59
## Prerequisites
610

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).
913

1014
## 1. Install the published release
1115

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.
17+
1218
```bash
13-
tj uninstall --yes 2>/dev/null # removes data, config, daemon
14-
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
1521
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.
2022
pipx install --force tokenjam
2123
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.
2624
```
2725

2826
**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.
2927

30-
## 2. Onboard (sets plan tier via the integration flow)
28+
## 2. Onboard
3129

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.
3331

3432
```bash
3533
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
4234
grep '^plan = ' ~/.config/tj/config.toml
43-
# [ ] plan field is set under [budget.anthropic]; no auto-written usd = 200
4435
```
4536

37+
**Pass criteria:** the `plan` field is set under `[budget.anthropic]`; no auto-written `usd = 200`.
38+
4639
## 3. Drive an example + verify CLI
4740

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).
4942

5043
```bash
5144
pipx inject tokenjam anthropic openai
@@ -55,70 +48,81 @@ cd ~/tokenjam
5548
source .env.local
5649
"$PIPX_PY" examples/single_provider/anthropic_agent.py
5750

58-
tj status # agent with cost > $0, tokens > 0
59-
tj traces # waterfall renders
60-
tj cost --since 1h # real USD values (not $0.000000)
61-
tj doctor # exit 0 or 1 (warnings ok)
51+
tj status
52+
tj traces
53+
tj cost --since 1h
54+
tj doctor
6255
```
6356

57+
**Pass criteria:**
58+
59+
- [ ] `tj status` shows the agent with cost > $0 and tokens > 0
60+
- [ ] `tj traces` renders the waterfall
61+
- [ ] `tj cost --since 1h` shows real USD values (not `$0.000000`)
62+
- [ ] `tj doctor` exits 0 or 1 (warnings ok)
63+
6464
## 4. Cost-optimization analyzers (smoke — verify each runs)
6565

6666
```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+
7574
tj optimize --json | python3 -c \
7675
"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')"
7776

78-
# Plan-tier metadata in JSON
7977
tj optimize --json | python3 -c \
8078
"import json,sys;d=json.load(sys.stdin);assert 'plan' in d and 'pricing_mode' in d;print('ok')"
8179
```
8280

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.
8484

8585
## 4b. TokenMaxx tier classification
8686

8787
```bash
8888
tj tokenmaxx
89-
# [ ] Bordered "TokenJam TokenMaxxing Report" panel renders
90-
# [ ] 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)
9389

94-
# Verify the JSON tier label is one of the six valid v0.3.4 tiers.
9590
tj tokenmaxx --json | python3 -c \
9691
"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:
9795

98-
# Reconfigure to a subscription plan and re-run — the multiplier line
99-
# should appear. Pick whichever plan matches your test config.
96+
- [ ] Bordered "TokenJam TokenMaxxing Report" panel renders
97+
- [ ] 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:
101+
102+
```bash
100103
tj onboard --claude-code --reconfigure --plan max_5x
101104
tj tokenmaxx
102-
# [ ] 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.
106105
tj onboard --claude-code --reconfigure --plan api
107106
```
108107

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.
110112

111113
## 5. Backfill adapters (smoke against committed fixtures)
112114

113115
```bash
114116
tj backfill langfuse --source-file tests/fixtures/langfuse_real_response.json
115117
tj backfill helicone --source-file tests/fixtures/helicone_real_response.json
116118
tj backfill otlp --source-file tests/fixtures/otlp_sample.json
117-
# Re-run any of them — must be idempotent
118119
tj backfill langfuse --source-file tests/fixtures/langfuse_real_response.json
119-
# [ ] "skipped N already present" on the re-run
120120
```
121121

122+
The final line re-runs langfuse to check idempotency:
123+
124+
- [ ] The re-run reports "skipped N already present"
125+
122126
If this machine has Claude Code history:
123127

124128
```bash
@@ -129,33 +133,35 @@ ls ~/.claude/projects/ >/dev/null 2>&1 && tj backfill claude-code
129133

130134
```bash
131135
tj cost --since 7d --compare previous
132-
# [ ] Current + Previous summary lines, cost/token delta lines
133136

134137
tj optimize --export-config claude-code
135138
ls ~/.config/tokenjam/exports/
136-
# [ ] claude-code-<date>.json file present
137-
# [ ] Contains "STRUCTURAL HEURISTIC ONLY" caveat comments
138139
```
139140

141+
- [ ] `--compare` prints Current + Previous summary lines and cost/token delta lines
142+
- [ ] A `claude-code-<date>.jsonc` file is present (it's JSONC — it carries comments)
143+
- [ ] It contains the "STRUCTURAL HEURISTIC ONLY" caveat comments
144+
140145
## 7. Policy list
141146

142147
```bash
143148
tj policy list
144-
# [ ] Table renders with POLICY / SETTING / SOURCE columns
145-
# [ ] "read-only preview" footer note
146149
```
147150

151+
- [ ] Table renders with POLICY / SETTING / SOURCE columns
152+
- [ ] "read-only preview" footer note
153+
148154
## 8. Server + Web UI
149155

156+
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+
150158
```bash
151159
tj serve &
152160
sleep 2
153161

154-
# HTTP fallback while server holds the lock.
155-
# Inject litellm into the pipx venv first (one-time per smoke run):
156162
pipx inject tokenjam litellm
157163
"$PIPX_PY" examples/single_provider/litellm_agent.py
158-
tj cost --since 1h # works via API fallback
164+
tj cost --since 1h
159165

160166
open http://127.0.0.1:7391/
161167
```
@@ -167,12 +173,12 @@ Spot-check:
167173
- [ ] Cost page shows non-zero USD values
168174
- [ ] Sidebar theme toggle works
169175

170-
### Offline-UI verification (v0.3.4 — PR #88)
176+
### Offline-UI verification (PR #88)
171177

172178
Open Chrome DevTools (or your browser's equivalent) → **Network tab** → reload `http://127.0.0.1:7391/`.
173179

174180
- [ ] **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
176182
- [ ] Favicon renders (data: URL, no external fetch)
177183

178184
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
181187
tj stop
182188
```
183189

184-
## 9. Cache cost-correctness (v0.3.4 — PRs #90 + #92)
190+
## 9. Cache cost-correctness (PRs #90 + #92)
185191

186-
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 fixed in 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.
187193

188194
```bash
189-
# Spans table now has cache_write_tokens (migration 5).
190195
duckdb ~/.tj/telemetry.duckdb "PRAGMA table_info(spans)" 2>/dev/null \
191196
| grep cache_write_tokens \
192197
&& echo "ok: cache_write_tokens column present"
193198

194-
# Any captured Anthropic cache-hit span should have non-zero cost_usd.
195199
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
198201
FROM spans
199202
WHERE cache_tokens > 0
200203
AND (input_tokens = 0 OR input_tokens IS NULL)
201204
AND (output_tokens = 0 OR output_tokens IS NULL)
202205
" 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
205206
```
206207

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.
208213

209214
---
210215

211216
## Claude Code integration (smoke)
212217

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+
213220
```bash
214-
tj onboard --claude-code --plan max_5x # substitute your actual plan
221+
tj onboard --claude-code --plan max_5x
215222
cat ~/.claude/settings.json | python3 -m json.tool | grep -E "OTEL_LOGS_EXPORTER|OTEL_EXPORTER_OTLP_ENDPOINT"
216-
cat ~/.config/tj/projects.json # current cwd present
223+
cat ~/.config/tj/projects.json
217224

218-
# Re-run is a quiet no-op
219-
tj onboard --claude-code --plan max_5x # substitute your actual plan
225+
tj onboard --claude-code --plan max_5x
220226

221-
# Backfill ran automatically during onboard — verify history is present
222227
tj cost --since 30d --agent claude-code-tokenjam || true
223228
```
224229

230+
- [ ] `settings.json` carries the OTEL exporter env; `projects.json` lists the current cwd
231+
- [ ] The second onboard is a quiet no-op
232+
225233
## Codex integration (smoke)
226234

227235
```bash
@@ -233,27 +241,29 @@ SERVER_SECRET=$(grep ingest_secret ~/.config/tj/config.toml | sed 's/.*= "//' |
233241
CODEX_SECRET=$(grep -oE 'Bearer [^"]+' ~/.codex/config.toml | sed 's/Bearer //')
234242
[ "$SERVER_SECRET" = "$CODEX_SECRET" ] && echo "ok: secret synced"
235243

236-
# If codex CLI is installed
237244
codex exec "say hello" 2>/dev/null && tj traces --agent codex_exec
238245

239246
tj stop
240247
```
241248

249+
- [ ] `ok: secret synced` prints (the Codex Bearer token matches the server's ingest secret)
250+
- [ ] If the `codex` CLI is installed, a `codex exec` run shows up under `tj traces --agent codex_exec`
251+
242252
---
243253

244254
## Pass criteria summary
245255

246256
| Step | Pass criteria |
247257
|------|--------------|
248258
| 1 | `pipx install --force tokenjam` succeeds, version matches release |
249-
| 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 |
250260
| 3 | Example runs without DB-lock errors; CLI shows real USD values |
251261
| 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 |
253263
| 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 |
255265
| 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** |
257267
| 9 | `cache_write_tokens` column present on the spans table (migration 5); cache-hit spans show non-zero cost_usd |
258268
| Claude Code | Onboard writes settings.json + projects.json; re-run is a no-op |
259269
| Codex | Onboard writes `[otel]` + `[mcp_servers.tj]` to codex config; secret synced |

0 commit comments

Comments
 (0)