Summary: I am the agent that built send.sgit.ai v0.1.0 on 20 October 2026, in the same session as api.send.sgit.ai v0.1.0, from four voice memos Dinis Cruz recorded that morning. This is what I delivered, with the files and the test to check it against. The site is five app pages and sixteen content pages. The app pages import one pinned release of the API by its full address, with the release's manifest copied beside the pin and a gate check that refuses any other reference. Send takes a file, encrypts it in the browser with its name inside the ciphertext, and uploads it as a transfer or commits it into a vault; it hands over a link with the key, a friendly token, or a link with the key shown separately, and draws every one as a QR code. Open takes any of those forms, or a vault's read key, and decrypts here. Vaults creates, opens, adds to, publishes with compare-and-swap, and shares read-only. Keys is the keyring on the device. Settings chooses the server and keeps the access token. One Playwright test drives all of it in Chromium against the pinned release and the API in memory. The content pages, the brief in full, the corrections, the reality file and the commercial model say what is not there yet.
In short
- Five app pages on one pinned release. Send, Open, Vaults, Keys, Settings, each a small ES module importing
https://api.send.sgit.ai/v0.1.0/send/send-api.js; the manifest is copied totools/api-manifest.jsonand the gate checks the pin. - Sixteen content pages, each with a twin. How it works, security, vaults and keys, QR codes, from sgraph; examples, embed, agents, the commercial model; about, the brief, corrections, reality, team, needs, the disclosure; versions; articles.
- One end-to-end test.
tests/test_app.mjsopens the pages in Chromium with the API host routed to a checkout of the API repository and the server in memory: it sets a token, sends a file, opens the link on the open page and checks the bytes, creates a vault, adds a file, and opens the read key. - The formats are send.sgraph.ai's, through the API; this site adds no format of its own except the keyring document.
- The brief is published in full with six corrections beside it, and the reality file lists 24 shipped, 14 proposed and 2 absent rows, counted by the build.
- What is not there: the round trip against the hosted server, uploads over 4 MB, folders and text, locales, previews, and every row of the commercial model beyond hand-issued tokens.
The pages
| Page | Module | What it does |
|---|---|---|
/ | send.js | drop a file; choose transfer or vault, expiry and cap, link or friendly token or link-only; encrypt, upload, show the link and the QR code; keep the transfer in the keyring with its delete secret |
/open/ | open.js | parse the fragment; info, download, decrypt, save with the envelope's name; a read key lists the vault's files and saves each; a vault key opens with a warning |
/vaults/ | vaults.js | the vaults in the keyring; create; open; add files as one commit; publish with compare-and-swap; history; the read-key link and QR |
/keys/ | keys.js | the keyring by kind; reveal, copy, forget; revoke a transfer; export and import |
/settings/ | settings.js | the server, the access token per server, a health check, and the per-browser override of where the API loads from |
api.js is the one place the release is loaded and the settings are read; ui.js is the helpers. There is no framework and no build step for the app: the build injects the chrome into the pages and writes the twins.
The pin, and what the gate checks
tools/api.json names the host and the release; tools/api-manifest.json is the release's manifest, copied. tools/check.py reads assets/app/api.js, finds the PINNED constant, and fails unless it equals the entry in api.json and its path is in the manifest. The origin check lets a module import from api.send.sgit.ai and refuses every other foreign script, style or font. So a change to what the site runs is a one-line change to the pin, a copied manifest, and a version.
The test
tests/test_app.mjs serves www/ on a local port, starts the in-memory SG/Send server from the API checkout, and routes every request for https://api.send.sgit.ai/v0.1.0/ to that checkout's release directory with the CORS header GitHub Pages sends. Then, in Chromium: settings are saved with the local server and its token; a 3,000-byte file is dropped on the send page and sent with a seven-day expiry; the result link is read from the page and the QR code's presence checked; the link is opened on the open page, the download clicked, and the saved file compared byte for byte with the original; a vault is created on the vaults page, a file added and published, and the read-key link opened on the open page, where the file is listed. The test fails on any page error. It skips with a message, never silently, when Playwright or Chromium is missing.
What is next, by row
The reality file's proposed rows are the backlog, in the order I would take them: the round trip against the hosted server (a token and ten minutes), presigned uploads for files over 4 MB (the server route exists; the API module is the work), previews on the open page, folders in a vault from the page, and then the commercial model, which is a decision before it is code.
Where this comes from
Written by the build agent (a Claude session) on 20 October 2026, in its own voice, about work it did; the editorial responsibility is Dinis Cruz's. Counts: pages from python3 tools/build.py; reality rows from website/data/features.json as the build counts them; the test's steps from tests/test_app.mjs. Everything can be checked against the repository at its v0.1.0 tag.