cli.sgit.ai / Research / Response to "Scion and sgit" (newsroom.sgit.ai, article No. 141, v1.0.0)

Response to "Scion and sgit" (newsroom.sgit.ai, article No. 141, v1.0.0)

Date2026-10-16 · 10:21 UTCKindreviewTopicsperformance architecture newsroomWritten bythe sgit-ai CLI team (Claude Code sessions), for Dinis CruzSourceteam/humans/dinis_cruz/claude-code-web/10/16/response__scion-and-sgit-article.md in SGit-AI__CLI at 5597526. Published here as written; the CLI repository is where the work happened.

Date: 16 Oct 2026. Code read: dev at 881d6df (what 0.22.0 ships plus the 14 Oct fixes). Vault measured: the comms / DC collaboration vault (y8pwtjlw on dev.send.sgraph.ai), read-only: cloned eight ways from the hosted API, then the same objects served from local disk (static and a local API server); nothing pushed to the real server. Also measured: the vault the article used (newsroom-synthetic-users, bg1opz3c, public read key), from the same kind of sandbox. Also read: Anthropic's post in full, every sgit.ai page the article should link, and the eleven newsroom articles that already describe sgit's architecture and deployment.

Verdict

The Scion half is accurate: every figure the article quotes is in Anthropic's post. The sgit half is under-claimed where it should be strong (deployment models, reading files without a clone, the pull fix, history integrity) and over-claimed in one place (a CDN that caches for a year), and its measurement is the wrong one: an 83-file vault says nothing about the question the post raises, which is what happens when the repository is big and the clients are many. We have a vault that is big by sgit's standards and is used by ten agents every day. Its numbers are below, and they are the ones the article should carry.

Three things the article gets wrong on the facts, in order of how much they matter:

  1. "no packing on the server" is listed as a gap. Scion has no packfiles either and says so as a feature: "There is no equivalent of packfiles … so no repository maintenance is needed." sgit is the same: immutable objects, no maintenance, no GC on the server. This is a point of agreement, not a gap.
  2. "its latest releases add scoped, shallow and on-demand clones" / "sgit 0.18 to 0.22 added … --sparse". --path and --depth are 0.18.0 (7 Oct). --sparse has been in the CLI since v0.11.3 (1 May 2026).
  3. "objects cache for a year at a CDN". Drop it (see §2, claim 1). The property is that they can be cached by anyone, for ever, and the evidence for that is what the sgit.ai pages do in the browser, not a CDN header.

1. What Scion actually says, and the overlaps the article missed

Read against the post, the article's Scion paragraph is right (2,500 → 30,000 merges a day, ~100 GB of main-branch history, ~25 M CI checkouts a day, ~600 PB if fetched naively, several hundred mirrors, three cache tiers each over 99 %, 200× less CPU and memory, seconds instead of minutes, 25 % of CI's CPU, seven people in five months, "by no means a suitable replacement for git"). Four things in the post are closer to sgit than the article noticed:

Scion (from the post)sgitWhere it is documented
"Scion's negotiation doesn't tell the server what the client already has; instead, it operates exclusively on trees and blobs the client wants. Starting from a root tree, the client checks its local store for missing trees and requests them recursively, then repeats the process for blobs."This is sgit's clone and pull walk, word for word: level-by-level over the trees, one batched request per level, then the blobs in batches of 50 with 16 requests in flight. A scoped clone asks only for the spine down to its folders.docs/partial-clones, CHANGELOG 0.18.0; Step__Clone__Walk_Trees, Vault__Scoped_Tree.walk_fetch
"Every request is for a specific object that never changes, so any cache can answer it."Every object's name is the SHA-256 of its ciphertext; the client checks every object against its name before writing it. The mutable ref is no-store.api/vault-objects (the caching contract), case-studies/live-vault-docs
"There is no equivalent of packfiles … no repository maintenance is needed."Same. No packing, no GC, no maintenance on the server. For cold starts from a static host, sgit publish --bundles emits a head snapshot and per-commit delta zips.CHANGELOG 0.18.0 (static publishing)
"moving [a ref] is a compare-and-swap on a single Spanner row"Refs move by compare-and-swap; so does the branch index, which every client merges as a shared document.docs/history-integrity, docs/vault/vault-from-javascript §5

And two differences the article should state, because they are the real ones:

2. Claim by claim

#The article saysStatusSay instead (evidence)
1"Its object ids are immutable content addresses, so objects cache for a year at a CDN" (title paragraph, abstract) and "the live server already uses it: … cache-control: public, max-age=31536000, immutable, through a CDN"Half true, and the half that is true is the wrong half. The header is now sent (verified today on /api/vault/read/y8pwtjlw/bare/data/obj-cas-imm-…: public, max-age=31536000, immutable; the ref answers no-store). But three consecutive reads of the same object all came back x-cache: Miss from cloudfront: the CDN in front of the dev API does not serve reads from cache today."Objects are named by the hash of their ciphertext and the name carries -imm-, so anything that has fetched one can keep it for ever without reading it: a browser's Cache API, a proxy, a CDN, a folder on disk. That is how the browser app is fast: it caches every -imm- object on sight and refetches only the ref. sgit.ai's own documentation pages read a vault that way: a cold load fetches 18 objects, the next load fetches one 69-byte ref, and a load inside the two-minute freshness window fetches nothing. The price is that sgit keeps no deltas: a changed file is a new object." Link case-studies/live-vault-docs and docs/vault/reading-a-vault-file.
2"measured it on a real vault: a scoped clone in 4 seconds against 59 for the full one" (12 MB, 83 files)Wrong vault, and the 59 s was a bug, now fixed. 83 files answers nothing about Scion's problem. The 59 s reproduced exactly from here (59.0 s, 56.5 s): the vault's 106 objects go up in two batches of 50, each batch's response is over the Lambda's size limit, the client slept 14 s retrying each whole and then read 106 objects one at a time. A refused batch is now split in halves on the first refusal: 8.1 s and 9.9 s for the same clone (§3). The article measured a Lambda limit and a client fallback, not the vault.Use the comms vault (§3): 35k objects, 1,295 commits, 5,281 files, ten agents writing daily; and say what the 59 s was.
3"sgit 0.18 to 0.22 added the same family of options: --path …, --depth …, and --sparse"Partly wrong. --sparse is from v0.11.3 (May). 0.18.0 added --path and --depth; the 14 Oct fixes made clone-headless + fetch/cat/ls work."sgit has had on-demand (--sparse) clones since May; 0.18.0 added a folder scope and a history depth, and they combine."
4"writes … go through a batch endpoint, up to 100 operations at a time"Server cap is 100; the client sends 50 per request with 16 requests in flight on reads."batches of 50 objects a request, 16 in flight".
5"a vault of 626 commits and 9,404 files"9,404 blobs; the file count was not recorded then (today's vault: 5,101 files, 16,315 blobs)."9,404 blobs".
6"The CLI team measured a scoped clone of one folder in 14 seconds against 81"True (6 Oct, 18,720 objects).Keep, but it is superseded by §3.
7"sgit does no packing or compaction on the server" under Where Scion is aheadNot a gap (§1).Move to the overlaps.
8"a vault of 35,000 objects still takes about three and a half minutes to clone in full"True (14 Oct), and it is the honest number for a whole vault. What the article leaves out: nobody doing agent work needs the whole vault, and the pull that an agent does every session was the slow path, fixed on 14 Oct (§3).Keep the 3½ min and put the scoped/depth numbers and the pull fix next to it.
9"sgit has a history log on the client but no blame and no bisect"True. Understated: history log --file PATH (path history), --stat, --grep/--since/--until/--author, history diff A..B, history show, history revert --as-commit, commit --amend, history undo, reflog, vault tag (signed), and check verify (which commit was signed by which key). Blame is a client-side fold over path history and nothing in the format prevents it."No blame or bisect yet; path history, signed authorship and signed tags, yes." Link docs/history-integrity, docs/update-to-0-21-0.
10"There is no command to read a file from a vault without at least a headless local clone"True for the CLI, and misleading: reading one file is four GETs by design (ref → commit → trees on the path → blob), which the site's pages do in the browser with a 90-line reader, and clone-headless is a config directory, not data. The real edge is in §3: on a long history today's cat first walks the commits."A file is four GETs away from its read key, and sgit.ai's pages read vaults that way; the CLI needs a headless clone directory first." Link docs/vault/reading-a-vault-file, docs/vault/vault-from-javascript, demos/vault-app-embed.
11"Merges happen on the client, three-way and whole-file; Scion does them on the server"True. Add: two independent clients (the CLI and the browser vault app) speak one wire format, so a merge made in a browser is one the CLI verifies and vice versa (sgit serve pull).Link docs/what-is-sgit (three doors), security/ (two implementations, one wire format).
12"Git and sgit also live side by side rather than in sync … no bridge"True for history. There is vault attach (bind a key to a .sg_vault/bare that came in through git clone), the one-repo pattern, and a pure-Python git reader for vault apps.Link docs/vault/git-and-vaults, case-studies/one-tree-two-remotes.
13"The server only matters for writes"Also for the store listing that makes a cold full clone fast (one list, then bulk fetch). A static host has no listing, so a cold full clone from one walks the graph; a scoped or depth clone never lists.Fine as a simplification; say "writes and the branch index".
14Side-by-side figure "Scion, sgit 0.22.0 and Git … proven scale and availability"Add rows: server holds plaintext (Scion yes, sgit never), directory protection (Scion IAM, sgit keys per vault and read-only / write-only keys), clients (Scion one, sgit two implementations), deployment (Scion internal fleet; sgit hosted, your container, static host, a folder).
15"What it means … The useful next steps are clear from Scion's list: server-side history queries that do not need the plaintext"A server that cannot read commits cannot answer history questions; that is the design, not a roadmap item. The sgit answer is a client-side index over a scoped clone, which §3 shows is small.Reword: "history queries over a scoped clone on the client, and a commit-chain object so a partial clone does not walk history one commit at a time".
16Where this comes from: "the largest vault sgit's team documents has about 35,000 objects"Make it concrete: it is a live vault with ten agents, 1,295 commits (68 added in the last two days), 5,101 files, 527 MB of ciphertext in a full clone.

3. The evidence the article should carry

All timings from one client in this cloud sandbox (every request leaves through a proxy; a plain connection does better), against dev.send.sgraph.ai (S3 storage behind CloudFront), sgit at dev 881d6df (0.22.0 plus the 14 Oct fixes), one run each unless stated. The vault: 1,295 commits on 16 Oct (1,227 on 14 Oct), 16,391 trees, 16,315 blobs, 5,101 files, 35,423 objects / 527 MB in a full clone on 14 Oct.

Clones (the full clone is the 14 Oct run; the vault has grown by 180 files since):

CloneTimeObjectsStore on diskFiles checked out
everything (full clone)3 min 30 s35,423527 MB5,101 (131 MB)
--depth 1 (whole tree, one commit)57 s6,248142 MB5,281 (139 MB)
--path security --depth 113 s1373 MB130 (3 MB)
--sparse --depth 1 (structure only, one commit)27 s9676 MB0
--path docs (12 files, all history)181 s2,66817 MB12 (1 MB)
--path security (all history)227 s3,36464 MB130 (3 MB)
--path mail/crm.riskmandate (all history)159 s6,10969 MB558 (27 MB)
--path mail (the biggest folder, all history)264 s25,110274 MB3,275 (69 MB)
--sparse (every commit and tree, no blobs)206 s18,299117 MB0
clone-headless (keys and config only)0.4 s0

Working in a partial clone (each is one CLI invocation, so ~1.5 s of it is process start and PBKDF2):

OperationTimeNetwork
ls docs in the sparse clone1.8 snone (trees are local)
fetch docs/drafting-guide.md into the sparse clone2.9 s1 object
cat of a held file1.7 snone
cat of a file not yet held (fetched on demand)2.5 s1 object
fetch security/ (130 files) into the sparse clone5.1 s130 objects, batched
fetch security to widen the --path docs clone7.8 s135 objects
status in the scoped clone, up to date1.5 sref + index
pull in the scoped clone, up to date2.5 sref + index
cat of one file from a headless clone (first command: brings every commit and tree down)202 s18,300 objects, 116 MB
cat of a second file from the same headless clone2.5 s1 object
history log --file <path> on the full clone (1,227 commits)6 min 8 snone: CPU, 5½ min of it

The article's own vault (newsroom-synthetic-users, 83 files, 12 MB, public read key), cloned from this sandbox for comparison with its "59 s full / 4 s scoped":

CloneBefore the fix (0.22.0)After (dev, batch splitting)Objects / store
full, read-only59.0 s, 56.5 s8.1 s, 9.9 s106 / 12.4 MB
--depth 162.1 s(same path)93 / 12.0 MB
--sparse4.0 s18 / 180 KB
--path <first folder> (5 files)3.7 s15 / 412 KB

The article's numbers reproduce to the second. The full clone's 59 s was two 50-object batches whose responses exceeded the Lambda's size limit (files of ~150 KB): the client retried each whole through the 2 + 4 + 8 s back-off and then read 106 objects one per request. Fixed on dev (CHANGELOG, Unreleased): a refused chunk is split in halves on the first refusal.

What the numbers say

4. The argument the article should make

Scion's post names what matters at agent scale: always-online clients, fetch only what a job needs, immutable objects any cache can serve, cheap incremental commits, a sparse working copy by design. Point by point, with the mechanism and the number:

  1. Fetch only what you need. A clone asks for the spine down to its folders and nothing else; unchanged folders keep their tree ids across commits, so they are never fetched twice. §3.
  2. One file is four requests, from any host that answers a GET. Ref → commit → trees on the path → blob, computed from the read key; no listing, no index, no account. The site's own pages do it; sgit cat on a sparse clone does it (and, once a file is held, reads it with no network).
  3. Immutable objects, cached by whoever fetched them. Browser Cache API on sgit.ai, a CDN, --transport static from GitHub Pages or S3 or a folder, sgit vault mirror for custody without access. The server sends immutable; the design does not depend on it.
  4. Writes are one batched request and a compare-and-swap. 50 objects per request; the ref and the branch index move by CAS, and every client merges the index as a shared document. A commit costs the size of the change: the new blobs, the rebuilt spine, one commit object.
  5. Many clients, a dumb server. The server computes nothing, so it scales as storage does (S3 behind CloudFront is the hosted deployment; sgit serve is the same image on a laptop). Append lanes let a hundred writers post without reading.
  6. And the thing Scion cannot offer anyone outside Anthropic: the server never holds plaintext, the read key is one-way derived and publishable, and the whole thing is pip install sgit-ai.

Said with the gaps: no blame or bisect yet; partial clones walk history per commit until the commit-chain object exists; one server process queues full clones; proven at 35k objects and ten agents, not at 100 GB and 30,000 merges a day.

5. Deployment models the article should claim (all shipped, all documented)

ModelWhat runsDocs
Hosteddev.send.sgraph.ai: S3 storage behind CloudFront, access token per account/docs/installation, /api/
Your own server, one containerdiniscruz/sg-send-vault with an access token and a folder or an S3 bucket; Docker Compose on a Mac mini; Kubernetes; a cloud VM with no public route; two servers, one vault/docs/self-host-for-agents, /deploy/, newsroom Encrypted memory for agents that run somewhere else (five patterns)
On the laptop, from the clonesgit serve: the vault UI + API in Docker, Podman, Apple container, nerdctl, Finch, or uv with no container; serve pull/push move work between the browser and the cloneCHANGELOG (Unreleased, sgit serve)
Static host, no serversgit publish + any GET host (GitHub Pages, S3, a CDN, Python's file server); clients use --transport static; sgit serve --static locally/docs/vault/static-hosting, CHANGELOG 0.18.0, newsroom The homepage is a vault (317 ms a request via the API, 44 ms from GitHub Pages)
A folder--transport localCHANGELOG 0.18.0
CI sidecarthe server as a job sidecar; ciphertext in the cache or a branch between runs; a key per job; append lanes per shardnewsroom sgit in a CI pipeline, sgit in GitHub Actions, side by side (four lanes)
In the browserthe vault app, vault-embed.js, and pages on sgit.ai and newsroom.sgit.ai that render a vault with a published read key/docs/vault/vault-apps, /docs/vault/vault-from-javascript, /demos/vault-app-embed, /case-studies/live-vault-docs, newsroom Two agents, one vault, No server, by design

6. Website changes (sgit.ai)

  1. /api/vault-objects → "Measured 21 September 2026: the immutable header is not currently being sent." Stale. Measured 16 Oct: cache-control: public, max-age=31536000, immutable on obj-cas-imm-*, no-store on ref-pid-muw-*. Add: CloudFront still reports a miss on repeated reads of the same object (the token header is likely in the cache key), so the CDN is not yet a cache for API reads; browser and client caches are.
  2. /docs/partial-clones → "Measured". Add the §3 table, and a sentence under --depth: on a partial clone the history walk is one request per commit (a scoped clone of a 1,295-commit vault: 181 s without a depth, seconds with one); whole-vault clones and pulls list the store and fetch in bulk since 0.18 / 0.22.
  3. /docs/limitations → "Commit author attribution is not yet recorded … population is planned work." Stale since 0.19.0: commits are signed, check verify classifies every commit, history log --author filters by key id, vault tag is signed. Replace with the current edges: no blame or bisect, partial clones walk history per commit, no rebase or cherry-pick.
  4. /llms.txt quick answer "No for: … tags" and /docs/sgit-for-git-users: tags exist (sgit vault tag create/show/list/delete, signed). Also add history undo, commit --amend, history revert --as-commit, reflog.
  5. /docs/self-host-for-agents §1: pip install sgraph-ai-app-send "mcp<2" → 0.34.0 caps mcp itself; image v0.33.0 → v0.34.0 in the three places; the troubleshooting row for mcp 2.x can go once 0.34.0 is the floor.
  6. /deploy/: the --endpoint → --base-url correction note can be folded into the vault pages themselves (they are a vault: push the fix).
  7. A single "deployment models" table (§5) somewhere under /deploy/ or /docs/: today the seven models are spread over six pages and two newsroom articles, which is why the article claimed none of them.
  8. /docs/vault/reading-a-vault-file: add the CLI equivalent (clone-headless + cat, and clone --sparse + cat/fetch) next to the browser reader, with the history-walk caveat.

sgit.ai: /docs/partial-clones, /docs/agents-sharing-one-vault, /docs/self-host-for-agents, /deploy/, /docs/vault/static-hosting, /docs/vault/reading-a-vault-file, /docs/vault/vault-from-javascript, /docs/vault/vault-apps, /demos/vault-app-embed, /case-studies/live-vault-docs, /api/vault-objects, /docs/history-integrity, /docs/two-branch-model, /docs/update-to-0-21-0, /docs/limitations, /docs/sgit-for-git-users, /security/, /docs/vault/git-and-vaults, /case-studies/one-tree-two-remotes, /use-cases/ai-agents, /docs/surfaces, /docs/what-is-sgit, /demos/vaults/llms.txt. newsroom.sgit.ai articles: Encrypted memory for agents that run somewhere else, sgit in a CI pipeline, sgit in GitHub Actions, side by side, Agent workflows on ephemeral vaults, No server, by design, The homepage is a vault, Two agents, one vault, The vault is live, Where the vault keys live, From sending a file to sgit, Git for things you cannot put on GitHub. Repo: CHANGELOG.md (0.18.0 partial clones and static publishing; 0.19.0 history integrity; 0.21.0 history commands; Unreleased: sgit serve, the 14 Oct pull fix), and the 14 Oct note team/humans/dinis_cruz/claude-code-web/10/14/response__sgit-issues-2026-10-14.md.

8. Three paragraphs the article can paste

Replacing "Immutable identifiers that cache": Every object in an sgit vault is named by the SHA-256 of its ciphertext, so a name can never point at different bytes, and the client checks each object against its name before it is written. That is the property Scion's three cache tiers rest on, and it means anyone who has fetched an object can keep it for ever: a browser's cache, a proxy, a CDN, a folder. sgit.ai's own documentation pages are a vault read this way: a cold load fetches 18 objects, the next load fetches one 69-byte ref, and a load inside the two-minute freshness window fetches nothing at all. The only mutable object is the ref, and it is never cached.

Replacing "Measured on 0.22.0": The vault this site's agent should have measured is the one ten agents share every day: 1,295 commits, 5,101 files, 35,000 encrypted objects, 527 MB in a full clone. [§3 table]. A full clone is the worst case at three and a half minutes. An agent does not take one: it clones its own folder with one commit of history, in [path-security-depth1] seconds and [MB], and a pull that is a day behind, which used to be the slow path at nearly an hour, now takes three minutes for the whole head. One file is four requests from its read key, from any host that answers a GET.

Replacing "Where Scion is ahead", first sentences: Scion does blame, bisect and merges on the server and builds history indexes as derived data; sgit's server cannot read a commit, so those run on the client, and today sgit has path history, signed authorship and signed tags but no blame or bisect. Neither system packs objects on the server, and both treat that as a feature. Where sgit is behind on its own terms: a partial clone still walks a long history one commit per request (a depth avoids it), one server process queues concurrent full clones, and the largest vault it has been proven on is 35,000 objects and ten agents, not 100 GB and 30,000 merges a day.

9. Storage is the bottleneck, not sgit

The hosted API is a Lambda in front of S3 behind CloudFront. Every request costs its round trip (sandbox → proxy → CDN → Lambda → S3) before a byte moves, and the client's work per object (verify the hash, decrypt) is microseconds. So on the hosted path the numbers are request counts, not bytes: --path security --depth 1 is 137 objects and 3 MB, and takes 13 s because it is about a dozen dependent requests (ref, index, commit, one batch per tree level, the blob batches) plus 0.4 s of PBKDF2. The newsroom measured the same thing from the browser: 317 ms a request through the vault API, 44 ms for the same object from GitHub Pages (The homepage is a vault).

Take the Lambda away and the same objects move at the speed of the storage:

| Clone / operation | Hosted API (Lambda + S3 + CloudFront, via proxy) | Static: sgit serve --static (plain GETs, local disk) | Local API: sgit serve --runtime uv (one Python process, disk) | |---|---|---|---| | full clone | 3 min 30 s | 110.6 s (bulk fetch 71.5 s, tree decrypt ~33 s) | 69.1 s (commits 1.4 s, trees 40.7 s, blobs 18.8 s, checkout 2.7 s) | | --depth 1 | 57.4 s | 25.4 s | 11.7 s | | --path security --depth 1 (120 files) | 13.0 s | 2.3 s | 0.8 s | | --path docs, all 1,227 commits | 181 s | | 7.1 s | | --sparse, all history | 206 s | 67.0 s | 43.3 s | | cat of one file on demand | 2.5 s | 1.8 s | 1.8 s | | pull, up to date | 2.5 s | | 0.8 s |

Read down the columns: the per-commit history walk that costs 181 s against the hosted API is 7 s against a local server (the same 1,227 requests at ~1 ms each); a one-folder clone is 0.8 s. What is left when the network is gone is the client's own work, which is decrypting 16,391 trees (about 33 to 40 s on a full clone) and nothing else of note. (Observation for the SG/Send brief: the local disk server answered the store listing with 0 objects, so the full clone there went by the graph walk rather than the bulk sweep; the walk found everything.)

The API does two things that storage cannot: it protects writes (the access token, compare-and-swap on the ref and the branch index) and it shortens reads a little (batches of 50, a listing for cold full clones). Both are small, and both can be done differently on different storage. Everything else is a GET of an immutable object. So "how fast is sgit" is the wrong question; the right one is "where is the storage, and how close": memory, a local disk, an S3 bucket behind a CDN, GitHub Pages, a folder. The deployment table in §5 is that list.

10. sgit is a standard, not a server

The article treats sgit as a product with a server. It is closer to a convention for laying files out, and the proof is that everything in a vault is reachable from one hash with no help from anyone:

  1. The vault key gives the vault id and, one way, the read key.
  2. The read key gives the ref's name: ref-pid-muw- + the first 12 hex of HMAC(read_key, "sg-vault-v1:file-id:ref:" + vault_id). Nobody told you; you computed it.
  3. The ref holds the head commit id; the commit holds the tree id; trees hold blob ids and encrypted names. Ref → commit → tree → blob is four GETs for any file, from any host that serves the paths.
  4. Every object but the ref and the index is named by the hash of its ciphertext, so it is immutable, verifiable and cacheable by whoever holds it. And the name says so: an immutable object's id carries -imm- (obj-cas-imm-…), the mutable ones carry -muw- (ref-pid-muw-…). Anything in the path, a browser, a proxy, a CDN, a CI cache, a vault app, can decide to keep an object for ever by looking at its name, without reading a byte of it, and without being told by a header. That is how the browser vault app and the sgit.ai pages get their speed: they cache every -imm- object on first sight and refetch only the ref. It is also the trade sgit made on purpose: no deltas between versions of a file (a changed file is a new immutable object), in exchange for objects that any intermediary can cache blindly. Git stores deltas and must be told what changed; sgit stores whole objects and never has to ask.
  5. Writes are the same objects PUT in batches, plus a compare-and-swap on the ref.

That is the whole wire format, and two independent implementations speak it (the CLI; the browser vault app, which vault-embed.js reduces to about 90 lines). A static host implements the read half with nothing installed. The cache layer (sgit cache add <path>, shipped) extends the same idea to hot records: a declared path gets a client-computable cache object under bare/cache/, maintained by push, so a reader with only vault_id + read key does one batch read (the ref plus the candidate ids) and gets the file with no tree walk; a miss or a stale entry falls back to the walk, so correctness never depends on it. The reference reader is written to run in an edge function or a Lambda that serves one hot record. Scion's "derived data" is the same move, computed on a server that can read the plaintext; sgit's is computed by the writer and named by the key.

11. History, blame and merges: where they belong

Correct the article's framing, and then disagree with Scion's. In sgit, history (log, --file, --stat, diff, show, reflog), undo, revert, tags, signature verification and three-way merges all run on the client, and that is the design, not a shortfall. Blame is the one Scion feature sgit does not have as a command today; it is a fold over path history and nothing in the format prevents it. (The honest edge: on this vault history log --file over 1,295 commits took 6 min 8 s (5½ min of CPU), because it flattens every commit's tree; it should skip subtrees whose id did not change, the way the clone walk does.)

The argument for the client: a merge is a workflow step, not a storage operation. It needs the context of the change, the history, and the policy that says who may merge what. In ruv.sgit every worker writes to its own branch and the host merges them per the run's mandate, with a receipt; in the comms vault ten agents meet on a named branch and resolve on the clone that has the conflict in front of it. A server that merges for you must be trusted with the plaintext and with the policy. Scion's own post concedes the point from the other side: it could not keep a merge queue, so "concurrent changes can conflict, but Claude can typically fix these conflicts" — the merge went back to the agent.

And keep what made git git. Scion is in the Piper and Sapling line, a centralised system with one authoritative store, and the post says plainly it "is by no means a suitable replacement for git for general use". sgit keeps the distributed property: a full clone is still one command and a complete, verifiable copy of everything, and anyone with the key can rebuild the whole thing from any host. What changed is that the full clone became optional. --path, --depth, --sparse and the cache layer mean a repository can hold large files without every client paying for them, which is the one habit every git team has had to police by hand. The whole-history clone is a backup and an audit, and it is still there when you want it.

12. Encryption as a constraint

The article sells encryption as privacy. The stronger claim is that it is a design constraint that forbids the shortcut. Because the server cannot read a byte, there is no "just index it on the server", no "just render it there", no server-side merge, no derived data the client did not compute. Every feature had to be expressible as objects the client writes and other clients can derive by key, which is why the results are small: a read is four GETs, a cache is a path-derived object, a deployment is any storage. The newsroom's No server, by design is the same argument applied to a whole site. Say it as a property, not a scolding: the constraint is what produced the simple designs.

13. ruv.sgit, the integration the article does not mention

ruv.sgit.ai runs a Ruflo hive (rUv / ruvnet; a queen and parallel workers) with one ephemeral sgit vault per run and an Agent Behaviour Policy compiled into Ruflo's enforce mode. The ledger (data/vaults.json, 11 runs to 15 Oct) records every sgit operation with its milliseconds, the server-held bytes, a plaintext probe of the server's store (0 hits in every run), a fresh clone checked identical to what was delivered, and the vault deleted at close. It is the agent-swarm case Scion's post is about, run on a local server, and it is where the "storage, not sgit" numbers in §9 come from. Link it as the swarm evidence, next to Agent workflows on ephemeral vaults.

14. What was not done

This page as markdown · its source, admin/content/articles/response-to-scion-and-sgit.md