Two verbs. One agent hands off — dirty tree included — with a note. A different agent, on a different machine, model, account, or vendor, resumes exactly and keeps going.
Just because your agents are ephemeral doesn't mean their work has to be.
The agent is temporary. The vault is permanent.
Today an agent's work usually dies with its sandbox unless a human ferries it — copies a diff into a
chat, zips a directory, walks someone through what changed. kygit handoff replaces the
ferrying: it captures your exact repository state — staged, unstaged, deleted, and untracked changes,
all distinct — mints a single-use key, and you paste the key to the next agent. That agent runs
kygit resume and gets the exact state back, note included, on a machine that has never
seen this repository before.
kygit handoff. The dirty tree — staged, unstaged, deleted,
and untracked files, each distinct — is captured and encrypted on A's own machine; a Handoff Note
(what happened, what remains, what to try next) is written alongside it. A single-use
Handoff Key — kgh1_…, 69 characters — is assembled and printed
exactly once. Nothing about the key ever reaches KyGit's servers.kygit resume kgh1_… (a brand-new machine with only
npx -y @kychee/kygit installed works). B becomes a member of A's org at A's own role (or narrower, if A minted it that way), the
working tree is restored into a fresh directory exactly as A left it, and the note renders as
Markdown. B reads what A did, runs the tests the note names, and continues — or pushes straight back
to the same vault.kygit handoff --json
→ kgh1_9f2a... (printed once — copy it now)
kygit resume kgh1_9f2a... --to ./work
→ restored: 2 modified, 1 staged, 1 untracked, 1 deleted
→ note: "Auth flow done; tests green except the OAuth callback redirect..."
handoff captures dirty work by default (its sibling verb,
snapshot, keeps refusing dirty work by default — two verbs, two defaults, on the same
capture path underneath). Staged changes, unstaged changes, deleted files, and untracked files are all
restored distinctly on the other end — resume tells them apart, it does not flatten
them into one commit. Files your .gitignore already excludes are never
transferred, exactly as with an ordinary push.
A fixed sensitive-file denylist is applied to the untracked set only (tracked files are the choice you
already committed to git, so they travel as-is): .env and .env.*,
*.pem, *.key, private-key files (id_rsa*,
id_ed25519*), .npmrc, .netrc, .git-credentials,
*.tfstate*, credential JSON, .aws/**, .ssh/**, and more.
Anything excluded is named in the response — capture.sensitive_excluded[] — never silently
dropped, never silently included. A path you deliberately want handed over anyway is re-admitted with
--include-sensitive <glob>.
The Handoff Note travels sealed alongside the checkpoint, readable by every key-holder forever: what
happened, what's in progress, what's failing, what was tried and didn't work, the next steps, the exact
commands to run (test / build / run), decisions made, and open questions. It is written truthfully — a
harness that invents a passing test result to look finished defeats the entire point of a handoff.
kygit resume renders it as Markdown by default; --json returns it raw.
Before the checkpoint commit is even written, a client-side scan refuses the handoff if the note itself
contains something that looks like a secret (a known key prefix, a `-----BEGIN` block, a high-entropy
token) — a note is read by another agent, and secrets have the secrets API instead.
Anyone holding this key becomes a <role> of this org until first use or <expires_at>.
That is the exact sentence kygit handoff prints to your terminal — it is not paraphrased
here, and the CLI does not soften it. A handoff mints an org membership, not a scoped read link: the
recipient becomes a real member at your own role, or narrower if you asked for narrower
(--role <role>), never wider. Paste the key only to whoever you mean to hand real
authority to.
--ttl <seconds>); unclaimed keys simply expire.kygit handoff --revoke
<id> (or list the open ones first with --list).1 GB of encrypted vaults, free forever, unlimited repos — never expires, never deleted for non-payment.
The free tier every fresh agent lands on is perpetual — it does not lapse on a clock the way a trial does. That matters specifically for a handoff: the whole point is that work can sit in the vault for however long it takes another agent to pick it up, and a vault that could expire out from under an unclaimed handoff would undercut the product. GitHub is the honest comparator on the floor itself — free, unlimited repos, never expires — and KyGit's free floor is held to the same bar. Where the two part ways is what the host can see: GitHub can read every repository it stores; KyGit cannot read yours. Private by construction, not by policy — the keys never leave your machines, and what reaches storage is ciphertext we cannot open.
A handoff is a claim against your own vault, and the vault's own exit ramp applies to it exactly as it
applies to everything else in the vault: Your repository ciphertext moves directly between your
machine and storage — our servers never handle it. With a mirror configured
(kygit mirror s3://your-own-bucket, the recommended default rather than a power-user
extra), Your ciphertext replicates to a bucket you own. We can't decrypt your repository
history — and we can't hold it either. If we disappeared tomorrow, your repository is
recoverable from a bucket listing and your keys, with an open-source tool. No server required.
Provable, not promised. We proved it against production: a real vault, mirrored, then
recovered ref-exact with the gateway deliberately unreachable. Every prune requires receipts
from two independently built open-source implementations — one in TypeScript, one in
Rust.
The durability sentence carries its honest qualifier, and a handoff is the best answer to it: The vault protects source history from host-side loss while a principal keystore survives. A vault starts with exactly one keystore that can open it — the client says so to your face — and a lone agent on one machine is a single point of failure for its own history. The moment B resumes, a second keystore on a second machine can open the vault: two agents who can each restore it are precisely the backup one agent never had. Human envelopes — a person's own key on the vault — are next; until they ship, keep a keystore backed up, and let a handoff be the second copy in the meantime.
There is no separate KyGit CLI, API, or protocol for this — one machine surface, one vocabulary:
run402 repos handoff / run402 repos resume, or the same two verbs through the
shim, kygit handoff / kygit resume. Your reference is
run402.com/llms-full.txt (section “gitvault”,
routes under POST /gitvault/v1/vaults/:vault_id/handoffs and
POST /gitvault/v1/handoffs/:handoff_id/claim). There is no MCP tool for either verb — a
handoff mints a bearer secret, and a resume mutates org membership and writes a working tree, the same
law that keeps repos create/delete CLI/SDK-only.
| Verb | Does | MCP |
|---|---|---|
kygit handoff | Capture the dirty tree, write the note, mint a single-use key | — |
kygit resume <key> | Claim the key, restore the tree, join the org, render the note | — |
@kychee/kygit alone is enough — npm i -g @kychee/kygit installs the engine and
the brand door together, and git-remote-kygit ships with it, so git push
against a kygit:: remote works out of the box.
npm i -g @kychee/kygit
kygit create # provisions a vault immediately, scaffolds a kygit:: remote
kygit handoff # capture + mint, whenever you need to hand off
kygit::org/name and run402::org/name address the identical vault — the door
you came in decides which spelling is rendered; the underlying vault has no opinion about it.