~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/knotless

git that lives in your Atmosphere account

Forked from chadtmiller.com/knotless

0
0
155 lines · 6.2 KB Raw History
# knotless

Git that lives in your atproto account.

It works on any stock PDS, with nothing to install. People push with plain
git through a remote helper, and agents do the same over MCP.

A knotless repository is a handful of records in your own atproto repo.
There is no git server and no knot. The repository moves with your account
and is in your CAR backups, and anyone can clone it from your PDS directly.

Forks, pulls, issues and reviews are records too, each in its author's
account. One optional server, `knotless-serve`, adds a read cache, an index
of pulls and issues, a gateway for collaborators, and web pages. It is cheap
to run.

```sh
curl -fsSL https://knotless.dev/install.sh | sh   # knotless, git-remote-knotless, knotless-mcp, and the runner, labeller and reviewer
knotless login alice.bsky.social                   # OAuth, in your browser

git push knotless://alice.bsky.social/my-project main
git clone knotless://alice.bsky.social/my-project
```

[knotless.dev](https://knotless.dev) runs `knotless-serve`, and hosts
knotless's own repository:
[chadtmiller.com/knotless](https://knotless.dev/chadtmiller.com/knotless).

## What it does

- `git push`, `fetch` and `clone` over `knotless://` URLs. `knotless-serve`
  also serves reads over git smart HTTP, partial and shallow clones
  included.
- Commits, branches, reviews and merges from the CLI or MCP, with no clone.
- Forks, pulls, reviews, issues, protected branches and a merge queue.
  Collaborators push through a gateway the owner chooses.
- Private repositories in permissioned spaces, where the pulls, issues and
  comments are as private as the code.
- An MCP server for agents: over stdio on your machine, or over HTTP from
  `knotless-serve`.
- CI: `knotless-run` runs workflows in containers on pushes and pulls, and
  writes checks that gate merges.
- Read-only web pages for code, history, diffs, pulls, issues and checks,
  with syntax highlighting and Mermaid diagrams, on a phone or a desktop.
- atproto's moderation: hides, blocks, reports, and takedowns published as
  labels.

## How it works

```mermaid
flowchart LR
  you[git, knotless CLI,<br/>or an agent over MCP] -->|XRPC| pds[(Your PDS:<br/>dev.knotless.* records<br/>and pack blobs)]
  others[Collaborators] -->|service token| gw[Gateway]
  gw -->|writes as you| pds
  pds --> feed[Jetstream]
  feed --> serve[knotless-serve:<br/>cache, index, web pages]
  feed --> run[knotless-run:<br/>workflows]
  run -->|checks| ci[(Runner's PDS)]
  readers[Anyone] -->|clone, browse| serve
  readers -->|clone| pds
```

Four record types in the owner's account hold a repository:

| Record | Key | Holds |
| --- | --- | --- |
| `dev.knotless.repo` | name | the repository's `key` (a TID), description, default branch, collaborators, gateway and branch rules |
| `dev.knotless.ref` | `<key>.<hash of ref name>` | one ref's target, and a generation counter |
| `dev.knotless.claim` | `<key>.<hash>.<generation>` | the lock on one generation of a ref |
| `dev.knotless.pack` | `<key>.<tid>` | an immutable, self-contained git pack, inline when small and in blobs when not |

A push creates the claim for the ref generation it read, in the same
`applyWrites` as the ref update. The PDS accepts only the first create of a
key, so each ref has its own compare-and-swap, and agents pushing to
separate branches never contend.

The keys share the repository's prefix, so one `listRecords` reads a
repository's refs, or its newest packs. Once a repository holds more than 32
packs, they are folded into one, so a clone stays a few reads however long
the history is.

The [design pages](docs/design/README.md) cover the rest: the limits of a
stock PDS, the failure cases, the trust model and the prior art.

## Performance

A warm push is two round trips to the PDS, and a fetch of a small push is
one. Against the reference PDS on the same machine, with 50 ms of
round-trip time added:

| | p50 |
| --- | --- |
| `git push`, one small commit | 223 ms |
| `git fetch`, one new commit | 177 ms |
| `knotless repo commit`, no checkout | 366 ms |
| `git clone`, compacted | 158 ms |
| 16 agents pushing 16 branches at once | 443 ms total |

[Performance](docs/reference/performance.md) has every measurement and how
it was taken.

## Documentation

- [Getting started](docs/guide/getting-started.md): install, log in, push,
  commit without a checkout.
- [Collaborating](docs/guide/collaborating.md): sharing, forks, pulls,
  reviews, merging, moderation.
- [Private repositories](docs/guide/private.md).
- [Agents](docs/guide/agents.md): connect Claude Code, Claude Desktop,
  Cursor or claude.ai.
- [Running knotless-serve](docs/guide/server.md): the cache, appview,
  gateway and web pages.
- [Workflows](docs/guide/workflows.md): CI with `knotless-run`.
- [Command reference](docs/reference/cli.md): every command, flag and
  environment variable.

The [docs index](docs/README.md) lists every page.

## Components

- [`knotless`](crates/knotless): the CLI and `git-remote-knotless`. They
  talk to PDSes directly.
- [`knotless-mcp`](crates/knotless-mcp): the MCP server.
- [`knotless-serve`](crates/knotless-serve): the optional read cache,
  appview, gateway, moderation service and web pages, in one binary that
  fits a small VPS.
- [`knotless-run`](crates/knotless-run): the workflow runner.
- [`knotless-triage`](crates/knotless-triage): the triage bot, which labels
  issues with a classifier's choices.
- [`web`](web): the SvelteKit pages that `knotless-serve` hands requests to.

## Development

```sh
just setup    # npm install in harness/ and web/, llvm-tools for coverage
just test     # every test, against the npm reference PDS
just fmt      # rustfmt and oxfmt
just lint     # rustfmt, oxfmt, clippy and svelte-check
```

Tests cover every line and function, and CI fails below that.
[Development](docs/development.md) covers the test harness, screenshots and
agent scenarios. [AGENTS.md](AGENTS.md) says how changes are made and
landed.

## Status

knotless runs [knotless.dev](https://knotless.dev), which hosts knotless's
own development. Not done yet: verifying refs against signed repository
commits ([Known gaps](docs/design/security.md#known-gaps)).

## License

MIT or Apache-2.0, at your option: [LICENSE-MIT](LICENSE-MIT),
[LICENSE-APACHE](LICENSE-APACHE).