Files
claude-skills/.wiki/concepts/compress-dedup.md
vitya 6e4f3f481b refactor(skills): dedup compress -> caveman-compress [v1.0.0]
skills/compress/ was a byte-identical dupe of skills/caveman-compress/
(SHA256 match across all 7 scripts/ files; SKILL.md diff was name: +
Process step 2 only; descriptions textually identical = arbitrary
harness tie-break + double-counted listing budget).

Kept caveman-compress canonical: it carries README.md (benchmarks +
caveman-toolkit branding) and SECURITY.md (Snyk false-positive writeup),
and matches the caveman-* prefix invariant.

Ported the better Process-step wording from compress
(`cd <directory_containing_this_SKILL.md>`) into caveman-compress;
the prior `cd caveman-compress` form assumed cwd was the parent dir
and broke when invoked from ~/.claude/skills/caveman-compress/.

Added version: 1.0.0 to caveman-compress frontmatter
(first versioned release; aligns with skill-versioning concept).

Removed: skills/compress/, dist/compress.skill,
~/.claude/skills/compress/ (manual prune; install.sh has no prune step
yet -- future [install-ps1] task should add --prune).

Slash-command impact: /compress gone; /caveman-compress and
/caveman:compress (toolkit-canonical) remain.

Wiki: .wiki/concepts/compress-dedup.md (rationale + rejected
alternatives), index.md + log.md updated.

Tasks: [compress-dedup] flipped active -> done in same commit
(per-task file .tasks/compress-dedup.md created with full decisions
log).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 21:49:44 +03:00

92 lines
6.4 KiB
Markdown

---
title: compress vs caveman-compress dedup
type: concept
tags: [skills, dedup, caveman, repo-hygiene]
updated: 2026-05-05
---
# compress vs caveman-compress dedup
> Two skills shipped the same payload under different names. Kept `caveman-compress` (richer, on-brand), deleted `compress`. Recorded here so future readers don't reinvent the analysis.
## What we found
Side-by-side audit of `skills/compress/` and `skills/caveman-compress/`:
| Layer | `compress` | `caveman-compress` |
|---|---|---|
| `scripts/__init__.py` | identical (SHA256) | same |
| `scripts/__main__.py` | identical | same |
| `scripts/benchmark.py` | identical | same |
| `scripts/cli.py` | identical | same |
| `scripts/compress.py` | identical | same |
| `scripts/detect.py` | identical | same |
| `scripts/validate.py` | identical | same |
| `SKILL.md` description | byte-identical text | byte-identical text |
| `SKILL.md` Process step 2 | `cd <directory_containing_this_SKILL.md> && python3 -m scripts ...` (generic) | `cd caveman-compress && python3 -m scripts ...` (brittle, assumes cwd is parent) |
| `SKILL.md` `name:` | `compress` | `caveman-compress` |
| `README.md` | absent | present (benchmarks table, branding, "Part of Caveman" toolkit linkage) |
| `SECURITY.md` | absent | present (Snyk false-positive writeup: subprocess + file I/O patterns explained) |
| Frontmatter `version:` | absent | absent (added `1.0.0` as part of this dedup) |
Description text in both skills' frontmatter:
```
Compress natural language memory files (CLAUDE.md, todos, preferences) into caveman format
to save input tokens. ... Trigger: /caveman:compress <filepath> or "compress memory file"
```
— literally the same paragraph. The harness loads both skill listings, both register independently, descriptions identical ⇒ activation tie-break is arbitrary, and the listing budget pays twice.
## What we kept and why
**Canonical = `caveman-compress`.** Reasons in order of weight:
1. **Richer artefacts** — README.md and SECURITY.md exist only here. The README is not boilerplate: benchmarks table on real files (claude-md-preferences.md, project-notes.md, mixed-with-code.md), 46% average savings claim, before/after example. The SECURITY.md is what static-analysis (Snyk) hooks into, so deleting it would re-open the same false-positive ticket the upstream author already closed.
2. **On-brand naming** — the skill is part of the [JuliusBrussee/caveman](https://github.com/JuliusBrussee/caveman) toolkit. The `caveman-*` prefix lines up with the rest of the cluster: `caveman` (speak compressed), `caveman-commit` (commit-message variant), `caveman-review` (PR-review variant), `caveman-help` (help card), `caveman-compress` (compress files). `compress` was the lone exception that broke the prefix invariant.
3. **History reads cleanly** — the per-task `[skill-readmes]` plan groups the caveman cluster as a single batch for README work. Keeping the prefix means that batch covers all of them; mixing in a stray `compress` would force a "wait, do we README this one separately?" decision later.
## What we ported across before deleting
The only thing `compress` did better than `caveman-compress` was Process step 2. Original wording:
```
cd caveman-compress && python3 -m scripts <absolute_filepath>
```
This assumes cwd is the parent of `caveman-compress/`. When the agent invokes the skill from `~/.claude/skills/caveman-compress/`, that assumption is false (cwd is the skills dir, parent is `~/.claude/`). The `compress` SKILL.md had the robust form:
```
cd <directory_containing_this_SKILL.md> && python3 -m scripts <absolute_filepath>
```
— ported into `caveman-compress/SKILL.md` as part of this dedup. Net: the canonical skill now has the better instructions plus the README + SECURITY.
Also added `version: 1.0.0` to frontmatter — first versioned release. Aligns with the rest of the infra-skill cluster ([skill-versioning](skill-versioning.md)).
## What we rejected
**Alias-stub** — keep `skills/compress/SKILL.md` as a tiny pointer file with description "alias for caveman-compress, see that skill". Rejected: the harness has no alias mechanism. Every SKILL.md file fully registers as a skill, with its description text consuming the listing budget. An alias-stub still occupies a listing slot and a description allowance — there's no "see that skill" indirection at the harness level. Pure waste of a listing entry.
**Keep both, document them as siblings** — let the user pick which slash-command name they prefer (`/compress` vs `/caveman-compress`). Rejected: descriptions are identical; the harness has no signal to disambiguate; activation tie-break is arbitrary. Forces every future `/caveman:compress` call to gamble on which copy the harness picks.
**Delete `caveman-compress`, keep `compress` as the simpler name** — rejected because we'd lose the README, SECURITY.md, and the caveman-toolkit branding link. `compress` was the stripped-down fork; reverting to it would be a net regression in artefact quality.
## Install-path impact
`scripts/install.sh` has no prune step. Removing `skills/compress/` does **not** remove `~/.claude/skills/compress/` on the user's machine — the install script copies, never deletes. Manual `rm -rf ~/.claude/skills/compress/` is required during this dedup. Same applies to `dist/compress.skill`: deleted explicitly, since the next `build.sh` run iterates over `skills/<name>/` and won't recreate an artefact for a source folder that no longer exists.
> **Future work:** the [`install-ps1`](../../.tasks/STATUS.md) ⚪ task should at minimum match `install.sh`'s behavior, but is also the right time to add a `--prune` flag that removes `~/.claude/skills/<name>/` for every name not in `skills/<name>/`. Would have made this dedup automatic instead of three-step.
## Slash-command impact
Before: `/compress`, `/caveman-compress`, and `/caveman:compress` (toolkit-canonical) were all live.
After: `/compress` is gone. `/caveman-compress` and `/caveman:compress` still work. User confirmed `/compress` was effectively never used; no migration needed.
## See also
- [skill-versioning](skill-versioning.md) — why infra skills carry `version:` in frontmatter and the project-discipline Rule 3 bumps tie back here
- [repo-layout](repo-layout.md) — flat `skills/` layout means duplicates show up as flat sibling folders, easy to spot in a directory listing
- [skill-vs-plugin](skill-vs-plugin.md) — caveman-compress is a bare SKILL.md (no slash command, no hooks, no MCP), the right granularity for this workload