For software that updates itself

Check a new version before it goes live.

When your software ships a new version of itself, keel runs that version first and only switches to it if it actually works. If it does not, the old version keeps running. Every decision is signed and written to a log you can check later.

When to use it

Reach for keel when a deploy can break itself.

It fits software that updates or redeploys itself, where a bad version reaching users is expensive to undo.

Use it when

  • your app, agent, or worker ships new versions of itself
  • a broken version reaching users is costly
  • you want a signed record of what shipped and what passed

You probably do not need it when

  • you deploy by hand and review every change
  • rolling back is trivial and cheap
  • there is no automated promote step to guard

Quick start

Try it in four commands.

The quick path exercises the real library and the deletion example. It does not call a network service or ask for a secret.

  1. bun install install the library and site workspace
  2. bun test run deterministic library and content checks
  3. bun run examples/delete-the-handrolled-gate/run.ts replay the deletion receipt

Examples

What it catches, shown five ways.

Each example states a falsifiable claim, runs a harness, and leaves a receipt with a two-sided review. Projection stays separate from observed results.

refused receipt

Bad live candidate refused

A candidate that builds but fails a real request cannot promote.

bun run examples/refuse-bad-self-update/run.ts promotion denied; known-good restored
refused receipt

Stolen token inert

A valid write token cannot promote a different artifact without a fresh proof.

bun run examples/stolen-token-useless/run.ts ref unchanged after replay and forgery attempts
refused receipt

One key cannot ship

A 2-of-3 threshold blocks a single compromised verifier key.

bun run examples/one-key-cant-ship/run.ts single signer refused; edited log detected
accepted receipt

Audit survives restart

Trust state and signed decisions survive reload and detect tamper.

bun run examples/audit-survives-restart/run.ts 7 checks pass after reload and tamper injection
accepted receipt

Hand-rolled gate deleted

A toy worker deletes local deploy-gate logic by importing keel.

bun run examples/delete-the-handrolled-gate/run.ts 41 owner lines shrink to 25 while attacks flip to refused

How it works

Five small parts, one yes-or-no.

The load-bearing primitive is content addressing. A proof, a promotion, and a rollback all name the same bytes.

01

A candidate is named by content digest.

02

A verifier builds, smokes, and records evidence for that exact digest.

03

The proof is signed by an active trusted key, or by enough keys for a threshold.

04

Promotion uses a scoped token and compare-and-swap against the known baseline.

05

Every decision appends to a hash-chained receipt.

Status

What is proven, and what is not.

75 tests pass
5 example receipts
1 downstream adopter: executor-cloudflare

Limits

What keel does not do.

keel does not deploy, run servers, or hold your keys. You wire it into the deploy you already have and supply the deploy, verify, rollback, and storage steps.

  • keel does not deploy an app for you.
  • keel does not hold long-lived write credentials.
  • keel does not trust a passing test without an artifact-bound proof.
  • keel earns the downstream claim only by adoption: executor-cloudflare imports it and deleted its own gate code.