Guided Portfolio Conversation — Architecture
Browser, Worker, model, and operational state boundaries for the portfolio guide.
README · ARCHITECTURE · TECHNICAL · source
Three state planes
BROWSER WORKER + MODEL D1 / KV
full active turns ────────▶ validate bounded context event metadata
rolling summary retrieve public evidence shared rate limits
six recent turns ◀──────── stream answer + new summary no raw conversation
conversation epoch provider requests: store=false
The browser owns the complete active conversation and the epoch used to invalidate late work. The Worker receives transient bounded context, applies authentication and privacy boundaries, and retrieves evidence independently. D1 and KV support operations, not conversational recall.
Request path
- The browser sends the current question, a summary capped at 2,000 characters, and at most six recent turns.
- The Worker validates roles, per-turn length, and a 6,000-character combined context limit.
- Retrieval searches visible documents plus server-only notes derived from public material.
- The model streams an answer with provider storage disabled.
- After a complete answer, a small second call produces the next rolling summary.
- The browser records the completed exchange and displays an active-context indicator.
Visitor history is explicitly serialized as untrusted continuity. It can help resolve a pronoun; it cannot establish a fact, change the system policy, or become a citation.
Clearing and cancellation
clear aborts the current request and increments the conversation epoch. A completion is accepted only when its captured request epoch still matches the current epoch. This handles the race where cancellation and an already-buffered completion cross paths.
Export paths
export transcriptbuilds Markdown locally from structured turns.export summarysends a bounded conversation to a protected Worker route. The route generates plain text, escapes every dynamic field into a fixed HTML template, allowlists portfolio links, and returns a no-store attachment.
Summary export accepts at most 40 turns and 40,000 characters. The limit bounds cost and parsing work; a longer browser conversation can still exist.
Related systems
| Guided portfolio conversation | Water Cooler |
|---|---|
| One visitor's active context | Shared live room |
| Browser owns complete turns | Durable Object owns coordination |
| HTTP streaming | WebSocket fanout |
| Attractor-inspired context | Separate multi-participant subsystem |
The guide applies an idea I am also exploring in Attractor — Adaptive Context and Personalization: useful context can be a small, changing representation of what matters rather than an unlimited transcript copied into every request. It does not run the Attractor implementation; it uses that design principle for one active visitor conversation.
That single-visitor boundary is also why browser-held state is enough here. The Water Cooler coordinates multiple live participants in a shared room, so its Durable Object and WebSockets solve a different ownership and fanout problem. I choose the state mechanism based on the coordination problem rather than giving every feature the same infrastructure.