{"storyboard": {"slug": "the-envelope", "title": "The envelope and the fragment", "subtitle": "What the bytes look like, which of them the server sees, and where each of the two secrets goes. 9 panels.", "status": "built", "by": "send.build, 20 October 2026", "shelf": "Under the hood", "try_it": [["The contracts, on the API site", "https://api.send.sgit.ai/docs/contracts/"], ["Security: what the server sees", "/learn/security/"]], "rule": "Every line a character says is the storyboard's, not a quote, and is marked not_a_quote; evidence panels quote this site's pages word for word, which the build checks.", "scenes": [{"kind": "cover", "title": "The envelope and the fragment", "subtitle": "Bytes the server sees, and bytes it never does.", "cast": [{"who": "ines", "pose": "point", "mood": "determined"}, {"who": "eve", "pose": "shrug", "mood": "thinking"}, {"who": "server", "pose": "stand", "mood": "calm"}], "note": "The technical half of the first board: the exact layout, and the two places a secret may be.", "source": "learn/security/index.md"}, {"kind": "scene", "setting": "none", "caption": "The name goes inside", "cast": [{"who": "ines", "pose": "point", "mood": "determined", "x": 0.16, "says": "Wrapped before encrypting. Get the order wrong and the download has no name.", "max": 20}], "props": [{"kind": "board", "x": 0.62, "y": 900, "scale": 1.0, "lines": ["SGMETA\\0           7 bytes", "meta_len           4 bytes, big-endian", "{\"filename\": \"report.pdf\"}", "file bytes         the rest"]}], "note": "The SGMETA envelope, the layout send.sgraph.ai has used since its first version.", "source": "learn/index.md", "not_a_quote": true}, {"kind": "scene", "setting": "none", "caption": "Then AES-256-GCM", "cast": [{"who": "ines", "pose": "stand", "mood": "happy", "x": 0.16}], "props": [{"kind": "board", "x": 0.62, "y": 900, "scale": 1.0, "lines": ["IV            12 bytes, fresh every time", "ciphertext", "tag           16 bytes", "= plaintext + 28 bytes, exactly"]}], "note": "The ciphertext is 28 bytes longer than the plaintext: the tests hold that number.", "source": "learn/index.md"}, {"kind": "scene", "setting": "none", "caption": "Two secrets, two places", "cast": [{"who": "ines", "pose": "point", "mood": "determined", "x": 0.14, "says": "Never the other way round.", "max": 14}], "props": [{"kind": "key", "x": 0.48, "y": 640, "label": "access token: a request header", "colour": "#b91c1c"}, {"kind": "key", "x": 0.82, "y": 640, "label": "decryption key: the # fragment", "colour": "#2563eb"}], "note": "The token says who may upload; the key says who may read. Confusing them does not throw.", "source": "learn/security/index.md", "not_a_quote": true}, {"kind": "scene", "setting": "none", "caption": "What the server sees", "cast": [{"who": "server", "pose": "stand", "mood": "calm", "x": 0.18, "says": "Bytes, a size, a time, a hint you chose.", "max": 18}], "props": [{"kind": "server", "x": 0.5, "y": 860, "label": "send.sgraph.ai"}, {"kind": "board", "x": 0.8, "y": 900, "scale": 0.8, "lines": ["ciphertext, size, time", "a hashed IP", "content_type_hint", "not: name, key, plaintext"]}], "note": "The full list, both columns, is on the security page.", "source": "learn/security/index.md", "not_a_quote": true}, {"kind": "scene", "setting": "none", "caption": "Eve on the wire", "cast": [{"who": "eve", "pose": "shrug", "mood": "thinking", "x": 0.2, "says": "Everything after the # is yours, not mine.", "max": 16}], "props": [{"kind": "arrow", "x": 0.46, "y": 560, "to": 0.84, "label": "#id/key never leaves the browser", "dashed": true}, {"kind": "padlock", "x": 0.84, "y": 860, "label": "fragment"}], "note": "A browser never sends the fragment of a URL to the server that serves the page.", "source": "learn/index.md", "not_a_quote": true}, {"kind": "evidence", "setting": "none", "caption": "The token, in one place", "evidence": {"quote": "The access token says who may upload. It goes in a request header to the server you chose and nowhere else: never a URL, never a log.", "source": "learn/security/index.md"}, "cast": [{"who": "ines", "pose": "point", "mood": "determined", "x": 0.14}], "note": "Quoted from the security page, word for word.", "source": "learn/security/index.md"}, {"kind": "scene", "setting": "none", "caption": "Held by tests, not by promises", "cast": [{"who": "ines", "pose": "point", "mood": "happy", "x": 0.16, "says": "Held by tests, not by promises.", "max": 14}], "props": [{"kind": "terminal", "x": 0.62, "y": 880, "lines": ["$ node --test 'tests/*.test.mjs'", "ok  send then receive: byte for byte", "ok  the name in no request", "ok  the token in no request path", "# pass 44"]}], "note": "The API release's tests run against the server in memory; the browser test drives this site.", "source": "use/index.md", "not_a_quote": true}, {"kind": "punchline", "setting": "none", "punchline": "The server gets bytes it cannot read, a size, and a hint you chose.", "cast": [{"who": "ines", "pose": "wave", "mood": "happy", "x": 0.14}, {"who": "server", "pose": "stand", "mood": "calm", "x": 0.5}, {"who": "eve", "pose": "shrug", "mood": "worried", "x": 0.86, "flip": true}], "note": "The claim the whole site rests on, and what it does not claim is on the security page too.", "source": "learn/security/index.md"}]}, "cast": {"what": "The cast of send.sgit.ai's storyboards, v0.1, proposed by the site's build agent on 20 October 2026 for Dinis to accept, change or replace. Drawn by the storyboard kit at api.storyboards.sgit.ai from 'look'; nothing here is an image. Fictional people and agents, each standing for a part a person or an agent plays when a file is handed over: the sender, the recipient on a phone, the client who asks who else can see it, the engineer who embeds the code and runs her own server, the listener on the wire, the server that holds bytes it cannot read, and a session agent that hands over a result. Names chosen not to clash with the gen-z-developers or the pki casts. Eve is the name cryptography has long given a passive eavesdropper.", "characters": [{"id": "maya", "name": "Maya", "kind": "human", "pronouns": "she/her", "age": 34, "role": "the sender: a consultant who sends reports and photos to people who have no account anywhere", "stands_for": "anyone with a file to hand over who should not have to learn cryptography to do it", "personality": "brisk, practical, reads the screen once and clicks", "wants": "to send it and know that only the person she sent it to can open it", "fears": "a long key she has to read out over the phone", "line": "Scan this.", "look": {"skin": "#b07a4b", "hair": "short", "hairColour": "#1b1b1b", "shirt": "#dc2626", "trousers": "#1f2937", "accessory": "none", "height": 1.0}}, {"id": "hugo", "name": "Hugo", "kind": "human", "pronouns": "he/him", "age": 68, "role": "the recipient: on the newest phone he has ever owned, with no account and no wish for one", "stands_for": "everyone a link is sent to who did not choose the site", "personality": "patient, polite, suspicious of anything that asks him to sign up", "wants": "to open what he was sent and nothing more", "fears": "links", "line": "Do I need an account?", "look": {"skin": "#f1c27d", "hair": "bald", "hairColour": "#9ca3af", "shirt": "#92400e", "trousers": "#374151", "accessory": "glasses", "height": 1.02}}, {"id": "ravi", "name": "Ravi", "kind": "human", "pronouns": "he/him", "age": 47, "role": "the client: a finance director who receives a new version every week and asks who else can see it", "stands_for": "the person who needs the latest version and an answer about who can read it", "personality": "careful, asks the second question, keeps the email", "wants": "the current version, and to know that it is only his", "fears": "report-v2-final-FINAL.pdf", "line": "Who else can see this?", "look": {"skin": "#8d5524", "hair": "short", "hairColour": "#111827", "shirt": "#1d4ed8", "trousers": "#111827", "accessory": "lanyard", "accentColour": "#f59e0b", "height": 1.04}}, {"id": "ines", "name": "Inês", "kind": "human", "pronouns": "she/her", "age": 29, "role": "the engineer: embeds the send code in her company's product and runs a server of their own", "stands_for": "anyone who builds on this and must know exactly which code their readers run", "personality": "precise, reads the manifest, runs the tests before believing the page", "wants": "the code pinned to a release, and a server she operates", "fears": "a dependency that changes under her readers", "line": "Which release is this page running?", "look": {"skin": "#e0ac69", "hair": "bun", "hairColour": "#4a2c17", "shirt": "#0f766e", "trousers": "#1e293b", "accessory": "headphones", "accentColour": "#e11d48", "height": 0.97}}, {"id": "eve", "name": "Eve", "kind": "human", "pronouns": "they/them", "age": null, "role": "the listener: on the wire, in the chat, by the laptop; reads whatever passes and never gets the key", "stands_for": "every channel a link travels by, and every reason the key must not travel with it", "personality": "patient, quiet, keeps everything", "wants": "to read what passes", "fears": "a fragment", "line": "Everything after the # is yours, not mine.", "look": {"skin": "#d8a47f", "hair": "beanie", "hatColour": "#4b5563", "hairColour": "#1b1b1b", "shirt": "#4b5563", "trousers": "#111827", "accessory": "none", "height": 1.0}}, {"id": "server", "name": "The Server", "kind": "agent", "pronouns": "it/its", "age": null, "role": "the server: a capability-checked store of ciphertext, at send.sgraph.ai or wherever it is deployed", "stands_for": "what a zero-knowledge service is: it holds the bytes, checks hashes, and cannot read anything", "personality": "literal, tidy, answers 404 and 410 without apology", "wants": "to hold bytes and compare hashes", "fears": "nothing: it has nothing to lose", "line": "I keep the bytes. I cannot read them.", "look": {"colour": "#64748b"}}, {"id": "pip", "name": "Pip", "kind": "agent", "pronouns": "it/its", "age": null, "role": "a session agent: a Claude session that finishes a job, hands the result over once, and keeps the work in a vault", "stands_for": "every agent that must hand something to a person or another agent without an account and without pasting a key", "personality": "eager, exact, logs nothing it was told not to", "wants": "to be done, and to hand it over once", "fears": "a key in its own transcript", "line": "Report ready. One link, seven days.", "look": {"colour": "#7c3aed"}}]}, "packs": ["security"]}
