| name | output-compress |
| description | Tiered output compression (caveman-derived): an explicitly opt-in, token-saving rewrite mode with a never-compress whitelist, model-tier compression caps, and a deterministic fidelity gate (no LLM self-judgment). Use when the user types output-compress, /compress, "compress lite|full|ultra", or asks to shorten/condense internal or scratch output. Do NOT use for: the final user-facing response language, safety/irreversible-action confirmations, contract fields (Goal/Non-goals/Done-when/Return), audit or review findings that must stay verbatim, or as a default/always-on behavior. |
| metadata | {"version":"1.5.0"} |
Output-Compress â tiered, whitelist-safe, mechanically verified compression
Origin: github.com/juliusbrussee/caveman compression syntax. This version fixes the
upstream's two gaps â no fidelity scoring, no model-tier calibration â by adding a
never-compress whitelist, a tier-capped compression matrix, and a deterministic
fidelity-check script. Compression is opt-in, never default. The fidelity check
is deterministic â it is never model self-judged.
Usage
/compress <level> [scope] â level is one of lite | full | ultra. scope defaults
to internal output from this point forward (scratchpad text, sub-agent intermediate
output, the body of a mechanical report). If no level is given, use the cap for the
current reader tier (see §2). This skill is never applied automatically â it must be
explicitly invoked per turn or per scope.
1. Compression levels
| level | rule | expected savings |
|---|
lite | strip filler words / pleasantries / throat-clearing only; keep full sentences and articles | low |
full | + drop articles, allow sentence fragments, lead with the result then explain | medium â measured ~13% bytes saved on CJK prose (n=13, gate-verified organic sample; earlier n=4 informal sample showed 15-18%); upstream's ~65% self-report is for English-style text, which has more articles/filler words to strip than CJK does, so English-heavy output may land closer to the upstream figure than CJK does |
ultra | + drop connective words (only in sentences outside the whitelist) | high â fidelity risk rises with it (see §4 gate) |
A stylized "telegraphic" mode that changes the response's natural language (e.g. classical-register rewrites) is explicitly out of scope for this skill â it conflicts with keeping the final user-facing response in the user's normal language. Add it as a separate opt-in mode if you need it.
Two ledgers â output tokens vs input tokens. Compression pays off in two distinct ways;
know which one you're buying before you spend the effort:
- Disposable text (a status note, an intermediate answer nobody will re-read): just
write it short in the first place â that saves output tokens directly, and there is no
original to diff so the fidelity gate doesn't apply.
- Persisted text (logs, memory files, reports, sub-agent prompts that future turns
re-read): use the full three-step flow (compress â gate â persist). This costs a little
output now but buys input-token savings on every future read â and the gate is mandatory
because a lost detail here compounds across sessions.
Mixing these up wastes effort: gating disposable text adds overhead for nothing, and
skipping the gate on persisted text trades permanent fidelity for a one-time saving.
Single-use dispatch prompt ruling (which ledger a one-shot sub-agent prompt belongs
to was previously undecided â decided here): a prompt that will be sent once and not
re-read may be generated directly in already-compressed style, skipping the
original+compressed+gate flow, only if every contract field
(Goal/Non-goals/Done-when/Return or this project's equivalent naming) is written
verbatim in full â i.e. compress everything around the contract fields, never the
fields themselves. If you are not confident the contract fields will survive
untouched, use the full original+compressed+gate flow instead; do not skip the gate on
a prompt whose contract fields you also intend to compress.
2. Model-tier compression caps
Weaker models reconstruct meaning from fragments less reliably, so they get a lower cap; stronger models can absorb more aggressive compression and still recover intent.
| reader tier | cap | rationale |
|---|
| small models (Haiku-class) | lite | weak fragment/ellipsis reconstruction; these models generally need more explicit, step-level guidance, which compression works against |
| mid-tier (Sonnet-class) | full | this is the tier caveman's default level was originally calibrated against |
| frontier (Opus/GPT-5-class) | ultra | strong enough to recover elided connectives and implicit structure |
| any model not yet calibrated | start at lite | run 5-10 representative tasks and check the fidelity gate before raising the cap for that model |
"Reader" = who consumes this text, not who produces it. A sub-agent prompt's reader is
the worker model's tier; a log or memory file's reader is any future session at any tier,
so use the lowest common tier (lite) for anything long-lived. This matrix is derived
from general reasoning about model capability, not from local measurement â calibrate
it against your own fidelity-gate failure rate before trusting the caps as-is.
Coverage ćçœźć€æ· (pre-check before compressing): before compressing an agent-dispatch
prompt or archival/log text, run <output-compress>/scripts/fidelity-check.py --coverage --original <file>
and follow its recommendation (skip / lite / tier-cap, thresholds â„40% / 20â40% /
<20% whitelist-covered bytes) rather than defaulting straight to the reader-tier cap.
These thresholds are provisional (n=2, 2026-07-12): whitelist-dense dispatch prompts
saved only 6.8% at ultra and 2.4% at full after gate retries â for that kind of
text, the expected saving is often smaller than the cost of a gate round-trip, so
checking coverage first can save you the compressâgateâretry cycle entirely.
3. Never-compress whitelist (fidelity gate's comparison baseline)
- Code blocks / inline code / URLs / file paths (including bare filenames like
deploy.log â card7 2026-07-12) / commands and their output / env vars (assignment form NAME= â the bare-acronym match was card1's false-FAIL source)
- All numbers (percentages, amounts, version numbers, line numbers â embedded in prose too); dates compared as whole tokens and repeated values must keep their occurrence count (multiset, card2 2026-07-12)
- Negation words AND quantifier bounds, with their entire clause scope (not/never/unless/except/no/cannot + at most/at least/up to/no more than, and local-language equivalents) â dropping a bound turns it into an exact value, the same silent flip as dropping a negation (card3 2026-07-12)
- Structured tags your project uses for provenance/status/review markers (e.g.
[STATUS], ticket IDs, evidence-level flags) â list your own patterns in the fidelity-check script's CUSTOM_TAG_PATTERNS
- Safety-critical statements (irreversible-action confirmations, incident/priority-0 report language) â never compress these at all; this whitelist entry is a second line of defense on top of the "do not use" rule above
- Contract fields (Goal / Non-goals / Done-when / Return {} or equivalent
handoff-contract structure) â skip these as whole blocks, never compress them
sentence-by-sentence. Evidence: a field run compressed a Done-when block clause by
clause and deleted an inline verification command embedded inside it; the gate
caught it, but the failure mode was treating a contract field like ordinary prose
instead of skipping the entire field untouched (2026-07-12).
- Hedges/qualifiers â occurrence count must not decrease (only / may / provisional /
unverified / tentative / estimated / caveat / assume(s/ing) / subject to, and
local-language equivalents; word-list SSoT =
HEDGES in
scripts/fidelity-check.py). "The evidence survived but the caveat needed to
interpret it was stripped" is a named second fidelity axis â
decontextualization (arXiv 2606.29251: LLM compression can flip which decision
the original text supports) â and is treated at the same severity as a dropped
negation (added 2026-07-17).
4. Fidelity gate (mechanical, run after every compression)
python3 "${CODEX_HOME:-$HOME/.codex}/skills/output-compress/scripts/fidelity-check.py" \
--original /tmp/orig.txt --compressed /tmp/comp.txt
The script extracts each whitelist category via regex from both versions and diffs the
two sets â it is not an LLM judge. This avoids the noise and inconsistency that
comes from asking a model "does this still mean the same thing" (which is exactly the
self-judgment pattern this skill is designed to replace). Before any compressed output
is persisted (a log, a memory file, a saved report), show the fidelity-check output
alongside it â don't persist compressed text on a bare claim of "still accurate."
Compression is deletion, not rewriting. The only allowed operations are: strip
filler words, drop articles, drop redundant connectives, cut sentence fragments. Never
rephrase a sentence to make it shorter â paraphrasing risks silently swapping which
literal words carry a whitelisted element, most often negations. Example: rewriting
"rather than X" into "does not include X" replaces one negation word with a different
one; the gate correctly flags this as a lost element (the original negation word's
count dropped), but the deeper problem is that the rewrite was unnecessary risk in the
first place â a pure deletion pass never has this failure mode. If a sentence needs to
be reworded (not just trimmed) to get shorter, leave that sentence uncompressed.
Negation-first ordering (2026-07-17): as the first compression step, enumerate
every negation/quantifier-bound clause (whitelist item 3) and lock those sentences
whole, then run the deletion pass over the remaining text. Field logs (2026-07-12)
showed 3/3 first-round full-level dispatch-prompt compressions failing the gate on
negation_counts alone; front-loading the lock eliminates that fixed retry round
without touching the gate's thresholds.
Rewrite â delete, even for a single word: a field run rewrote Provide at least: into
Min set: â shorter, but it silently dropped the quantifier bound at least,
turning a minimum into an unqualified list. The gate correctly intercepted it
(2026-07-12). Compression may only delete tokens that are already there; substituting
a shorter phrase for a longer one is rewriting, not compression, even when it looks
like a trivial word swap.
Add --log --level <L> --context <C> to also append a JSONL record to
compress-log.jsonl (path configurable via --log-file) â see the script's --help
and §5 below for what the log is for. Each record includes grounded_pct: the
fraction of the compressed text's word-level tokens that appear in the original (a
deterministic groundedness proxy borrowed from arXiv 2503.19114's measurement idea).
Under the deletion-only rule it should sit at ~100; a drop means rewriting/generation
crept in â it is the second measurement axis alongside saving_pct.
Gate efficacy (field run, 2026-07-12): 2/2 true-positive fidelity FAILs caught (a
dropped quantifier, a deleted inline verification command), 0 false-positives, both
fixed and re-passed on the first retry â the mechanical (non-LLM-judge) approach held
up under real dispatch-prompt compression, not just synthetic test cases.
4b. Delegating compression to a cheaper model (optional)
Splitting the work: deciding which sentences are deletable is a judgment call and can
be delegated to a cheap/small worker model; the fidelity gate is a deterministic check
and must always be run by the orchestrating agent itself, never by the worker
(a producer must not verify its own output â a worker's "gate passed" claim is not
evidence; the orchestrator's own fidelity-check output is).
Executor-tier policy: prefer a cheap model as the compression executor and avoid
having a frontier model self-compress long text â not only for cost: arXiv 2602.09789
(the "scaling paradox") measured that larger compressor models are less faithful,
preferring their own semantic priors over the source text. Cheap executor + mechanical
gate is independently supported by that result.
Delegate only when all three hold, otherwise compress inline: â the text will be
persisted (not disposable); ⥠the original is â„4KB (below that, handoff overhead
exceeds expected savings â whitelist-dense text saved only 2.4â6.8% in field runs);
âą the --coverage pre-check does not say skip. Flow: orchestrator runs
--coverage to pick the level â spawns the worker with the original's path, the full
§3 whitelist, the deletion-only + negation-first rules, and the target level â the
orchestrator itself runs fidelity-check.py (+ --log, tagging context as
delegated-<original context> so delegated and inline runs can be compared) â pass
persists, fail falls back to the original text (no re-delegation â a re-compress
round-trip costs more than it saves).
5. Calibration and known limits
- Treat your own logged savings numbers as observations, not commitments: the sample
is self-selected (only runs where the model chose to compress and chose to log get
recorded, and under advisory auto-activation the execution rate can silently be
zero), so always quote them with that qualifier.
- The 65% savings figure in §1 is the upstream project's self-reported number from a
single model on English text; treat it as a rough prior, not a local guarantee, until
you've run your own before/after comparison on a handful of representative tasks. The
one local measurement so far (§1, CJK prose) landed well below it.
- A single lost number or negation typically costs several times its saved tokens once
you account for the back-and-forth needed to catch and re-ask for it â reserve
ultra
for output you can afford to discard/regenerate, not for anything a decision depends on.
- Run compression with
--log and periodically inspect compress-log.jsonl's pass,
missing_keys, and saving_pct fields: a levelĂcontext combination with a high
failure rate is a signal to lower that combination's cap (§2); a saving_pct that
stays low for a given context is a signal that compression isn't worth the fidelity
risk there. This applies to both passing and failing runs, so keep logging failures
instead of silently discarding them.
Known limits (carried over from the source implementation)
- The
path regex can miss bare directory names embedded in non-Latin-script prose
(no file extension to anchor on) â spot-check path-heavy text manually before
persisting compressed output at file scope.
- Negation fidelity is checked by "count does not decrease," which cannot detect a
negation word surviving while its clause's scope silently changed â for anything
where a negation carries real logical weight, use
lite or skip compression.
- The hedge list (whitelist item 7) is deliberately conservative to keep the
false-FAIL rate low; lowercase modal
may is protected, while month-name May is
ignored to avoid date false positives. It will not catch every stripped qualifier. Extend HEDGES
with your own language's hedge words, preferring multi-word phrases.
Auto-activation (optional)
See USAGE.md §7 for wiring this skill to run automatically every turn (a
UserPromptSubmit-style hook for Claude Code, an always-loaded AGENTS.md section for
Codex) instead of invoking it manually per conversation.
Pace-aware level adjustment (optional)
If your environment exposes a usage-pacing signal (e.g. a hook that compares actual
quota burn against elapsed window time and emits AHEAD / ON_PACE / BEHIND verdicts),
you can couple it to compression levels:
- AHEAD (burning quota faster than the window is elapsing): bump the compression
level by one, within the reader-tier cap from §2 â never for small-model readers,
whose cap is
lite for fidelity reasons, not budget ones.
- ON_PACE / BEHIND: revert to the default level. Compression above the default is
a budget lever, not a permanent setting.
- Always log pace-driven bumps (
--log, keep the level field): periodically
compare the fidelity-gate failure rate of pace-bumped runs against normal runs â if
the bumped group fails noticeably more, drop the coupling; the budget saving isn't
worth the fidelity loss.
A portable reference pacer ships as scripts/usage-pacer.py (bring your own usage
JSON â schema in its docstring; includes a once-per-window user-notification arm and a
self-test). Provider-specific official-usage feeders ship alongside it:
scripts/claude-usage-fetch.py for Claude subscriptions and
scripts/codex-usage-fetch.py for Codex/ChatGPT sessions. Each refreshes the same
neutral JSON file before the pacer runs, while the pacer itself stays provider-neutral.
Hook wiring with the injection-diet rules is in USAGE.md §7. Keep the two
responsibilities separate: the pacer decides when, this skill decides how much, and
the fidelity gate stays the final arbiter either way.
Absolute-threshold escalation (orthogonal to pace verdicts): independent of the
AHEAD/ON_PACE/BEHIND burn-rate verdict above, the pacer also tracks raw quota level â
used_pct >= 80% bumps compression one level within the reader-tier cap; >= 95% jumps
straight to the cap. This fires even when ON_PACE (a window can be right on schedule
and still be at 83% used). Dedup on state change belongs to the injecting hook, not the
pacer â see compress/compress_msg in its output schema.
Handoff-aware pacing (nearly-exhausted window): when used_pct >= 90% and
< 0.5h remains, the pacer emits HANDOFF_PREP or the circuit-breaker
HANDOFF_HALT. These verdicts decide when to preserve work; hook execution and host
scheduling are not deterministic.
Codex's v1.4.1 helper is packet-backed and memory-assisted. Packet writing is opt-in
(OC_CODEX_HANDOFF_PACKET=1, default off) and defaults to the git root's .codex/handoffs,
configurable with OC_CODEX_HANDOFF_DIR; this can create untracked repo metadata. The
JSON packet is authoritative and the derived Markdown is never read for control flow.
Only an allowlisted pacer summary is stored; access tokens, authorization headers,
cookies, session IDs, turn IDs, unknown verdict keys, prompt text, and transcript paths
are excluded. The helper validates verdict mtime (default max age 600 seconds), or
accepts a newly generated verdict from --refresh; stale HANDOFF_PREP is ignored.
Codex memory is advisory only and is not claimed to be synchronized.
New packets remain pending until --write-packet validates seven nonblank bounded fields
and records a complete git-root/worktree/HEAD/status guard. Non-Git directories and
untracked hashing beyond the guard budget do not become ready. Only then does HANDOFF_PREP give the
Codex host resume_at, a stable heartbeat name, and a prompt containing exact
handoff_id and packet path. The helper does not create automation. --resume-context
requires the exact ID/path, a matching host receipt, and rejects repository drift. For HANDOFF_HALT, the packet
becomes halted after checkpoint validation and no wake is provided. SessionStart with
source=resume injects only scheduled/resuming packets, while same-task source=compact
may inject ready state. PostCompact emits no
additionalContext because that event does not support it. See USAGE.md §7.
Changelog
-
1.5.0 (2026-07-17): added the hedge/decontextualization whitelist category (§3
item 7, HEDGES in the fidelity script), the grounded_pct second measurement axis
in --log records, the negation-first compression ordering (§4), the delegated
compression flow with the cheap-executor policy (§4b, scaling-paradox grounding),
and the self-selected-sample qualifier on quoting logged savings (§5).
-
1.4.1 (2026-07-13): added validated checkpoint writes, exact-ID resume, repository
drift guards, heartbeat receipts, strict --refresh, crash-stale lock recovery,
synchronized Markdown views, git-root packet paths, and complete SessionStart wiring.
-
1.4.0 (2026-07-13): replaced the Codex helper's prior handoff wording with an opt-in
packet-backed, memory-assisted control plane: atomic allowlisted JSON packets,
freshness/NO_DATA gates, safe resume filtering, dynamic hook event names,
idempotent completion, and host-owned automation inputs. Markdown is derived only.
-
1.3.0â1.2.0 (2026-07-13): prior handoff-aware pacing releases. Their advisory
verdict fields remain provider-neutral; Codex control semantics are defined by the
v1.4.1 packet-backed helper above.
-
1.1.0 (2026-07-12): added scripts/fidelity-check.py --coverage --original <file> pre-check mode (§2); added the Coverage ćçœźć€æ· note, the contract-fields
whole-block hard rule (§3 item 6), the rewriteâ delete quantifier case (§4), and the
single-use dispatch prompt ruling (§1) â all from a field run's fidelity-gate
findings (see USAGE.md for a worked --coverage example).
-
1.0.0: initial tiered compression + whitelist + fidelity gate + pace coupling.