diff --git a/src/components/ArchitectureDiagram.css b/src/components/ArchitectureDiagram.css index eeea10d..366eb85 100644 --- a/src/components/ArchitectureDiagram.css +++ b/src/components/ArchitectureDiagram.css @@ -71,19 +71,13 @@ .node:focus-visible { border-color: var(--accent); } -.node-layer { - font-family: var(--mono); - font-size: 10.5px; - letter-spacing: 0.12em; - color: var(--accent); - text-transform: uppercase; -} .node-title { font-family: var(--display); font-weight: 600; font-size: clamp(14px, 1.5vw, 17px); color: #fff; line-height: 1.1; + white-space: pre-line; } .node-sub { font-family: var(--mono); @@ -114,7 +108,7 @@ background: var(--bg-2); } .node-obs { - background: rgba(255, 255, 255, 0.014); + background: var(--surface); border-style: dashed; } diff --git a/src/components/ArchitectureDiagram.jsx b/src/components/ArchitectureDiagram.jsx index f795d50..a9fec67 100644 --- a/src/components/ArchitectureDiagram.jsx +++ b/src/components/ArchitectureDiagram.jsx @@ -41,10 +41,16 @@ function edgePath(e) { } // node → observability card if (e.route === "tap") { - const top = byId.obs.y; + const o = byId.obs; + const top = o.y; const [ax, ay] = a.bottom; - if (e.from === "reasoner") return `M 555 ${ay} C 467 300 467 452 525 ${top}`; - if (e.from === "safety") return `M ${ax} ${ay} C ${ax} 452 702 472 665 ${top}`; + // reasoner sits directly above obs with skills between — bow left around the skills box + if (e.from === "reasoner") { + const bow = byId.skills.x - 33; + return `M ${byId.reasoner.x + 55} ${ay} C ${bow} ${ay + 86} ${bow} ${top - 36} ${o.x + 25} ${top}`; + } + // safety taps in from the right, curving down past obs's right edge + if (e.from === "safety") return `M ${ax} ${ay} C ${ax} ${ay + 118} ${o.x + o.w + 12} ${top - 16} ${o.x + o.w - 25} ${top}`; return `M ${ax} ${ay} C ${ax} ${ay + 28} ${ax} ${top - 28} ${ax} ${top}`; // skills } // vertically stacked (same column) @@ -76,7 +82,7 @@ export default function ArchitectureDiagram() { One typed contract, two coupled systems.

- A slow S2 reasoner plans in typed tool-calls; a fast S1 rSkill layer + A slow reasoner plans in typed tool-calls; a fast rSkill layer executes action chunks. Perception lifts detections into spatial memory; both feed the reasoner and the rSkills, and a deny-by-default supervisor gates every command before it reaches the robot — whose new state flows straight back into perception and the next decision. @@ -124,7 +130,6 @@ export default function ArchitectureDiagram() { onBlur={() => setHovered(null)} tabIndex={0} > - {n.layer} {n.title} {n.sub} diff --git a/src/data/layers.js b/src/data/layers.js index 1df3c1e..2c841b5 100644 --- a/src/data/layers.js +++ b/src/data/layers.js @@ -1,22 +1,25 @@ // Architecture-diagram nodes + edges — a closed control loop. -// Coordinates are in the SVG viewBox space (0 0 1120 620). +// Coordinates are in the SVG viewBox space (0 0 1120 648). // Forward flow reads left→right; the loop closes via two feedback paths // (robot → world state over the top, robot → sensors along the bottom). export const NODES = [ - { id: "sensors", x: 36, y: 230, w: 152, h: 104, group: "io", layer: "L0–L1", title: "Sensors + HAL", sub: "RGB-D · lidar · tactile" }, - { id: "world", x: 250, y: 118, w: 184, h: 96, group: "io", layer: "L1–L2", title: "World State", sub: "tf2 · 30 Hz · detections" }, - { id: "memory", x: 250, y: 330, w: 184, h: 96, group: "io", layer: "L2", title: "Spatial Memory", sub: "advisory scene graph" }, - { id: "reasoner", x: 500, y: 118, w: 190, h: 96, group: "s2", layer: "L4", title: "S2 · Reasoner", sub: "LLM planner · tool-calls" }, - { id: "skills", x: 500, y: 330, w: 190, h: 96, group: "s1", layer: "L3", title: "S1 · rSkill", sub: "VLA policy · 30–200 Hz" }, - { id: "safety", x: 756, y: 230, w: 150, h: 104, group: "safety", layer: "L6", title: "Safety", sub: "C++ · deny-by-default" }, - { id: "robot", x: 968, y: 230, w: 116, h: 104, group: "robot", layer: "act", title: "Robot", sub: "real · sim" }, - { id: "obs", x: 500, y: 488, w: 190, h: 84, group: "obs", layer: "L7", title: "Observability", sub: "OTel · Foxglove" }, + { id: "sensors", x: 36, y: 230, w: 120, h: 104, group: "io", title: "Sensors", sub: "RGB-D · lidar · tactile" }, + { id: "perception", x: 194, y: 118, w: 132, h: 96, group: "io", title: "Perception AI", sub: "detections → spatial" }, + { id: "world", x: 364, y: 118, w: 132, h: 96, group: "io", title: "World State", sub: "tf2 · 30 Hz · detections" }, + { id: "memory", x: 364, y: 330, w: 132, h: 96, group: "io", title: "Spatial Memory", sub: "advisory scene graph" }, + { id: "reasoner", x: 534, y: 118, w: 190, h: 96, group: "s2", title: "Reasoner", sub: "LLM planner · tool-calls" }, + { id: "skills", x: 534, y: 330, w: 190, h: 96, group: "s1", title: "rSkills\n(robot skills)", sub: "VLA · VLM · reward · ROS" }, + { id: "safety", x: 762, y: 230, w: 150, h: 104, group: "safety", title: "Safety", sub: "C++ · deny-by-default" }, + { id: "robot", x: 950, y: 230, w: 134, h: 104, group: "robot", title: "Robot", sub: "Edge · Fleet · Cloud · Sim" }, + { id: "obs", x: 534, y: 488, w: 190, h: 96, group: "obs", title: "Observability\nTraceability", sub: "OTel · Foxglove" }, ]; export const EDGES = [ // forward path - { from: "sensors", to: "world" }, + { from: "sensors", to: "perception" }, + { from: "perception", to: "world" }, + { from: "perception", to: "memory" }, { from: "world", to: "memory" }, { from: "world", to: "reasoner" }, { from: "world", to: "skills" },