By Kodelyth · · 6 min read
RTK makes the shell output that goes into the model smaller. Terse mode makes the output that comes out of it smaller. The governing rule is one line:
Make the AI's mouth smaller, not its brain smaller.
Same answers. Fewer words. Code byte-exact. The savings are real — output tokens aren't cached by the provider, so there's no cache discount hiding the benefit — but ECC still ships two different things under the name "terse," and only one of them is measured. This post is about telling them apart, and about when terse actually loses.
The dial
Type /terse [level] in your AI tool. The level sticks for the session. The
same fix, at four settings:
| Level | Style | Approx |
|---|---|---|
off | normal voice | 0% |
lite | drop filler ("basically", "essentially") | ~25% |
full | Telegram-style fragments (default) | ~50% |
ultra | maximum, symbols over words | ~70% |
Normal: The reason your React component is re-rendering is likely because you're creating a new object reference on each render cycle... I'd recommend using useMemo to memoize the object.
Full: New ref each render → re-render. Wrap object in
useMemo.Ultra: Ref/render.
useMemoit.
The percentages are approximate by design — how much you save depends on how much filler the answer had to begin with.
What it never touches
Byte-preserved at every level: fenced code blocks, inline code, shell commands
and error text, URLs, file paths, identifiers, numbers, versions, hashes, and
YAML/JSON. The reason is obvious once stated — a shortened command is a wrong
command, and a wrong command is worse than a verbose correct one. Terse
compresses the prose around the technical payload, never the payload.
Two things named terse — and only one is measured
This is the distinction that matters, and the one most "N% savings" claims blur.
- The runtime skill compresses the AI's replies. Session-scoped, triggered
by
/terse. Its savings are estimated. - The file compressor compresses markdown files on disk —
CLAUDE.md,tasks/lessons.md, rule files. Permanent. Its savings are measured.
ECC labels both for what they are, rather than quoting the bigger number and hoping you don't ask.
The file compressor reports real bytes
kodelythecc terse compress <file> runs a deterministic, zero-dependency
rewriter: it strips 40+ filler patterns, converts wordy connectives to compact
ones, merges wrapped prose, and removes politeness padding — while byte-preserving
code, YAML frontmatter, inline code, URLs, and paths. Because there's a real
before and a real after, the stats are measured, not modeled:
const { compressText } = require('kodelyth-ecc/scripts/terse/compress.js');
const { output, stats } = compressText(source);Run on a prose sentence that happens to contain a command and a path:
IN: In order to fix the bug, you should basically just wrap the object in
useMemo. Due to the fact that React re-renders, essentially a new reference
is created. Please note that the command is `npm run build` and the path
is ./src/app.tsx.
OUT: to fix the bug, just wrap the object in useMemo. because React re-renders,
a new reference is created. the command is `npm run build` and the path is
./src/app.tsx.
STATS: { originalBytes: 236, newBytes: 164, saved: 72, savedPct: 31,
estimatedTokensSaved: 18 }in order to → to, due to the fact that → because, "you should" and
"please note" gone — and npm run build and ./src/app.tsx untouched. It's
deterministic (same input, same output, safe to re-run) and on real prose-heavy
markdown lands around 30% byte reduction with 100% code/URL/path integrity.
Point it at the files injected into every session and the saving compounds.
The runtime ledger says "estimated" on every row
The runtime side cannot measure the same way, and doesn't pretend to. There is no
non-terse copy of a given reply to diff against, so saved is modeled: the
actual output tokens times a per-level baseline multiplier.
const RAW_MULT = { lite: 1.33, full: 2.0, ultra: 2.85, off: 1.0 };
// rawEstimate = actual * RAW_MULT[level]; saved = rawEstimate - actual;Those multipliers are assumptions — "full is about 2x the terse size" — not
measurements. So every ledger row carries "estimated": true, and the docs say
it outright: for measured (not estimated) savings today, use the file compressor.
On top of that, automatic per-turn recording isn't wired on the main path yet, so
the runtime ledger only fills when a turn is explicitly recorded. An honest
dashboard shows the estimate labelled as an estimate, which is exactly what this
one does.
When terse is net-negative
Terse is not free, and it's worth knowing when it loses. The failure mode is a
reply compressed so far that the reader can't act on it and has to ask a
clarifying follow-up. That follow-up isn't cheap: the next turn re-bills the
entire input context — the whole conversation so far — which can dwarf the
handful of output tokens ultra just saved. One avoidable round-trip costs more
than the compression bought.
So the sweet spot is narrow and real: lite or full for a fluent user who
reads fragments fine. ultra on genuinely explanatory content, or any level for
someone who needs the prose to follow the answer, can cost more than it saves.
Terse changes how the AI talks, which is why it stays dormant until you type
/terse — it's a per-session, user-consented choice, not a default.
Using it
/terse full # in your AI tool — set the runtime level
/terse off # back to normal voice
kodelythecc terse compress CLAUDE.md # measured file compression, in place
kodelythecc terse stats # runtime ledger (estimated, and says so)Terse mode is MIT, inspired by (not copied from) Caveman. The compressor and ledger are dependency-free Node in scripts/terse. Full reference in Terse Mode; the input-side companion is RTK.
npm i -g kodelyth-ecc && kodelythecc