RATCHET

Agent friction, measured.

A mechanism that only turns one way. This one watches your AI coding agents work, finds where they keep hurting themselves, and makes it hard to slip back.

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:

SignatureWhat it catches
WAITA call far above its own tool's median duration. The slow thing you stopped noticing.
REPEATThe same region of a file read again with no edit between. Context that should have been held.
PAGINGDifferent 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.
REPHRASEA run of consecutive searches with no edit between them. The tool or the store is mis-shaped.
SERIALLong runs of single-call read-only turns. Independent work that never got batched.
CEREMONYA 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:

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

TierContentsLeaves the machine
raw_recordYour transcripts, verbatimNever
actionNormalized and pricedNever
findingDerived shapes onlyBy 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.