// BUILDER VIEW — for developers studying the design pattern const { useState } = React; const LAYERS = [ { id: "interfaces", label: "interfaces/", sub: "Discord · API · Web", color: "#38d4c8", bg: "rgba(56,212,200,0.06)", desc: "Adapter layer. Swappable without touching core/ or agents/. Discord today, REST API in the fork.", files: ["discord/bot.py", "discord/commands.py", "discord/voice.py"], forkable: false, }, { id: "agents", label: "agents/", sub: "Orchestrator · Specialists", color: "#e8a84c", bg: "rgba(232,168,76,0.06)", desc: "Implementation-specific personas and domain logic. Entirely replaced in a fork. No framework code lives here.", files: ["orchestrator.py", "specialist_a.py", "specialist_b.py"], forkable: false, }, { id: "core", label: "core/", sub: "Orchestrator · ABAC · Memory", color: "#9d7ee8", bg: "rgba(157,126,232,0.08)", desc: "Context-agnostic. No personas, no domain logic. This is what gets forked for professional deployments.", files: ["graph/client.py", "graph/abac.py", "orchestrator/base.py", "orchestrator/memory.py", "specialists/base.py"], forkable: true, }, { id: "services", label: "services/", sub: "Write Worker · Auditor · Cataloger", color: "#9d7ee8", bg: "rgba(157,126,232,0.05)", desc: "Stateless, horizontally scalable workers. Domain-agnostic chunking and embedding. The write worker cluster is universal across all deployments.", files: ["cara/main.py", "cara/chunker.py", "cara/embedder.py", "cara/writer.py"], forkable: true, }, { id: "graph", label: "FalkorDB", sub: "Graph + Vector · OpenCypher", color: "#9d7ee8", bg: "rgba(157,126,232,0.04)", desc: "Graph storage with native vector search. 384-dim embeddings. Relationships are first-class primitives.", files: ["schema: Chunk · Context · Topic · Entity · Insight"], forkable: true, }, ]; const DECISIONS = [ { q: "Why graph over vector DB?", color: "#9d7ee8", a: "Relationships matter. A vector DB finds similar chunks; a graph knows who said what, when, in what context, across sessions. Memory is relational — retrieval needs to traverse those relationships, not just rank by similarity.", }, { q: "Why append-only writes?", color: "#38d4c8", a: "Trust requires auditability. Modifying records destroys the provenance chain. Corrections are new nodes that supersede old ones — linked, not overwritten. The historical record is always intact.", }, { q: "Why fire-and-forget for the write worker?", color: "#e8a84c", a: "Memory consolidation must never slow a conversation. The orchestrator fires the write worker payload after the response is sent. If the write worker is down, the conversation continues unaffected. Memory is important — but never in the critical path.", }, { q: "Why structural ABAC?", color: "#9d7ee8", a: "Policy engines can be misconfigured. Graph topology cannot. A chunk tagged only to `personal` context has no traversal path from a `trade` query origin — not by rule enforced at runtime, but by the shape of the data itself.", }, { q: "Why human adjudication at limits?", color: "#38d4c8", a: "The system is honest about where its competence ends. When the Validator cannot resolve a classification edge case, it creates a structured escalation record and suspends automated action. Human judgment is the accountability mechanism.", }, { q: "Why one-step-behind cataloger?", color: "#e8a84c", a: "The cataloger processes the previous exchange's data, never the current one. It is always one step behind by design. Speed and safety are maintained structurally — discipline cannot guarantee what architecture can.", }, ]; const PATTERNS = [ { label: "Append-only", color: "#38d4c8", icon: "→+", desc: "All writes additive. Tombstones retire, never delete. Corrections supersede." }, { label: "Structural ABAC", color: "#9d7ee8", icon: "⬡", desc: "Topology enforces access. No traversal path = no access." }, { label: "Fire & Forget", color: "#e8a84c", icon: "⤳", desc: "Memory writes are async. Response path is never blocked." }, { label: "Stateless Workers", color: "#38d4c8", icon: "≡", desc: "Any write worker instance handles any request. Horizontal scale." }, { label: "Human Ceiling", color: "#e8a84c", icon: "△", desc: "Edge cases escalate to human review. Automation knows its limits." }, ]; function LayerStack({ activeLayer, setActiveLayer }) { return (
{/* Fork annotation */}
REPLACE ON FORK
{/* Replaceable layers */} {LAYERS.filter(l => !l.forkable).map((layer, i) => ( setActiveLayer(activeLayer === layer.id ? null : layer.id)} isLast={i === 1}/> ))} {/* Fork line */}
FORK BOUNDARY
{/* Forkable layers */}
KEEP UNTOUCHED
{LAYERS.filter(l => l.forkable).map((layer) => ( setActiveLayer(activeLayer === layer.id ? null : layer.id)}/> ))}
); } function LayerRow({ layer, active, onClick }) { return (
{ if (!active) e.currentTarget.style.borderColor = layer.color + "30"; }} onMouseLeave={e => { if (!active) e.currentTarget.style.borderColor = "var(--border)"; }} >
{layer.label} {layer.sub}
{active && (

{layer.desc}

{layer.files.map(f => ( {f} ))}
)}
); } function DataFlowDiagram() { const steps = [ { label: "EXCHANGE", sub: "user message + agent response", color: "#38d4c8", side: "left" }, { label: "ORCHESTRATOR", sub: "fire-and-forget → write worker", color: "#e8a84c", side: "right", async: true }, { label: "WRITE WORKER", sub: "decompose · tag · embed", color: "#38d4c8", side: "right" }, { label: "CHUNK NODES", sub: "written with context + topic + entity edges", color: "#9d7ee8", side: "right" }, { label: "FALKORDB", sub: "permanent graph write · 384-dim vector stored", color: "#9d7ee8", side: "right" }, ]; return (
{steps.map((s, i) => (
{s.side === "left" ? (
{s.label}
{s.sub}
) :
}
{i === 0 ? (
) : null} {i > 0 &&
} {i > 0 &&
} {i < steps.length - 1 &&
}
{s.side === "right" ? (
{s.async && ( async )}
{s.label}
{s.sub}
) :
}
))}
); } function BuilderView() { const [activeLayer, setActiveLayer] = useState("core"); const [openDecision, setOpenDecision] = useState(null); return (
{/* Header */}

Design Pattern

A forkable framework with a
context-agnostic core.

The architecture separates what changes per deployment from what never changes. Fork the implementation. Keep the framework.

{/* Main two-column layout */}
{/* Left: Layer Stack */}
Layer Separation — click to expand
{/* Right: Data Flow */}
Memory Write Path
{/* Key patterns */}
Core Patterns
{PATTERNS.map(p => (
{p.icon}
{p.label}
{p.desc}
))}
{/* Design Decisions */}
Design Decisions — click to read rationale
{DECISIONS.map((d, i) => (
setOpenDecision(openDecision === i ? null : i)} style={{ background: openDecision === i ? "var(--surface2)" : "var(--surface)", border: `1px solid ${openDecision === i ? d.color + "50" : "var(--border)"}`, borderRadius: 7, padding: "14px 16px", cursor: "pointer", transition: "all 0.2s", }} onMouseEnter={e => { if (openDecision !== i) e.currentTarget.style.borderColor = d.color + "30"; }} onMouseLeave={e => { if (openDecision !== i) e.currentTarget.style.borderColor = "var(--border)"; }} >
{d.q}
{openDecision === i && (
{d.a}
)}
))}
); } window.BuilderView = BuilderView;