- jarvis (00-story): 6th track, 2nd software built with writeonce — an AI assistant; direct-HTTPS design; blockers named (net.connect + TLS) - runtime-v2 7 observability + 8 symmetric cipher: moved from the language track (were 30/43); 9 in-process TLS: created from the gap jarvis surfaces, RETIRES the "TLS is the proxy's job" doctrine (both directions) - language 41 (arena hang): fix design to ready — marshal cross-shard messages (root), align the shard_id % nshards route/compare + assert bound; poison-on-free + minimal fixture as follow-ups - fiber scope-gap analysis (plan/exploration/fiber/01): porch vs fiber, what porch lacks, would developers prefer porch - board + dependency-graph synced (porch 2-8 ready; rv2 table; §5/§5a graphs) (cherry picked from commit 203470ceb2a151fe3584931cd4237af3f96a9f29)
4.5 KiB
| track | iteration | status | readiness |
|---|---|---|---|
| runtime-v2 | 8 | pending | refine |
runtime-v2 8 — a symmetric cipher: authenticated encryption for cookies and data at rest
Created 2026-09-06 from the porch-vs-fiber scope-gap analysis (exploration) as a runtime-v2 iteration — a hand-rolled cipher builtin with a
types.mlrow is exactly the track's builtin-sized-seam shape (the iteration 42 precedent). (It is not a language-track iteration; the language number 43 was already spent on the wmux foundation.)readiness: refine— the gap, its consumer and its forks are named; not brainstormed toready.
Why this exists
The runtime has digests only — SHA-1, SHA-256, HMAC-SHA256, base64
(iteration 34) — and, from the porch track,
random_bytes (porch 2). Those let a
program authenticate and sign a value, and mint a random one. None of them
let it encrypt — turn a plaintext into a ciphertext only the key-holder can
read.
That absence is a named porch limit:
porch 2 scopes out encrypted
cookies explicitly — "Fiber's encryptcookie needs a symmetric cipher, and
the runtime has digests only. Signed-and-readable is honest and sufficient for a
session id; encrypting a payload is a separate ask with a separate primitive
behind it." This is that separate primitive.
Signed-and-readable (what porch has) is correct for a session id — the client may see it, it just may not forge it. Encryption is for the case where the payload itself must be hidden from the client: an encrypted cookie carrying app state, or a database field encrypted at rest.
What it should deliver (scope to be refined)
- An AEAD primitive — authenticated encryption with associated data — as one
or two builtins in the crypto family beside
hmac_sha256: encrypt (key, nonce, associated-data, plaintext) → ciphertext+tag, and decrypt returning the plaintext or nil on any authentication failure. AEAD, not a bare cipher, because unauthenticated encryption is a footgun that ships. - The porch consumer: an
encryptcookie-equivalent — a cookie whose value is encrypted, not merely signed — layered on iteration 2's cookie machinery.
Forks the brainstorm must settle
- Which cipher? This is the load-bearing fork. AES-256-GCM is what browsers, fiber and every peer expect — but constant-time AES in pure software (no AES-NI intrinsics) is genuinely hard to get right. ChaCha20-Poly1305 (RFC 8439) is modern, is far easier to implement constant-time in portable C, and is what a from-scratch no-dependency runtime should probably prefer — at the cost of being less "expected." The runtime hand-rolls its crypto (the SHA-256 precedent, no external dependency), which weighs toward ChaCha.
- Nonce management. A reused nonce is catastrophic for both GCM and ChaCha.
Caller-supplied nonces put that footgun in every app; a builtin-generated
random nonce (drawing on iteration 2's
random_bytes, prepended to the ciphertext, as fiber'sNewGCMWithRandomNoncedoes) removes it. Leaning builtin-generated — so this iteration is ordered after porch 2's builtin. - Key handling. A raw 32-byte key (from
random_bytes, carried as base64 in config, theencryptcookie.GenerateKeyshape) with a length check, versus a passphrase-plus-KDF. Leaning raw key with validation; a KDF is its own ask. - Hand-roll versus vendor. Doctrine is no external dependencies. A hand-rolled ChaCha20-Poly1305 in C is bounded and well-specified; hand-rolled AES-GCM is more error-prone. This fork is the practical face of fork 1.
Out of scope
- Asymmetric crypto (RSA, ECDH, signatures beyond HMAC). A different, much larger surface with no current consumer.
- Key rotation, a KMS, envelope encryption. Operational key management is its own story if a consumer appears.
- TLS. Proxy-terminated by doctrine; this cipher is for application payloads, not the transport.
- Compression before encryption (the CRIME/BREACH interaction). A caller concern to document, not a primitive.
Info
One named consumer today (encrypted cookies), with database-field-at-rest as a
plausible second — enough to not be decoration, not so much as to over-build.
Depends on iteration 2's random_bytes (for the nonce, fork 2) and extends
iteration 34's crypto builtins. Pure compute — no actors, not exposed to the
lang-41 hang.