What it is
Your coding agent already writes down everything it does. Every tool call, every retry, every token, every wall-clock gap — sitting in JSONL on your disk, rotating away on a timer, read by nobody.
ratchet reads it. It ingests those transcripts into SQLite, prices them against a date-keyed rate table, detects six recurring shapes of friction, and ranks the hotspots by what they actually cost you. The point is not a dashboard. The point is that the next agent to open your project can query what went wrong last time instead of rediscovering it.
Everything stays on the machine. Transcripts are stored verbatim in a local SQLite file and never leave it. There is no service, no account, no telemetry, and nothing to opt out of. The only tier designed to be portable is the derived findings layer, which holds shapes — never your paths, commands, or project names.
The six signatures
These are not lint rules. Each one is a shape that showed up repeatedly in real agent transcripts and cost real time:
| Signature | What it catches |
|---|---|
WAIT | A call far above its own tool's median duration. The slow thing you stopped noticing. |
REPEAT | The same region of a file read again with no edit between. Context that should have been held. |
PAGING | Different regions of one file read in sequence — too large to hold in a single read. It indicts the file, not the agent: the fix is an index or a split. |
REPHRASE | A run of consecutive searches with no edit between them. The tool or the store is mis-shaped. |
SERIAL | Long runs of single-call read-only turns. Independent work that never got batched. |
CEREMONY | A call fails, then the same command is retried with a tweak. Steps that serve the tool, not the goal. |
Quick start
macOS, Apple silicon or Intel. No Rust toolchain needed:
curl -fsSL https://ratchet.daystra.com/install.sh | sh
That installs two tools — ratchet, and atlas (below) — each a published build
whose SHA-256 is verified before anything is written, installs them to
~/.ratchet/bin, adds that to your PATH, registers both MCP servers,
and registers a launchd job that ingests every 30 minutes. A missing checksum entry is a hard
failure, not a skip — "nothing to verify" and "verified" must never reach the same branch.
Everything lives under $HOME; nothing needs sudo. The store is
~/.ratchet/ratchet.db, logs are in ~/.ratchet/logs/, and the schedule
is ~/Library/LaunchAgents/com.cybercussion.ratchet.plist. Open a new terminal (or
exec $SHELL -l) after installing.
It also verifies the job is really loaded before claiming success, and if it can't schedule the new one it restores the schedule it replaced. An install that can't move you forward should at least not move you backward.
# pin either tool alone, skip scheduling, or leave PATH alone
VERSION=0.3.9 curl -fsSL https://ratchet.daystra.com/install.sh | sh
ATLAS_VERSION=0.1.2 curl -fsSL https://ratchet.daystra.com/install.sh | sh
RATCHET_NO_SCHEDULE=1 curl -fsSL https://ratchet.daystra.com/install.sh | sh
RATCHET_NO_PATH=1 curl -fsSL https://ratchet.daystra.com/install.sh | sh
Then, at any time:
ratchet report # the human summary
ratchet hotspots # ranked friction, machine-readable
ratchet doctor # health contract; non-zero exit when something is wrong
ratchet enabled # what agents can actually reach on this machine
ratchet update # self-update of BOTH tools, checksums verified in-process
atlas <word> # code lookup in whatever project you are standing in
Building from source instead? Clone the tree and run scripts/dev-install.sh,
which compiles locally rather than downloading.
The second tool: atlas
The same installer lands atlas — a stdlib-only, single-file manifest of
pointers for whatever codebase you are standing in: declarations, name substrings, file
paths, path routes, endpoints, config keys. atlas <any word> from anywhere
inside a project — no verb, no setup, no index checked into your tree. Every answer carries
a file:line verified against disk at answer time; an empty answer means the live
tree was already grepped; and every answer ends with a footer naming what was searched, what
was not, and what this build does not model at all.
Independently versioned on purpose (currently v0.1.7) — pin it alone with
ATLAS_VERSION=, opt out with RATCHET_NO_ATLAS=1. Full reference:
ATLAS.md.
Why the numbers are different
Cache reads are not input tokens
Collapsing the four token buckets into "input" and "output" is the single largest source of wrong cost figures. On the corpus this was built against, cache reads outnumbered uncached input tokens by roughly a thousand to one — and they bill at a tenth the rate. Price that store naively and the total comes out 6.7× too high. Same data, same rate card, one modelling decision.
Unknown is never free
When ratchet cannot price something, the cost is NULL — never 0.
A zero would quietly vanish into every total and understate real spend, which is the one
thing a cost tool must never do. Rates are keyed by date and immutable: an action from
January prices at January's rate even after a July rate lands in the same table.
It tells you when it is lying
Every report ends with computed caveats about its own output. Not boilerplate — conditions it checks each run:
- Approval wait is not machine time — most harnesses state a real duration
for almost nothing, so a "slow call" figure is usually an elapsed call→result gap that
includes however long a permission prompt sat unanswered. Those rows are labelled
derived_upper_bound: a ceiling on machine time, never an execution cost. This correction demoted the store's #1 "slow tool" from 8.9 hours to 37 minutes — the median grep was 197 ms all along. - Suspicious duration — a hotspot averaging over 15 minutes per call is far more likely to be a gap where you walked away than real tool latency. It is shown, not suppressed, and labelled as unverified.
- Blind harness — a harness whose records this build can capture but not model is announced, so its absence from the rankings never reads as zero friction.
- Occurrence floor — signatures below the minimum count are dropped from rankings, and the report says exactly how many were dropped. Invisible, not absent.
- Single machine — one laptop cannot distinguish a fleet-wide property from a local habit. It says so, every time.
That last one is not hypothetical. Run across two machines, the top time-eating verb on one did not appear in the other's top twelve at all. What generalises is the shape — "your top verb eats hours" — never the specific verb.
Three tiers
| Tier | Contents | Leaves the machine |
|---|---|---|
raw_record | Your transcripts, verbatim | Never |
action | Normalized and priced | Never |
finding | Derived shapes only | By design |
Keeping raw records is what makes coverage retroactive. Add a model to the rate table a month from now and the history already on disk reprices itself — nothing is stranded at the value it happened to have when it was first seen.
Built for agents
Both tools speak MCP (ratchet mcp-server, atlas mcp-server) and are
registered at install. ratchet_context is the one-call orientation — health,
coverage, top hotspots by count and by time, trend gates, findings — and
ratchet_orient serves the same <ratchet-orient> packet a
SessionStart hook (ratchet hook install) can inject at the top of
every Claude Code session: the project's measured working set, traps, real median command
times and import hubs. Computed from the store, never authored, ~2 KB, and silent when
there is nothing measured to say.
ratchet agents-block --write --all pastes the teaching blocks into every measured
project, ratchet skill --write installs user-scope Claude Code skills, and
ratchet enabled --projects audits what agents can actually reach — never exiting
non-zero, because an un-enabled project is a normal state, not a fault.
Status
ratchet v0.6.4 · atlas v0.1.7. macOS. 711 tests. Modelled harnesses: Claude Code, Codex, Grok, Rift, Antigravity; Gemini CLI is captured raw and reported honestly as blind until normalizers exist. It is a tool built to answer a specific question — where is my agent wasting time — and it is deliberately more willing to say "I can't measure that" than to print a confident number it cannot support. History: CHANGELOG.md · field results: RESULTS.md · agent quick-start: llms.txt.