Keel:为 AI 编程助手瘦身的常驻上下文层
rockerlabs/keel
rockerlabs 开源 Keel,一个让 AI 编程助手每次会话只加载约 2.5K tokens 精简核心的"工作方式"层,其余内容按需加载,并附带零依赖 Bash 工具:拦截密钥的 git hook、安装检查器和公开仓库审计。它不绑定具体工具,任何助手都能用,安装约需 10 分钟,适合跨多项目长期使用或准备将私有仓库公开的场景。
Context isn't free — and most of yours is clutter.
Bloated
CLAUDE.mdfiles and a junk-drawer.claude/load as ballast every session — burning tokens and burying the signal your assistant actually needs. Keel keeps the always-on layer thin, and loads the rest only when a task needs it.
Keel is a small "how I work" layer your AI coding assistant reads at the start of every session — the ground rules, plus a map of where everything else lives — so it stops re-learning your project and stops drowning in a context dump. Alongside it are a few zero-dependency Bash tools: a git hook that blocks secrets and personal data, a setup checker, and a go-public audit. It's tool-independent — works with any assistant, not just Claude Code — and takes about 10 minutes to set up.
Built for the case where the clutter compounds: you run an assistant across several projects on a months-long horizon, and/or you're taking a private repo public. If that's you, read on.
What Keel brings
Four properties, independent of which model or tool you run — ordered from the most immediately felt to the reason the project exists:
- Economy. A thin, stable core (~2.5K tokens) instead of a context dump — the re-explanation
tax ("we branch off main… there's already a client in
net/…") stops being paid every session.keel tokens(seedocs/token-economy.md) reads your own agent sessions' actual spend, so this claim is checkable on your own machine, not just asserted here. - Stability. The same rails load every session, so behavior stops drifting between sessions — and the unchanged prefix is prime prompt-cache material.
- Constraint. The mechanized layer — the secret-guard git hook — blocks a key-shaped leak no
matter what the model decides. A hard guarantee, not a nudge. What it does and does not cover, leg by
leg:
SECURITY.md. - Accumulation. The reason for the other three (
PRINCIPLES.md, P0): decisions and project knowledge earned in a session outlive the session — and the model, and the tool itself.
They hold with different force — economy and accumulation are structural, stability is a nudge that scales with your model, constraint is mechanical — which is exactly the honest split in What runs by itself, what only nudges below.
Install
Two steps, and the installer never overwrites a file you own (linked mode's one edit: it appends
the single import line to an existing ~/.claude/CLAUDE.md; the other: a re-run from a terminal offers,
default no, to refresh only the Keel rails block inside a CLAUDE.md Keel wrote, backing the file up first).
1. Clone and install:
git clone https://github.com/rockerlabs/keel.git && cd keel && ./install.sh --link
--link wires everything by reference (symlinks + one import line): a later git pull in this clone
refreshes what is already wired, but a release that adds files needs ./install.sh --link re-run to
wire them (the CHANGELOG says when), and removal is fully enumerable. It also turns on the secret-guard git hook.
(Plain ./install.sh makes a one-time copy instead — right for tools other than Claude Code; Codex has
its own preset, ./install.sh --codex, that generates ~/.codex/AGENTS.md directly.)
Prefer a different door — one terminal line, no git, or let the agent do it? See Other ways to install below, ranked simplest-first.
2. Restart Claude Code and run /keel-setup — the assistant finishes setup, no editing by hand.
It works even with no projects yet: it fills in your machine details and sets the ground rules.
Run it again inside each project you want Keel on (not the keel folder you just cloned): there it
writes a first draft of that project's CLAUDE.md from its own code — you review the draft, you
don't write it. (Don't see /keel-setup? You're in an old session — start a fresh one.)
Want to see it work before installing? ./examples/tour.sh runs a safe demo in a throwaway sandbox
(touches nothing on your machine): it sets up a sample project and watches secret-guard block a
key-shaped secret.
Other ways to install
#1 → #3, simplest first — pick your door (the last row is deferred)
#1 — Let your assistant install it (simplest — one sentence, the agent handles every branch). On Claude Code (or the Claude desktop app), paste:
Install Keel from https://github.com/rockerlabs/keel — read its README install section and set it up for me (linked mode if I have git), then tell me how to finish with
/keel-setup.
#2 — One line, no manual clone:
curl -fsSL https://raw.githubusercontent.com/rockerlabs/keel/main/bootstrap.sh | sh -s -- --linkClones Keel to
~/keel(setKEEL_DIRto change) and links it; re-run anytime to update. Drop--linkfor a one-time copy.
#3 — Manual, step by step — the
git clone … && ./install.sh --linkcommand at the top of Install: inspect-first, offline, full control.
| # | Flow | Needs git? | Auto-updates? | secret-guard? |
|---|---|---|---|---|
| 1 | Ask your agent | agent decides | yes, if git | yes, if git |
| 2 | One line, terminal | optional | yes, with --link |
yes, if git |
| 3 | Manual, step by step | yes | yes | yes |
| — | Download & open (.dmg) |
no | no | no |
Two facts decide the columns: the prose rails are just text files (git isn't needed to place them),
but secret-guard is a git hook — no git, no guard (the curl path falls back to a tarball and
installs the rails-only half). The .dmg row is deferred until real demand. Pin a release instead of
latest main with KEEL_REF=<tag>, or default to the last release automatically with
.../releases/latest/download/bootstrap.sh — both work on every path. Full walk-through of the
terminal flows, including the no-git fallback and version pinning →
docs/getting-started.md.
How it works
Keel rests on three plain ideas:
- Load a little always, the rest on demand — a small stable core every session; everything else pulled in only when a task needs it.
- Some things last, some don't — tools go out of date in a year; your judgment and project decisions don't. Invest in the lasting part, keep the machinery thin.
- Add a rule only when something hurts — every rule must fix a real problem you actually ran into.
That's what keeps a
CLAUDE.mdfrom rotting into a junk drawer.
flowchart TD
subgraph always["Always loaded — every session (thin core ~2.5K tokens + your project file)"]
core["CLAUDE.md — thin core:<br/>ground rules + a map of where the rest lives"]
proj["project CLAUDE.md<br/>(when you are in a project)"]
end
subgraph demand["On demand — pulled only when a task needs it"]
fw["FRAMEWORK.md (~13.3K)"]
prin["PRINCIPLES.md (~5.9K)"]
inst["INSTANCE.md"]
cmd["commands/* (when invoked)"]
agents["agents/keel-polish-reviewer<br/>(/polish's read-only reviewer)"]
end
subgraph never["Never in context — runs in the shell (0 tokens)"]
tools["secret-guard, doctor,<br/>public-audit, init-project, …"]
end
core -->|the map points here| fw
core --> prin
core --> inst
core -.->|when invoked| cmd
cmd -.->|/polish spawns it| agents
tools -.->|only their output reaches context| core
Loading
The foundation is in PRINCIPLES.md; the reusable how-to is in
FRAMEWORK.md. For exactly what loads when — and what it costs in tokens, with a
with/without comparison — see docs/loading-and-cost.md.
What runs by itself, what only nudges
This is the honest part. A file full of good advice does not, on its own, change how your assistant behaves — loaded text nudges it, but nothing forces it to follow.
- Runs by itself: the tools — the secret-guard git hook, the public-audit go-public scan,
install / doctor / init-project, and, once you opt in, the
/polishgate (Claude Code). They fire whether or not anyone remembers them; what each does →docs/reference.md.doctoralso reports a stale or unreachable memory file →docs/memory-layers.md. - Up to you:
PRINCIPLES.md,FRAMEWORK.md, and theCLAUDE.mdground rules shape decisions when read — a lens you choose to look through, not an autopilot.
Knowing which is which is the point: the always-on layer keeps context lean; the tools do the enforcing.
Just want the git hook?
The two safety tools work standalone — plain Bash + git, no Keel core, no config files, and they never enter your assistant's context:
git clone https://github.com/rockerlabs/keel.git && cd keel tools/install-secret-guard.sh --global # every repo on this machine, from now on
- secret-guard blocks key-shaped secrets (
ghp_,AKIA…,sk-…,glpat-, …) on every commit and push — and, opt-in, your own personal data (real name, emails, drive labels, serials) listed in a local never-committed file, caught even inside UTF-16 binary fixtures. It exists because exactly such a leak shipped in practice: test fixtures generated from a real device carried their owner's name, and a plain-text scan couldn't see it. - public-audit (
tools/public-audit.sh <repo>) scans a repo's files and its git history for personal and secret leaks before you flip it public — commit/tag identities, declared tokens, the same local personal-literals file secret-guard uses, emails, home paths — including inside binary blobs.
One of the tools, ~40 seconds, nothing mocked: install the hook → an API key is blocked on commit →
your own name is blocked even inside a UTF-16 binary fixture. Reproduce it yourself:
docs/demo/record-demo.sh (sandboxed, touches nothing).
The pre-PR gate — the agent can't lie about review
On Claude Code, /polish + its gate is the repo's other mechanized guarantee, alongside secret-guard.
Once wired, the agent's own gh pr create is hard-denied until /polish — simplify, tests, a
review depth matched to the diff — has run cleanly on the current commit. And the claim can't be faked:
a hook writes a mechanical trace the moment a real /code-review pass runs, and the gate cross-checks it
before unlocking — so "review: medium" in a PR's own history means a review actually ran, not that the
model said so. /polish has a fresh-context subagent run the real, built-in /code-review pass first (for low,
medium and high), attempts that pass in-session if the subagent cannot, and only if that attempt is
refused too does it fall back to spawning an independent subagent to review instead, traced the same
mechanical way, and the PR is labeled honestly in every case.
tools/install-pre-pr-gate.sh <repo> # project scope (default) — --global covers every repo instead
- Opt-in, separate from
install.sh. A hook changes what a session can do without asking each time, so/polishships with every install but wires nothing until you run this. It never clobbers a hook you already have: a foreign hook on the same slot is left alone and ours is appended beside it (unlikeinstall-secret-guard.sh, which refuses a foreign hook without--force);--forceis only for a stale copy of the same hook at another path, and backs it up. - Gates the agent, not you. The hook fires on the assistant's own tool calls — your terminal, and a
human typing
gh pr createby hand, are never blocked. - Claude-Code-specific. Hooks are a Claude Code mechanism; see
ADAPTING.mdfor the honest boundary on other tools.
Full walkthrough — what changes in your day, the receipts, the residual limits →
docs/getting-started.md.
Optional: a machine-global watcher. tools/machine-watch.sh fingerprints the files a live check must
never touch (git's global config, the global hooks dir, ssh config, shell rc files) and tells the session,
on the tool call that changed one, what happened — it catches the "a retried command lost its sandbox"
accident the prose rail cannot. Same opt-in discipline as the gate:
tools/install-machine-watch.sh <repo> # project scope (default) — --global covers every session instead
Project scope survives a deleted ~/.claude but covers only that repo's sessions; --global covers all of
them but lives in ~/.claude. --uninstall removes exactly what it wired. On a harness without hooks,
machine-watch.sh snapshot x before a live check and check x after it do the same by hand.
Who sees a report: the model, always — that relay is the guaranteed channel. The hook's banner is
client-dependent (the Claude desktop app does not render it), so an alert-tier change also raises a native
OS notification (macOS, or Linux with notify-send); KEEL_MACHINE_WATCH_NOTIFY=0 turns that off. On
macOS that notification comes from Script Editor and is dropped silently until Script Editor may notify:
once, open Script Editor, run display notification "test" with title "keel", and accept the prompt.
Good to know
"Isn't this just a well-written
CLAUDE.md?" Mostly, yes — and that's the point: one that's already written, installed in one command, tested on CI across three platforms, and disciplined enough to stay thin. Plus the guard rails a text file can't give you — the git hook and the go-public audit.
Not using Claude Code? Keel doesn't depend on it. The ideas, the
tools/, and the always-on file work with any AI coding tool (Cursor, Aider, Codex, a plain API agent, …); the one Claude-Code-specific bit is the slash commands. SeeADAPTING.md.
Already have your own conventions? Keel isn't all-or-nothing and won't fight your setup —
install.shnever overwrites a file you own (bar the one consented, backed-up rails-block refresh described under Install). Lift single ideas fromPRINCIPLES.md/FRAMEWORK.mdinto your ownCLAUDE.md, run the standalone tools next to what you have, or grab onecommands/*.mdand ignore the rest — a method to graft on, not a framework to adopt whole.
One command for the rest. Install drops a
keelCLI into~/.claude/bin(the summary prints a one-line PATH hint if that dir isn't on your PATH) —keel helplists the verbs:keel install,keel sync(pull + re-wire),keel doctor,keel audit,keel init,keel check,keel tokens(where your tokens went, and why),keel uninstall(reverses the install, backing up anything it removes),keel version, andkeel help. It's a thin front-end over the sametools/*.sh, so it works from any directory, not just the clone. The CLI needs a checkout it can point into, so the plaincurl | shcopy install skips it (its temp clone is deleted right after — the summary says so); the--linkflow and manual-clone installs wire it.
Status: early experiment. A cleaned-up copy of one person's working setup, public to find out whether it helps anyone besides its author. Feedback welcome; expect rough edges.
Docs
docs/reference.md— what's in the box: every file, tool, and command at a glance.docs/getting-started.md— the longer setup walk-through, install flows, version pinning.docs/loading-and-cost.md— what loads when and the per-session token cost.docs/token-economy.md—keel tokens: where your own agent sessions' tokens went, and three diagnosed patterns (fan-out, cold prompt-cache resumes, repeated file reads) instead of only a total.docs/keel-ab.md— the Keel-vs-cold A/B: one operator-present data point measuring the "What Keel brings" claims against a cold baseline, with the frozen protocol and reproducible scripts.docs/going-public.md— a safe step-by-step for making a private repo public.docs/rollout-audit.md— checklist for verifying a model/harness upgrade didn't silently break your pipeline.docs/release-audit.md— a repeatable flow for a project's own release-readiness sweep, before tagging.docs/release-history.md— a one-paragraph-per-release digest, newest first, so you don't reconstruct "what shipped in vX.Y" from the fullCHANGELOG.md.docs/delta-audit.md— the release-candidate pass release-audit.md's phase 6 calls: a mechanically derived universe (every file a release range touched, plus its seam map) instead of a scope chosen by judgment.docs/drydock.md— a whole-tree audit of whether your knowledge base is still true: the prose your agent executes drifts silently, and nothing fails when it does.docs/verification-economics.md— when to stop auditing, what to file from a run, and how to tell whether your verification method is improving: the stopping rule and filing bar that governrelease-audit.md,delta-audit.mdanddrydock.mdruns.docs/vendor-review.md— a scriptable cross-vendor reading leg: a leak-gated bundle, a swappable client per vendor CLI, one round dir per launch.docs/delegation.md— fan bulk read-only analysis out to parallel subagent workers behind a file contract, keeping every gate in your own session.docs/release-management.md— running a whole release with one manager session and gated worker sessions — the gap between the two docs on either side of it here.docs/grooming.md— assembling the next release from the backlog on a fixed cadence: retro first, pains supplied only by the operator, a mandatory fresh-reviewer round.docs/triage.md— the promote-or-drop pass over the staging tiers (learnings, ideas, the standing list): one verdict per entry, filed or deleted in the same pass.docs/parallel-sessions.md— running 2+ agent sessions against one repo safely: what a worktree does and doesn't isolate, the failure catalog, and the rails.ADAPTING.md— running Keel on tools other than Claude Code, with live cross-tool results.PRINCIPLES.md·FRAMEWORK.md— the foundation and the reusable how-to.
Note on internal ticket references: References like
dir #N,KB.n, andSEC4— in code comments,CHANGELOG.md, or a doc likedocs/release-audit.md— are internal development shorthand for a private backlog this repo doesn't ship; you don't need to resolve one to use the surrounding instructions, since full context is always in the prose around it.
Tests, scope, license
A small Bash test suite (no extra dependencies) runs on every change across Linux, macOS, and
Alpine/busybox, plus a
shellcheck pass — tests/run.sh runs the test suite locally; shellcheck -x --severity=warning
over the touched .sh files is a separate step. It's the same rule Keel asks of you, applied to Keel
itself.
Keel is a reference and method, not a packaged product or a subscription. Built for Claude Code but not
tied to any one model or tool — see ADAPTING.md.
Licensed under MIT (see LICENSE). Releases are tracked in CHANGELOG.md.
来源:GitHub · github.com
