CLAUDE.md · git:20260902.f0e19e0 · 2026-09-02 · sha256 d06073ef804949fa
CLAUDE.md git:20260902.f0e19e0A
Immutable. This exact content is served forever at /api/v1/blob/d06073ef804949fa.
# cc-repo-harness
A Claude Code plugin that lays a repository's foundation, and then stays to
measure whether it is still holding. The surprising part: **most of this
repository is not the plugin.** It is payload — files copied into somebody
else's repository, which must keep working after this plugin is uninstalled.
The split that decides where a new file goes: **the repository keeps the
harness, the plugin keeps the instrument.** Anything the repository needs in
order to work is copied into it. Anything that only *reports on* the repository
stays here and is run against it.
- **Covers**: the three identities below, and the rules no script can enforce.
- **Does not cover**: anything true of one directory only (that directory's own
`CLAUDE.md`), anything a script can block (`shared/scripts/guards/`), anything
a script can detect (`shared/scripts/gates/`). Detail added here is paid on
every turn of every session, forever.
## Three identities, one tree
Every file here is exactly one of these. Knowing which one you are editing is
the first question, because the answer changes who is affected.
| Path | Identity | Who gets it |
|---|---|---|
| `.claude-plugin/` `skills/` `agents/` `commands/` `hooks/` | the plugin | whoever installs it |
| `shared/` | **payload** | **copied into strangers' repositories** |
| `CLAUDE.md` `.claude/` `scripts/` `docs/` `eval/` `guide/` | our own harness | only us |
The plugin is charged for on **every turn of every session on the machine**, so
only one skill lives there: `bootstrap-repo-harness`, which is how a person
arrives -> docs/decisions/0024
## Hard rules
1. **Anything under `shared/` ships to strangers.** Write it for a repository
you have never seen. Tools only we need go elsewhere.
2. **A check nobody has watched fail is a file, not a check.** A new gate or
guard is not done until you have planted its defect, watched it go red, and
left a selftest case behind that does the same. See `writing-checks`.
3. **Exit 2 means COULD NOT JUDGE and is never a pass.**
4. **Repository behaviour never lives in the plugin.** If installing or
uninstalling this plugin changes what a repository *does*, that is a bug: it
makes the repository behave differently for teammates who have not installed
it. The plugin holds what protects a person from a repository, what teaches a
person, and what *measures* a repository. Nothing else. The instrument is the
reason to keep the plugin installed, and it is also the easiest place to
smuggle behaviour in — a diagnostic that starts fixing what it finds has
stopped being a diagnostic -> docs/decisions/0021
5. Which of `shared/` and `scripts/` a hook points at is decided per hook, and
only matters while editing the wiring: `.claude/rules/wiring.md` carries it
and loads there.
## Commands
**Before pushing, run this.** It is the whole suite, about seventy seconds:
```bash
python3 scripts/check.py # everything CI will run, that a laptop can
python3 scripts/check.py --list # what it would run, and what it skips
```
It reads `.github/workflows/ci.yml` and runs the steps out of it, so there is
no second list to drift. Unreadable step, or a linter this machine lacks: exit
2, by rule 3 below.
The pieces, when you want one of them alone:
```bash
python3 shared/scripts/guards/selftest.py # guards can still turn red
python3 shared/scripts/gates/selftest.py # gates can still turn red
python3 shared/scripts/context/selftest.py # hooks still reach the model
python3 shared/scripts/assess/selftest.py # the assessment can still score badly
python3 shared/scripts/selftest.py # scaffold reaches green, outlives the plugin
python3 shared/scripts/probe_repo.py --root . # what this repo has and lacks
python3 shared/scripts/assess/factsheet.py --root . # the whole assessment, one page
claude plugin validate . --strict # the manifest, by the first-party checker
```
## Where to look
- Full routing table: docs/index.md
- Why things are shaped this way: docs/decisions/
<!-- Cap: 100 lines, enforced by shared/scripts/gates/check_context_budget.py.
Hitting the cap is a signal to move a rule one hop out, not to compress it. -->