- 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)
6 KiB
| track | iteration | status | readiness |
|---|---|---|---|
| runtime-v2 | 9 | pending | refine |
runtime-v2 9 — in-process TLS: retiring the proxy-termination doctrine
Created 2026-09-07 from the gap
jarvissurfaces — an assistant must dial an LLM over HTTPS, and the runtime has no outbound TLS. The developer chose the full overturn: the runtime gains TLS both directions, and the standing "TLS is the proxy's job" doctrine is retired.readiness: refine— the gap, its consumers and its forks are named here; the implementation is deliberately left as this story's load-bearing fork, not settled.
Why this exists — and what it overturns
Three documents record the same standing decision, and this story reverses it:
- "TLS — permanently the proxy's job (framework doctrine)" — language 34 (crypto builtins, line ~83).
- "TLS — proxy-terminated, by doctrine, unchanged… the story says so out loud
rather than implying HTTPS clients" —
language 38
(which adds
net.connectas plaintext outbound TCP and explicitly refuses HTTPS). - "TLS, HTTP/2 | nobody — proxy-terminated by doctrine" — porch's "what this track does NOT own".
The doctrine was reasonable while nothing in-tree needed to dial anything: a
front proxy terminates inbound TLS, and there were no outbound callers. jarvis
breaks that — its whole job is to reach a remote API — and the developer's
direct-HTTPS choice for it means the runtime, not a companion, owns the
connection. Rather than carve out a one-directional exception, the decision is to
give the runtime TLS in both directions: outbound so a .wo program can dial
HTTPS, and inbound so porch can terminate TLS itself instead of mandating a
proxy in front of every deployment.
This is not a builtin-sized seam like the rest of this track. TLS 1.3 plus X.509 certificate validation is a large, security-critical subsystem — the one place the runtime's hand-roll-everything habit (the sha256 precedent) should not be assumed to extend. That tension is the load-bearing fork below.
What it should deliver (scope to be refined)
- Outbound TLS client — a
.woprogram dials an HTTPS endpoint: a TLS handshake over the TCP socketnet.connect(language 38) provides, with server certificate validation against a trust store. jarvis's direct path, and language 38's deliberately-excluded HTTPS half. - Inbound TLS server — porch terminates TLS on its own listener (cert + key loaded at startup), retiring the "put a proxy in front" requirement for a single-binary deployment.
- Certificate validation and a trust store — X.509 chain verification, hostname/SNI checks outbound; certificate + private-key loading inbound. This is where most of the risk and most of the code live.
Forks the brainstorm must settle
- Implementation source — the load-bearing fork (left open by direction). Vendor a small, audited TLS library (mbedTLS or BearSSL) compiled into the single static binary — correct and maintainable, but a build-time external dependency, an explicit exception to the no-external-deps doctrine the runtime otherwise holds — versus hand-rolling a TLS 1.3 subset plus X.509 in C, which matches the sha256 precedent but is thousands of security-critical lines and a hand-rolled certificate validator is a CVE factory (strongly discouraged). The honest lean is vendor-a-lib; TLS is exactly the thing not to hand-roll. This fork decides whether the whole "single static binary, no external deps" story gains a footnote.
- Phasing. Outbound first (jarvis's actual need) with inbound to follow, or both together since the handshake machinery and the vendored library are shared and only the client-vs-server role and validation direction differ.
- Trust store and cert provisioning. Where the outbound trust anchors come from (the system CA bundle, and its path across distros), and how the inbound side is handed its certificate and key (files, env, a reload story).
- TLS version and cipher policy. TLS 1.3 only (simplest, modern, smallest attack surface) versus 1.2+1.3 (broader reach). Leaning 1.3-only.
Consumers
Named, so this is not a capability shipped as decoration:
- jarvis 1 — outbound HTTPS to the LLM API (the reason this story exists).
- porch — inbound TLS termination, retiring the mandatory front proxy for a single-binary deployment.
- language 38 — the outbound HTTPS half it excluded by doctrine; this story is where that exclusion is lifted.
Dependencies
- language 38
—
net.connect(outbound TCP) is the socket the outbound handshake runs over; the client half of this story sits directly on it.
Out of scope
- HTTP/2. A separate protocol concern, parked behind language iteration 23 regardless; TLS is its prerequisite, not its owner.
- Mutual TLS / client certificates. A later slice if a consumer asks; the first cut authenticates the server, not the client.
- Updating the doctrine documents. Retiring "TLS is the proxy's job" means correcting language 34, language 38 and porch when this lands — a follow-up bookkeeping pass, named here so it is not forgotten, not part of the runtime work.
Info
This is the heaviest iteration in the runtime-v2 track and the only one that forces a doctrine reversal and, most likely, an external-dependency exception — both flagged above rather than buried. It is pure I/O-plane work (a handshake layer over the existing socket verbs); no actors, so it is not exposed to the lang-41 hang. It gates jarvis entirely: until it lands, jarvis cannot reach a model at all.