diff --git a/docs/00-dependency-graph.md b/docs/00-dependency-graph.md index 44bcfea..9bf4aff 100644 --- a/docs/00-dependency-graph.md +++ b/docs/00-dependency-graph.md @@ -342,7 +342,7 @@ flowchart LR classDef gap fill:#cf222e,color:#fff,stroke:none L29["language 29 @derive (⏸ hold)"]:::held - L38["language 38 net.connect (refine)"]:::refine + L38["language 38 net.connect ✅ landed (id 110); proxy middleware now buildable"]:::done L43["runtime-v2 8 symmetric cipher (refine, NEW 2026-09-06)"]:::refine L30["runtime-v2 7 observability (refine, moved from language 30, 2026-09-06)"]:::refine L18["language 18 TTL cache + transaction{} (⏸ hold)"]:::held @@ -423,6 +423,62 @@ the alacritty Wayland stage reuses GFDPASS + GVTE; the zen CDP driver now lacks only a WebSocket client; skillhost (28) has its stdin transport. +## 7. jarvis — the AI-assistant track and everything it waits on + +The sixth track ([jarvis](stories/jarvis/00-story.md)): an AI assistant built in +writeonce. Only **jarvis 1** (the chat loop) is close to startable; it sits on +two chains — the **outbound HTTPS path** (the real blocker, mostly runtime-v2 9's +TLS ladder) and the **framework path** (porch, all `ready`). Phase-level, because +the TLS ladder is where the waiting actually happens. + +```mermaid +flowchart TD + classDef done fill:#1a7f37,color:#fff,stroke:none + classDef ready fill:#0969da,color:#fff,stroke:none + classDef refine fill:#eac54f,color:#000,stroke:none + classDef held fill:#6e7781,color:#fff,stroke:none + + NC["net.connect (id 110) ✅"]:::done + A["rv2 9 A — AEAD ✅ (= rv2 8 A–C: ChaCha20-Poly1305 + AES-GCM)"]:::done + B["rv2 9 B — HKDF ✅"]:::done + C["rv2 9 C — X25519 ✅"]:::done + D["rv2 9 D — signatures: RSA-PSS/PKCS1 + ECDSA-P256"]:::refine + E["rv2 9 E — ASN.1/DER + X.509 chain + trust store"]:::refine + F["rv2 9 F — record layer + handshake FSM (client), net.connect_tls"]:::refine + G["rv2 9 G — inbound server (porch TLS termination)"]:::refine + + P2["porch 2 randomness+cookies (ready)"]:::ready + P3["porch 3 sessions (ready)"]:::ready + P6["porch 6 streaming (ready)"]:::ready + P7["porch 7 SSE (ready)"]:::ready + WOHTML["wo-html / writeonce-view ✅"]:::done + + J1["jarvis 1 — the chat loop (unwritten)"]:::refine + J2["jarvis 2 — tool use / agent loop"]:::refine + J3["jarvis 3 — retrieval (RAG) + embeddings/vector sub-gap"]:::refine + + NC --> F + A --> F + B --> F + C --> D + D --> E + E --> F + F --> J1 + P2 --> P3 + P6 --> P7 + P2 --> J1 + P3 --> J1 + P7 --> J1 + WOHTML --> J1 + J1 --> J2 + J1 --> J3 +``` + +The outbound path is the critical one: **A/B/C landed, D→E→F remain** (G is +inbound, not needed for jarvis dialling out). The framework path (porch 2/3/6/7) +is entirely `ready` and unblocked — buildable in parallel with the TLS ladder. +jarvis 1 itself is not yet written; jarvis 2/3 follow it. + ## Maintenance rule When an iteration or slice lands, update its node's class here in the diff --git a/docs/stories/jarvis/00-story.md b/docs/stories/jarvis/00-story.md index 0f69819..99a3130 100644 --- a/docs/stories/jarvis/00-story.md +++ b/docs/stories/jarvis/00-story.md @@ -24,16 +24,18 @@ therefore does not begin until two things exist. The design chosen is **direct outbound HTTPS** — jarvis dials the LLM API itself, keeping the pure single-binary story. That gates the whole track on -language work: +runtime work, now **partly built**: -- **`net.connect`** — outbound TCP — - [language 38](../language-runtime-database/38-content-platform-capabilities.md), - written but not yet built. -- **An outbound TLS client** — HTTPS over that socket — now owned by - runtime-v2 [9](../runtime-v2/09-in-process-tls.md) (in-process TLS), created - 2026-09-07 from this gap. It **retires the standing "TLS is the proxy's job" - doctrine**, giving the runtime TLS both directions — the load-bearing choice - jarvis's direct-HTTPS design forced into the open. +- **`net.connect`** — outbound TCP — ✅ **landed 2026-09-07** (`wob.h` id 110, + `getaddrinfo` DNS + blocking connect; the outbound half language 38 named). +- **An outbound TLS client** — HTTPS over that socket — owned by + runtime-v2 [9](../runtime-v2/09-in-process-tls.md) (in-process TLS), which + **retires the standing "TLS is the proxy's job" doctrine**. In progress: its + crypto foundations are landed and vector-gated — **A AEAD** (ChaCha20-Poly1305 + + AES-GCM, runtime-v2 [8](../runtime-v2/08-symmetric-cipher.md) A–C), + **B HKDF**, **C X25519** — and the remaining rungs (**D** signatures + RSA/X.509, + **E** ASN.1/X.509 chain, **F** record layer + handshake FSM, **G** server) are + what jarvis still waits on. A **local-gateway alternative was considered and set aside**: jarvis could speak to a small companion process over a unix socket (`net.connect_unix`, id 107) or @@ -44,7 +46,7 @@ owns its own connection rather than shipping a second executable. ## Architecture - browser ⇄ jarvis (a porch app) ⇄ [blocked seam: net.connect + TLS] ⇄ LLM API + browser ⇄ jarvis (a porch app) ⇄ net.connect ✅ + TLS (rv2 9, in progress) ⇄ LLM API Requests arrive at a porch web app; the answer streams the other way, token by token, LLM → jarvis → browser, over porch's SSE. Conversation state is durable @@ -85,10 +87,10 @@ Consumed, and already `ready` or shipped: Blockers, which must land before iteration 1 starts: -| Blocker | Owner | -| --- | --- | -| outbound TCP (`net.connect`) | language [38](../language-runtime-database/38-content-platform-capabilities.md) | -| outbound TLS client | runtime-v2 [9](../runtime-v2/09-in-process-tls.md) — in-process TLS, created 2026-09-07 from this gap; **retires the proxy-termination doctrine** | +| Blocker | Owner | State | +| --- | --- | --- | +| outbound TCP (`net.connect`) | language [38](../language-runtime-database/38-content-platform-capabilities.md) | ✅ **landed 2026-09-07** (`wob.h` id 110) | +| outbound TLS client | runtime-v2 [9](../runtime-v2/09-in-process-tls.md) — in-process TLS; **retires the proxy-termination doctrine** | 🔄 in progress — A AEAD ✅, B HKDF ✅, C X25519 ✅; **D–G remain** | ## What this track does NOT own