#SplitRail
knock me over like a leased Lexus through a splitrail fence 😭
September 15, 2026 at 4:55 PM
One quilt sandwich down. Now this...will be a project. It's a king sized quilt and I don't have enough space to lay it flat anywhere. Might run to the dollar store tomorrow and see if they have any pool noodles. This will be a learning experience #quilts #quilting #splitrail or #brokenfence ?
November 24, 2024 at 1:00 AM
AI transparency tools like Splitrail are great for optimizing agent efficiency across different platforms - an important step towards more practical and impactful AI usage in real apps.
June 20, 2026 at 1:32 AM
Good morning, bee balm! Walking along the ‘Wedges at Oakley’ (fence around the back yard)

#MorningWalk #GoodMorning #BeeBalm #Fence #Wedge #SplitRail #Winter #Snow #Nature #Garden #Chancellorsville #SpotsylvaniaCounty #Virginia
January 14, 2025 at 12:36 PM
This free tool shows you exactly what your AI agents cost you 🤯

Splitrail tracks token usage across Claude Code, Codex, Gemini, Cline, Roo Code, Kilo Code, OpenCode, and more — all in one dashboard. Real-time cost tracking.

#automation #claudecode #codex #gemini #aitools
June 19, 2026 at 2:21 PM
This time 30 years ago, I was surrounded by every news network and law enforcement agency in the United States. At the time, I was the only passenger of Amtrak's Sunset Limited who knew our train had been sabotaged because I'd found 2 of the notes left by terrorists. #Splitrail #History #Truth
October 9, 2025 at 4:28 PM
An append-only audit log caught two accounting bugs in a 216-star usage tracker
Last month I wrote about auditing 34 days of multi-model Claude Code usage and finding that a single missing model line was half my overspend. The core of that piece was a boring engineering decision: ingest every assistant message from Claude Code's session files into an **append-only log keyed by`message.id`**, and never let the source rewrite history. This is the follow-up I didn't plan to write. The same log just caught two accounting bugs in splitrail, a 216-star Rust usage tracker for agentic CLIs — and within twelve days of the first report, both were fixed in an official release: one through my PR, one through a maintainer-authored patch that adopted the report's analysis. Here's the play-by-play, with the numbers. ## Bug 1: your history quietly rewrites itself Claude Code rewrites session JSONL files in place when you resume or compact a conversation. Between two scans of the _same file_ , five of my assistant messages vanished — usage that was already incurred, gone from the record. Any tracker that recomputes totals from live files inherits this drift: yesterday's numbers change while you sleep. I filed it as #200. The maintainer confirmed the mechanism the same day — splitrail re-read live files, so messages removed by resume/compaction disappeared from historical totals — and shipped a fix in 3.6.0: a local SQLite history store that persists normalized usage and merges it with current session data before deduplication. Fast, clean work. One wrinkle: he suggested validating by comparing 3.5.9 vs 3.6.0 totals, expecting "3.6.0 should be higher." That's subtly wrong, and the distinction matters for anyone testing this class of fix: **on a cold start the two versions are equal** — the history store has nothing to restore yet. The divergence only appears _across_ drift events. So I built the test to create one. ## The validation protocol Everything ran against a frozen snapshot (APFS clone) of `~/.claude/projects`, so both versions scanned identical bytes, with every invocation under an isolated `$HOME` — own config, own history store, no upload path. Then: # | assertion | result ---|---|--- A | cold-start parity: fresh 3.5.9 == fresh 3.6.0 on identical input | ✅ identical B | 3.5.9 across a simulated resume/compact rewrite | ✅ drops by exactly the removed usage C | 3.6.0 across the same rewrite | ✅ totals unchanged — history store restores D | 3.6.0 restart stability, 3 consecutive runs | ✅ byte-identical output The simulated rewrite removes the last five assistant message-groups from the largest transcript — the same shape as the original drift event. The whole thing is now a self-contained regression fixture (PR #208, since merged): it fails red on 3.5.9 and passes green on 3.6.0, which is exactly what you want a regression test to do. The part I care most about: on the transcripts splitrail scans, 3.6.0 agreed with my append-only log **token-exact — 18,548,947 output tokens on both sides** across 13.5k messages. Two independent implementations, different languages, different dedup strategies, same number to the digit. (The tiny message-count delta was zero-usage api-error records splitrail intentionally skips.) When two systems reconcile exactly, every remaining discrepancy is a _finding_ , not noise. ## Bug 2: the discrepancy that was a finding Because the log records where every message came from, I could classify all of them against the live tree: class | files | messages | output tokens ---|---|---|--- live, main transcript (what splitrail scans) | 76 | 13,704 | 18,548,947 live, `subagents/**` transcript | 1,423 | 16,160 | 13,738,324 vanished (file exists, message.id gone) | 0 | 0 | 0 deleted (session file gone) | 874 | 11,821 | 14,238,006 Row two is the second bug. Claude Code writes subagent transcripts (Task tool: Explore, general-purpose, custom agents) under `projects/<slug>/<sessionId>/subagents/`, at directory depth ≥ 4. Splitrail's discovery hard-caps at depth 2 in three places (`WalkDir…min_depth(2).max_depth(2)`, a `components() == 2` path check, and the glob pattern). Those files are structurally invisible — **54% of my live messages, and roughly a third of the dollars, never entered any total**. The model mix makes the blind spot vivid: splitrail saw 22 of my 5,059 Sonnet messages and 0 of 1,566 Haiku messages. Those models run almost exclusively inside subagents. If you delegate heavily to cheap models — which is exactly what cost-conscious agent users do — your tracker undercounts the most, on the workflows you optimized hardest. Filed as #207 with the layout, a two-line repro, and a suggested fix. Two days later it was closed — and not by my patch. The maintainer wrote the fix himself: #209 "Include Claude Code subagent transcripts" (+428/−100 across seven files), whose description restates the issue's analysis and adopts its central caution — simply lifting the depth cap isn't enough; subagent records have to flow through the same `local_hash` dedup semantics as main transcripts, or you trade an undercount for a double-count. Both fixes shipped together in **splitrail 3.6.1** , which hit Homebrew within a day. On my corpus, the newly visible class is row two of the table above: 16,160 messages and 13.7M output tokens finally entering the totals. A fresh 3.6.1-vs-log reconciliation of the live tree is the obvious next check — part 3 starts there. ## What I'd generalize **Live mutable files are not an audit trail.** If your source can rewrite history, recomputation is not accounting. Append-only ingest with a stable per-record identity (`message.id`, last-write-wins on partials) is cheap insurance — mine is a few hundred lines and a SQLite file. **Reconcile token-exact or you know nothing.** "Close enough" totals hide entire bug classes. It was exact agreement on the scanned subset that turned the remaining gap into two nameable, fixable defects instead of a shrug. **Decompose the gap before you blame anyone.** "Your numbers are lower than mine" is an accusation; _"the gap is exactly deleted-files + an unscanned directory class, here's the table"_ is a bug report a maintainer can act on in hours. Both turnarounds here — #200→#204 in eight days, #207→#209 in two — happened because the mechanism arrived with the report. **Frozen snapshot + isolated`$HOME` is the whole trick for tracker A/B.** Clone the data, pin `HOME` (and `XDG_STATE_HOME`/`XDG_DATA_HOME` — on Linux, state dirs honor XDG and will escape your sandbox; CodeRabbit's review caught that one in my own fixture, fair is fair), and two binaries scanning identical bytes become a controlled experiment. ## Timeline date (2026) | event ---|--- Jul 11 | #200 filed — resume/compact rewrites session JSONL in place Jul 19 | #204 merged; **3.6.0** ships the SQLite history store Jul 20 | 4-assertion A/B validation on a frozen corpus; token-exact reconciliation vs the audit log Jul 21 | #207 filed (subagent blind spot); PR #208 opened; CodeRabbit review round addressed same day Jul 22 | PR #208 merged Jul 22–23 | Maintainer authors and merges #209; #207 closed; **3.6.1** released, Homebrew bumped Twelve days, two bugs, zero arguments about whose numbers were right — the log settled every question before it became a debate. ## The layer underneath All of this ran on TraceGuard's `routing_audit` module (v1.1.0, "audit evidence layer") — the append-only, message.id-keyed ingest of Claude Code transcripts into a SQLite trace store that part 1 was built on. Stable totals are the substrate; the point of the layer above is **stated-vs-revealed routing analysis, priced per decision** — which model you _said_ you'd route to, which one actually ran, and what the difference cost. That's part 3, and my totals finally sit still long enough to write it. (Apparently not a niche itch, either — the splitrail maintainer starred TraceGuard during this exchange and said he'd be interested in the audit part.) _`pip install traceguard` — Apache-2.0. The regression fixture is ~600 lines of stdlib Python + bash, merged in PR #208; the subagent fix shipped in splitrail 3.6.1._
dev.to
July 25, 2026 at 2:29 AM
🍻 splitrail 🍻

Real-time token usage tracker and cost monitor for CLI coding agents

🔗 https://splitrail.dev/

#homebrew #newpkg #macos #linux #formula
June 22, 2026 at 2:21 PM