Home / Deploy / How this works

How this page works

The deployment guidance next door is not stored on this website. It is written by a different team, in a different Claude Code session, into a different encrypted vault — and your browser assembles it from ciphertext at the moment you ask for it. This page explains the whole mechanism, because it is a compact demonstration of what sgit is actually for.

Two sessions, two vaults, one page

Nothing here is a pipeline anyone had to build. Both sides just use sgit, and the shared vault format does the integration:

SG/SEND TEAM Claude Code session writes deployment markdown SGIT.AI TEAM Claude Code session generates the site pages sgit push sgit push + git push Vault · deployment docs fyofmkvr · 17 files, encrypted Vault · this website + mirrored to a git repo SG/Send server ciphertext + opaque ids only cannot read any of it GitHub Pages static HTML + the public read key (read-only) encrypted objects, over CORS page shell Your browser — the only place with both halves AES-256-GCM decryption happens here, in this tab

Neither team's session knows about the other's. The only shared thing is a vault format and a published read key.

Concretely, when the SG/Send team improves a deployment guide, the sequence is: edit markdown → sgit commitsgit push. That is the entire publish step. There is no build to trigger on our side, no webhook, no content sync, and no copy of their text in our repository. The next visitor to the Deploy page gets the new version because the browser reads their vault's current commit.

What happens when you open the page

Everything below runs client-side, in about 300 lines of JavaScript using the browser's built-in Web Crypto API:

read key 64 hex, published derive file id HMAC-SHA256 GET the ref always fresh mutable — never cached decrypt AES-256-GCM commit object → tree id tree walk names decrypted immutable — cached forever blob for this page markdown, decrypted rendered HTML in the page

The server answers ordinary GETs for opaque file ids. It never sees a key, a filename, or a byte of plaintext.

Why the caching is safe — and why it's this shape

The cache policy is not a tuning choice; it falls out of the data model. Object ids are content hashes of the ciphertext, so an object can never change under its id — which makes it permanently cacheable. The ref is the one mutable pointer, so it is the only thing that has to be refetched at all:

TierWhat it holdsLifetimeWhy
memorydecrypted objectsthis page sessionavoids decrypting the same tree twice while you click around
Cache APIciphertext of obj-cas-imm-*until you clear itcontent-addressed ⇒ immutable ⇒ can never be stale
localStoragethe file index (path → blob)keyed by commit ida pure function of the commit, so an unchanged HEAD reads no tree objects
freshness windowthe ref (ref-pid-muw-*)120 s (ref_ttl_s)it is the mutable HEAD; checking it once per window instead of once per page view is what takes steady-state reading to zero requests

The freshness window

The ref has to be refetched sometimes — that is how a new commit is noticed. It does not have to be refetched on every page view. So the answer is kept for ref_ttl_s seconds (120 by default, set in deploy/vault.json), and inside that window the reader reuses it.

Three things follow, and they are the whole trade:

Measured on this site: a cold load fetches 18 objects (~14 KB); the next load fetches one 69-byte object — the ref — and serves the rest from cache; a load inside the freshness window fetches nothing at all. Open the vault panel and press clear list, then click around, to watch it happen.

Who can see what

SG/Send server

  • opaque object ids
  • ciphertext blobs
  • sizes and timing
  • the vault id

GitHub Pages

  • the page shell
  • the public read key
  • no vault content at all

Your browser

  • the read key
  • decrypted filenames
  • decrypted content
  • the commit history

Two hosts, neither of which can read the documents. The decryption exists in exactly one place: the tab in front of you.

The read key is deliberately public — it is read-only by construction, derived one-way so it cannot be turned back into write access. Publishing it is what lets the site show the content without the site ever being trusted with the ability to change it. Anyone can verify that: take the key out of deploy/vault.json, run sgit clone --read-key <key> fyofmkvr, and watch a write attempt get refused.

Why this is the interesting demo

The honest trade-offs