跳到正文
GitHub·· 9 天前AI 评分36

Keel:为 AI 编程助手瘦身的常驻上下文层

rockerlabs/keel

AI 导读

rockerlabs 开源 Keel,一个让 AI 编程助手每次会话只加载约 2.5K tokens 精简核心的"工作方式"层,其余内容按需加载,并附带零依赖 Bash 工具:拦截密钥的 git hook、安装检查器和公开仓库审计。它不绑定具体工具,任何助手都能用,安装约需 10 分钟,适合跨多项目长期使用或准备将私有仓库公开的场景。

正文

CI License: MIT

Context isn't free — and most of yours is clutter.

Bloated CLAUDE.md files 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.

Before and after: without Keel the assistant starts every session from zero and re-asks what you already settled; with Keel it reads one thin always-on file — ground rules plus a map of where the rest lives, loaded on demand

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:

  1. 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 (see docs/token-economy.md) reads your own agent sessions' actual spend, so this claim is checkable on your own machine, not just asserted here.
  2. Stability. The same rails load every session, so behavior stops drifting between sessions — and the unchanged prefix is prime prompt-cache material.
  3. 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.
  4. 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 -- --link

Clones Keel to ~/keel (set KEEL_DIR to change) and links it; re-run anytime to update. Drop --link for a one-time copy.

#3 — Manual, step by step — the git clone … && ./install.sh --link command 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:

  1. Load a little always, the rest on demand — a small stable core every session; everything else pulled in only when a task needs it.
  2. 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.
  3. Add a rule only when something hurts — every rule must fix a real problem you actually ran into. That's what keeps a CLAUDE.md from 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 /polish gate (Claude Code). They fire whether or not anyone remembers them; what each does → docs/reference.md. doctor also reports a stale or unreachable memory file → docs/memory-layers.md.
  • Up to you: PRINCIPLES.md, FRAMEWORK.md, and the CLAUDE.md ground 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.

Real sandboxed run: secret-guard blocks an API key on commit, then the owner's own name hidden inside a UTF-16 binary fixture

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 /polish ships 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 (unlike install-secret-guard.sh, which refuses a foreign hook without --force); --force is 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 create by hand, are never blocked.
  • Claude-Code-specific. Hooks are a Claude Code mechanism; see ADAPTING.md for 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. See ADAPTING.md.

Already have your own conventions? Keel isn't all-or-nothing and won't fight your setup — install.sh never overwrites a file you own (bar the one consented, backed-up rails-block refresh described under Install). Lift single ideas from PRINCIPLES.md/FRAMEWORK.md into your own CLAUDE.md, run the standalone tools next to what you have, or grab one commands/*.md and ignore the rest — a method to graft on, not a framework to adopt whole.

One command for the rest. Install drops a keel CLI into ~/.claude/bin (the summary prints a one-line PATH hint if that dir isn't on your PATH) — keel help lists 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, and keel help. It's a thin front-end over the same tools/*.sh, so it works from any directory, not just the clone. The CLI needs a checkout it can point into, so the plain curl | sh copy install skips it (its temp clone is deleted right after — the summary says so); the --link flow 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 full CHANGELOG.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 govern release-audit.md, delta-audit.md and drydock.md runs.
  • 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, and SEC4 — in code comments, CHANGELOG.md, or a doc like docs/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