[
  {
    "id": "01-system-context",
    "title": "Multimodal RAG Platform — System Context",
    "layout": "context",
    "canvas": { "width": 1500 },
    "colWidth": 250,
    "system": { "label": "Multimodal RAG Platform", "sub": "Ask across every modality" },
    "groups": [
      { "side": "left", "title": "People", "nodes": [
        { "id": "worker", "label": "Knowledge Worker", "kind": "actor", "rel": "asks questions", "dir": "in" },
        { "id": "curator", "label": "Content Curator", "kind": "actor", "rel": "uploads, corrects", "dir": "in" },
        { "id": "admin", "label": "Platform Admin", "kind": "actor", "rel": "tenants, policy", "dir": "in" }
      ] },
      { "side": "top", "title": "Content sources", "nodes": [
        { "id": "sp", "label": "SharePoint / Drive", "kind": "external", "rel": "delta crawl", "dir": "in", "kind2": "batch" },
        { "id": "wiki", "label": "Confluence / Wiki", "kind": "external", "rel": "page sync", "dir": "in", "kind2": "batch" },
        { "id": "lake", "label": "Object Store Drop", "kind": "external", "rel": "on upload", "dir": "in", "kind2": "async" },
        { "id": "media", "label": "Media Archive", "kind": "external", "rel": "audio, video", "dir": "in", "kind2": "batch" }
      ] },
      { "side": "right", "title": "AI model services", "nodes": [
        { "id": "claude", "label": "Claude API", "kind": "external", "rel": "generation, vision" },
        { "id": "embed", "label": "Embedding Service", "kind": "external", "rel": "text + image vectors" },
        { "id": "asr", "label": "Speech-to-Text", "kind": "external", "rel": "transcription", "kind2": "async" }
      ] },
      { "side": "bottom", "title": "Enterprise services", "nodes": [
        { "id": "idp", "label": "Identity Provider", "kind": "external", "rel": "OIDC / SSO", "dir": "in" },
        { "id": "siem", "label": "SIEM", "kind": "external", "rel": "audit events", "kind2": "async" },
        { "id": "downstream", "label": "Enterprise Search", "kind": "external", "rel": "answer API" }
      ] }
    ],
    "meta": { "v": "1.0", "owner": "Solution Architecture", "date": "2026-08" }
  },

  {
    "id": "02-high-level-architecture",
    "title": "High-Level Architecture",
    "layout": "flow",
    "canvas": { "width": 1560 },
    "chain": true,
    "stages": [
      { "title": "Ingest", "nodes": [
        { "id": "intake", "label": "Intake & Connectors", "sub": "upload + scheduled pull" },
        { "id": "raw", "label": "Raw Content Store", "kind": "store", "sub": "immutable, versioned" }
      ] },
      { "title": "Understand", "nodes": [
        { "id": "layout", "label": "Layout & OCR", "sub": "PDF, scans, Office" },
        { "id": "sense", "label": "Vision & Media", "sub": "VLM captions, ASR" }
      ] },
      { "title": "Index", "nodes": [
        { "id": "chunk", "label": "Chunk & Enrich", "sub": "contextual headers" },
        { "id": "write", "label": "Embed & Write", "sub": "dense + sparse + SQL" }
      ] },
      { "title": "Retrieve", "nodes": [
        { "id": "search", "label": "Hybrid Search", "sub": "vector, BM25, text-to-SQL" },
        { "id": "rerank", "label": "Fuse & Rerank", "sub": "RRF + cross-encoder" }
      ] },
      { "title": "Generate", "nodes": [
        { "id": "answer", "label": "Answer Synthesis", "sub": "Claude Opus 5" },
        { "id": "gate", "label": "Grounding Gate", "kind": "decision", "sub": "claim to span" }
      ] },
      { "title": "Serve", "nodes": [
        { "id": "ui", "label": "Answer + Citations", "sub": "page, bbox, timecode" },
        { "id": "fb", "label": "Feedback Capture", "sub": "into eval set" }
      ] }
    ],
    "edges": [
      { "from": "gate", "to": "search", "label": "weak evidence, retry once", "kind": "error" },
      { "from": "fb", "to": "chunk", "label": "curation signal", "kind": "async" }
    ],
    "meta": { "v": "1.0", "owner": "Solution Architecture" }
  },

  {
    "id": "03-layered-architecture",
    "title": "Layered Architecture",
    "layout": "bands",
    "canvas": { "width": 1500 },
    "layerHeaderWidth": 160,
    "bands": [
      { "name": "Experience", "nodes": [
        { "id": "web", "label": "Web App", "sub": "React + TypeScript" },
        { "label": "Chat & Upload" },
        { "label": "Source Viewer", "sub": "page / frame highlight" },
        { "label": "Admin Console" }
      ] },
      { "name": "API", "nodes": [
        { "id": "gw", "label": "API Gateway", "kind": "integration", "sub": "OIDC, quota" },
        { "id": "qapi", "label": "Query API", "sub": "FastAPI, SSE" },
        { "label": "Ingestion API" },
        { "label": "Admin API" }
      ] },
      { "name": "Orchestration", "nodes": [
        { "id": "orch", "label": "Query Orchestrator", "sub": "plan, retrieve, answer" },
        { "label": "Ingestion Workflows", "sub": "Temporal, durable" },
        { "id": "mgw", "label": "Model Gateway", "kind": "integration", "sub": "route, cache, cap" }
      ] },
      { "name": "AI services", "nodes": [
        { "label": "Layout & OCR" },
        { "label": "Vision Captioning" },
        { "label": "Transcription" },
        { "id": "emb", "label": "Embedding", "sub": "text + image" },
        { "label": "Reranker" },
        { "label": "Guardrails" }
      ] },
      { "name": "Data", "nodes": [
        { "id": "vec", "label": "Vector Index", "kind": "store" },
        { "label": "Lexical Index", "kind": "store" },
        { "label": "Analytical Tables", "kind": "store" },
        { "label": "Object Store", "kind": "store" },
        { "label": "Metadata DB", "kind": "store" }
      ] },
      { "name": "Platform", "nodes": [
        { "id": "iam", "label": "Identity & Policy", "kind": "security" },
        { "label": "Secrets & KMS", "kind": "security" },
        { "label": "Observability", "kind": "security" },
        { "label": "Audit & Lineage", "kind": "security" }
      ] }
    ],
    "edges": [
      { "from": "web", "to": "gw", "label": "HTTPS" },
      { "from": "qapi", "to": "orch", "label": "in-process" },
      { "from": "orch", "to": "emb", "label": "gRPC" },
      { "from": "emb", "to": "vec", "label": "search / upsert" }
    ],
    "note": "Dependencies point downward only. No layer calls the layer above it.",
    "meta": { "v": "1.0", "owner": "Solution Architecture" }
  },

  {
    "id": "04-container-architecture",
    "title": "Container Architecture (C4 Level 2)",
    "layout": "nested",
    "canvas": { "width": 1560 },
    "boxes": [
      { "title": "Kubernetes cluster — application namespace", "kind": "cloud", "dir": "col", "children": [
        { "title": "Edge & API", "kind": "boundary", "nodes": [
          { "id": "gw", "label": "API Gateway", "kind": "integration", "sub": "Envoy, OIDC" },
          { "id": "qapi", "label": "Query API", "sub": "FastAPI, 3 replicas" },
          { "id": "iapi", "label": "Ingestion API", "sub": "FastAPI, presigned PUT" },
          { "id": "aapi", "label": "Admin API", "sub": "tenants, policy" }
        ] },
        { "title": "Ingestion workers — autoscaled by queue depth", "kind": "boundary", "nodes": [
          { "id": "pw", "label": "Parse Worker", "sub": "layout, OCR" },
          { "id": "vw", "label": "Vision Worker", "sub": "VLM caption, GPU" },
          { "id": "mw", "label": "Media Worker", "sub": "ASR, keyframes" },
          { "id": "iw", "label": "Index Worker", "sub": "chunk, embed, write" }
        ] },
        { "title": "Retrieval & generation — synchronous path", "kind": "boundary", "nodes": [
          { "id": "orch", "label": "Query Orchestrator", "sub": "plan and assemble" },
          { "id": "ret", "label": "Retriever", "sub": "hybrid fan-out" },
          { "id": "rr", "label": "Reranker", "sub": "cross-encoder, GPU" },
          { "id": "mgw", "label": "Model Gateway", "kind": "integration", "sub": "route, cache, budget" }
        ] }
      ] },
      { "title": "Managed data services", "kind": "cloud", "nodes": [
        { "id": "vec", "label": "Vector Index", "kind": "store", "sub": "HNSW, per-tenant" },
        { "id": "lex", "label": "Lexical Index", "kind": "store", "sub": "BM25" },
        { "id": "tab", "label": "Analytical Tables", "kind": "store", "sub": "Parquet + SQL" },
        { "id": "obj", "label": "Object Store", "kind": "store", "sub": "raw + derived" },
        { "id": "meta", "label": "Metadata DB", "kind": "store", "sub": "PostgreSQL" },
        { "id": "bus", "label": "Work Queue", "kind": "queue", "sub": "per-stage topics" }
      ] }
    ],
    "outside": [
      { "id": "claude", "label": "Claude API", "kind": "external", "sub": "generation + vision" },
      { "id": "embapi", "label": "Embedding API", "kind": "external" },
      { "id": "asr", "label": "Speech-to-Text", "kind": "external" },
      { "id": "idp", "label": "Identity Provider", "kind": "external", "sub": "OIDC" }
    ],
    "edges": [
      { "from": "gw", "to": "qapi", "label": "HTTP/2" },
      { "from": "qapi", "to": "orch", "label": "gRPC" },
      { "from": "orch", "to": "ret", "label": "search" },
      { "from": "ret", "to": "vec", "label": "top-k ANN" },
      { "from": "ret", "to": "lex", "label": "BM25" },
      { "from": "ret", "to": "tab", "label": "SQL" },
      { "from": "orch", "to": "mgw", "label": "assemble" },
      { "from": "mgw", "to": "claude", "label": "citations on" },
      { "from": "iapi", "to": "bus", "label": "enqueue", "kind": "async" }
    ],
    "note": "Synchronous query path shown. Workers lease from the queue and write the indexes — that path is view 05.",
    "meta": { "v": "1.0", "owner": "Solution Architecture" }
  },

  {
    "id": "05-multimodal-ingestion-pipeline",
    "title": "Multimodal Ingestion Pipeline — One Lane per Modality",
    "layout": "swimlane",
    "canvas": { "width": 1640 },
    "laneHeaderWidth": 150,
    "stages": ["Intake", "Extract", "Interpret", "Chunk & enrich", "Index"],
    "lanes": [
      { "title": "Text & Markdown", "cells": [
        [ { "label": "Upload / crawl" } ],
        [ { "label": "Normalise encoding" } ],
        [ { "label": "Heading structure" } ],
        [ { "label": "Semantic chunks", "sub": "512 tok, 15% lap" } ],
        [ { "label": "Dense + sparse", "kind": "store" } ]
      ] },
      { "title": "PDF & Office", "cells": [
        [ { "label": "Upload / connector" } ],
        [ { "label": "Layout parse", "sub": "reading order" } ],
        [ { "label": "OCR fallback", "sub": "scanned pages" } ],
        [ { "label": "Page-anchored chunks" } ],
        [ { "label": "Dense + sparse", "kind": "store" } ]
      ] },
      { "title": "Images & charts", "cells": [
        [ { "label": "Standalone or embedded" } ],
        [ { "label": "Region crop", "sub": "bbox retained" } ],
        [ { "label": "VLM description", "sub": "Claude vision" } ],
        [ { "label": "Caption + OCR text" } ],
        [ { "label": "Text + image vector", "kind": "store" } ]
      ] },
      { "title": "Tables & sheets", "cells": [
        [ { "label": "Upload / extracted" } ],
        [ { "label": "Table detect", "sub": "cell structure" } ],
        [ { "label": "Header + type infer" } ],
        [ { "label": "Markdown linearise" } ],
        [ { "label": "Vector + typed rows", "kind": "store" } ]
      ] },
      { "title": "Audio & video", "cells": [
        [ { "label": "Upload / archive pull" } ],
        [ { "label": "Demux + keyframes" } ],
        [ { "label": "ASR + diarisation", "sub": "word timings" } ],
        [ { "label": "Timecoded windows" } ],
        [ { "label": "Vector + frame refs", "kind": "store" } ]
      ] }
    ],
    "note": "Every lane emits the same chunk record: text projection, provenance, modality tag.",
    "meta": { "v": "1.0", "owner": "Solution Architecture" }
  },

  {
    "id": "06-indexing-embedding-pipeline",
    "title": "Indexing & Embedding Pipeline",
    "layout": "flow",
    "canvas": { "width": 1520 },
    "chain": true,
    "stages": [
      { "title": "Intake", "nodes": [
        { "id": "cq", "label": "Chunk Queue", "kind": "queue", "sub": "at-least-once" },
        { "id": "dedup", "label": "Dedup & Hash", "sub": "content sha256" }
      ] },
      { "title": "Enrich", "nodes": [
        { "id": "ctx", "label": "Context Header", "sub": "Claude Haiku 4.5" },
        { "id": "pii", "label": "PII Redaction", "kind": "security", "sub": "policy driven" },
        { "id": "tag", "label": "Metadata Tagging", "sub": "ACL, source, date" }
      ] },
      { "title": "Embed", "nodes": [
        { "id": "temb", "label": "Text Embedding", "sub": "1024-d, batched" },
        { "id": "iemb", "label": "Image Embedding", "sub": "joint image-text" },
        { "id": "sparse", "label": "Sparse Terms", "sub": "BM25 analysis" }
      ] },
      { "title": "Write", "nodes": [
        { "id": "vec", "label": "Vector Index", "kind": "store", "sub": "tenant namespace" },
        { "id": "lex", "label": "Lexical Index", "kind": "store" },
        { "id": "tab", "label": "Analytical Tables", "kind": "store", "sub": "typed rows" }
      ] },
      { "title": "Verify", "nodes": [
        { "id": "probe", "label": "Recall Probe", "kind": "decision", "sub": "canary queries" },
        { "id": "cat", "label": "Catalog & Lineage", "sub": "version pinned" }
      ] }
    ],
    "edges": [
      { "from": "probe", "to": "ctx", "label": "below threshold, reindex", "kind": "error" }
    ],
    "note": "Enrichment runs on the Batch API where latency allows, at half the per-token cost.",
    "meta": { "v": "1.0", "owner": "Solution Architecture" }
  },

  {
    "id": "07-retrieval-generation-flow",
    "title": "Retrieval & Generation Flow",
    "layout": "flow",
    "canvas": { "width": 1600 },
    "chain": true,
    "stages": [
      { "title": "Admit", "nodes": [
        { "id": "q", "label": "User Question", "kind": "actor" },
        { "id": "guard", "label": "Input Guard", "kind": "security", "sub": "injection, PII" }
      ] },
      { "title": "Plan", "nodes": [
        { "id": "rw", "label": "Query Rewrite", "sub": "history-aware" },
        { "id": "route", "label": "Route", "kind": "decision", "sub": "modality + tool" }
      ] },
      { "title": "Search", "nodes": [
        { "id": "dense", "label": "Dense Search", "sub": "top 50" },
        { "id": "bm25", "label": "Lexical Search", "sub": "top 50, exact IDs" },
        { "id": "sql", "label": "Text-to-SQL", "sub": "aggregation over tables" }
      ] },
      { "title": "Fuse", "nodes": [
        { "id": "rrf", "label": "RRF Fusion", "sub": "rank-based merge" },
        { "id": "rr", "label": "Cross-Encoder Rerank", "sub": "top 8" },
        { "id": "parent", "label": "Parent Expansion", "sub": "small to big" }
      ] },
      { "title": "Generate", "nodes": [
        { "id": "asm", "label": "Context Assembly", "sub": "cached prefix" },
        { "id": "llm", "label": "Claude Opus 5", "kind": "external", "sub": "citations enabled" }
      ] },
      { "title": "Verify", "nodes": [
        { "id": "gate", "label": "Grounding Gate", "kind": "decision", "sub": "every claim cited" },
        { "id": "out", "label": "Answer + Citations", "sub": "page, bbox, timecode" }
      ] }
    ],
    "edges": [
      { "from": "gate", "to": "rw", "label": "unsupported claim, one retry", "kind": "error" },
      { "from": "route", "to": "sql", "label": "numeric question" }
    ],
    "note": "Abstain is a valid terminal state: no supporting span means no answer.",
    "meta": { "v": "1.0", "owner": "Solution Architecture" }
  },

  {
    "id": "08-data-architecture",
    "title": "Data Architecture — Zones and Ownership",
    "layout": "nested",
    "canvas": { "width": 1500 },
    "boxes": [
      { "title": "Knowledge data platform", "kind": "cloud", "dir": "col", "children": [
        { "title": "Raw zone — immutable, system of record", "kind": "boundary", "nodes": [
          { "id": "orig", "label": "Original Files", "kind": "store", "sub": "byte-identical" },
          { "id": "man", "label": "Ingest Manifest", "kind": "store", "sub": "checksum, ACL, source" },
          { "id": "leg", "label": "Legal Hold Set", "kind": "store", "sub": "retention locked" }
        ] },
        { "title": "Derived zone — reproducible, disposable", "kind": "boundary", "nodes": [
          { "id": "parsed", "label": "Parsed Documents", "kind": "store", "sub": "layout JSON" },
          { "id": "assets", "label": "Extracted Assets", "kind": "store", "sub": "images, tables" },
          { "id": "trans", "label": "Transcripts", "kind": "store", "sub": "word timings" },
          { "id": "chunks", "label": "Chunk Records", "kind": "store", "sub": "text + provenance" }
        ] },
        { "title": "Serving zone — query-time, rebuildable", "kind": "boundary", "nodes": [
          { "id": "vec", "label": "Vector Index", "kind": "store", "sub": "per-tenant namespace" },
          { "id": "lex", "label": "Lexical Index", "kind": "store" },
          { "id": "tab", "label": "Analytical Tables", "kind": "store", "sub": "typed, SQL-queryable" },
          { "id": "cache", "label": "Semantic Cache", "kind": "store", "sub": "TTL bound" }
        ] },
        { "title": "Operational", "kind": "boundary", "nodes": [
          { "id": "meta", "label": "Metadata DB", "kind": "store", "sub": "row-level security" },
          { "id": "audit", "label": "Audit Log", "kind": "store", "sub": "write-once" },
          { "id": "eval", "label": "Eval & Feedback Store", "kind": "store", "sub": "golden set" }
        ] }
      ] }
    ],
    "outside": [
      { "id": "cold", "label": "Cold Archive", "kind": "external", "sub": "glacier class" },
      { "id": "erase", "label": "Erasure Service", "kind": "external", "sub": "subject request" }
    ],
    "edges": [
      { "from": "orig", "to": "parsed", "label": "reparse on parser upgrade", "kind": "batch" },
      { "from": "chunks", "to": "vec", "label": "index build", "kind": "batch" },
      { "from": "orig", "to": "cold", "label": "after 90 days", "kind": "batch" },
      { "from": "erase", "to": "man", "label": "tombstone then purge", "kind": "error" }
    ],
    "note": "Only the raw zone is irreplaceable. Everything below it can be rebuilt from it.",
    "meta": { "v": "1.0", "owner": "Data Architecture" }
  },

  {
    "id": "09-integration-architecture",
    "title": "Integration Architecture — Every Interface",
    "layout": "hub",
    "canvas": { "width": 1560 },
    "left": { "title": "Inbound — who calls us", "nodes": [
      { "id": "webui", "label": "Web Application", "rel": "HTTPS + OIDC" },
      { "id": "esearch", "label": "Enterprise Search", "kind": "external", "rel": "REST /v1/query" },
      { "id": "bot", "label": "Teams / Slack Bot", "kind": "external", "rel": "signed webhook" },
      { "id": "spconn", "label": "SharePoint Connector", "kind": "external", "rel": "delta crawl, 15 min", "kind2": "batch" },
      { "id": "drop", "label": "Object Store Drop", "kind": "external", "rel": "event on upload", "kind2": "async" }
    ] },
    "centre": { "title": "Multimodal RAG Platform", "nodes": [
      { "id": "core", "label": "API Gateway", "kind": "integration", "sub": "OIDC, quota, schema" },
      { "id": "qsvc", "label": "Query API", "sub": "OpenAPI 3.1, SSE" },
      { "id": "isvc", "label": "Ingestion API", "sub": "presigned upload" }
    ] },
    "right": { "title": "Outbound — what we call", "nodes": [
      { "id": "claude", "label": "Claude API", "kind": "external", "rel": "generation + vision", "dir": "out" },
      { "id": "embapi", "label": "Embedding API", "kind": "external", "rel": "batched embed", "dir": "out", "kind2": "batch" },
      { "id": "asr", "label": "Speech-to-Text", "kind": "external", "rel": "async job + callback", "dir": "out", "kind2": "async" },
      { "id": "idp", "label": "Identity Provider", "kind": "external", "rel": "OIDC discovery, JWKS", "dir": "out" },
      { "id": "siem", "label": "SIEM", "kind": "external", "rel": "audit stream", "dir": "out", "kind2": "async" }
    ] },
    "note": "Every outbound call leaves through the model gateway or the egress proxy. No direct SDK calls from services.",
    "meta": { "v": "1.0", "owner": "Integration Architecture" }
  },

  {
    "id": "10-security-trust-zones",
    "title": "Security Architecture — Trust Zones and Crossings",
    "layout": "zones",
    "canvas": { "width": 1660 },
    "zones": [
      { "title": "Untrusted — Internet", "kind": "trust", "nodes": [
        { "id": "user", "label": "End User", "kind": "actor" },
        { "id": "mal", "label": "Malicious Upload", "kind": "risk", "sub": "macro, embedded script" },
        { "id": "inj", "label": "Prompt Injection", "kind": "risk", "sub": "text inside a document" }
      ] },
      { "title": "Perimeter", "kind": "trust", "nodes": [
        { "id": "waf", "label": "WAF & DDoS", "kind": "security" },
        { "id": "gw", "label": "API Gateway", "kind": "integration", "sub": "OIDC, mTLS out" },
        { "id": "rl", "label": "Quota & Rate Limit", "kind": "security", "sub": "per tenant" }
      ] },
      { "title": "Application — private subnet", "kind": "trust", "nodes": [
        { "id": "orch", "label": "Query Orchestrator" },
        { "id": "wk", "label": "Ingestion Workers", "sub": "no inbound routes" },
        { "id": "cg", "label": "Content Guard", "kind": "security", "sub": "AV, injection strip" },
        { "id": "mgw", "label": "Model Gateway", "kind": "integration", "sub": "egress allow-list" }
      ] },
      { "title": "Data — isolated subnet", "kind": "trust", "nodes": [
        { "id": "vec", "label": "Vector Index", "kind": "store", "sub": "tenant namespace" },
        { "id": "obj", "label": "Object Store", "kind": "store", "sub": "CMK encryption" },
        { "id": "db", "label": "Metadata DB", "kind": "store", "sub": "row-level security" },
        { "id": "audit", "label": "Audit Log", "kind": "store", "sub": "write-once" }
      ] },
      { "title": "Control plane & egress", "kind": "trust", "nodes": [
        { "id": "idp", "label": "Identity Provider", "kind": "external" },
        { "id": "kms", "label": "KMS & Secrets", "kind": "security", "sub": "rotation 90 d" },
        { "id": "claude", "label": "Claude API", "kind": "external", "sub": "allow-listed egress" },
        { "id": "siem", "label": "SIEM", "kind": "security" }
      ] }
    ],
    "edges": [
      { "from": "user", "to": "waf", "label": "TLS 1.3" },
      { "from": "waf", "to": "gw", "label": "bearer token" },
      { "from": "gw", "to": "orch", "label": "mTLS" },
      { "from": "gw", "to": "idp", "label": "verify JWKS", "route": "gutter" },
      { "from": "mal", "to": "cg", "label": "quarantine", "kind": "error" },
      { "from": "inj", "to": "cg", "label": "strip", "kind": "error" },
      { "from": "orch", "to": "vec", "label": "tenant filter" },
      { "from": "wk", "to": "obj", "label": "CMK envelope" },
      { "from": "mgw", "to": "claude", "label": "redacted", "route": "gutter" },
      { "from": "orch", "to": "audit", "label": "decision record", "kind": "async", "route": "gutter" },
      { "from": "audit", "to": "siem", "label": "forward", "kind": "async" }
    ],
    "note": "Retrieved content is data, never instruction. The generation prompt states this and the guard enforces it.",
    "meta": { "v": "1.0", "owner": "Security Architecture" }
  },

  {
    "id": "11-deployment-infrastructure",
    "title": "Deployment & Infrastructure",
    "layout": "nested",
    "canvas": { "width": 1560 },
    "boxes": [
      { "title": "Primary region — active", "kind": "cloud", "dir": "col", "children": [
        { "title": "Availability Zone A", "kind": "boundary", "nodes": [
          { "id": "ing1", "label": "Ingress Controller", "kind": "integration" },
          { "id": "n1", "label": "General Node Pool", "sub": "8 vCPU x 3" },
          { "id": "g1", "label": "GPU Node Pool", "sub": "1 x L4, rerank + VLM" },
          { "id": "eg1", "label": "Egress Proxy", "kind": "security", "sub": "allow-listed" }
        ] },
        { "title": "Availability Zone B", "kind": "boundary", "nodes": [
          { "id": "ing2", "label": "Ingress Controller", "kind": "integration" },
          { "id": "n2", "label": "General Node Pool", "sub": "8 vCPU x 3" },
          { "id": "g2", "label": "GPU Node Pool", "sub": "1 x L4, spot burst" },
          { "id": "eg2", "label": "Egress Proxy", "kind": "security", "sub": "standby" }
        ] },
        { "title": "Managed services — multi-AZ", "kind": "boundary", "nodes": [
          { "id": "pg", "label": "Metadata DB", "kind": "store", "sub": "HA pair, PITR" },
          { "id": "vecp", "label": "Vector Service", "kind": "store", "sub": "3 nodes, RF 2" },
          { "id": "lexp", "label": "Search Cluster", "kind": "store", "sub": "3 data nodes" },
          { "id": "objp", "label": "Object Store", "kind": "store", "sub": "versioned, CMK" },
          { "id": "redis", "label": "Cache", "kind": "store", "sub": "primary + replica" },
          { "id": "q", "label": "Work Queue", "kind": "queue", "sub": "DLQ per stage" }
        ] }
      ] },
      { "title": "DR region — warm standby, RPO 15 min / RTO 4 h", "kind": "cloud", "nodes": [
        { "id": "objd", "label": "Object Replica", "kind": "store", "sub": "cross-region copy" },
        { "id": "pgd", "label": "DB Read Replica", "kind": "store", "sub": "streaming" },
        { "id": "cl", "label": "Pilot Cluster", "sub": "0 replicas until failover" },
        { "id": "rb", "label": "Index Rebuild Job", "sub": "from derived zone" }
      ] }
    ],
    "outside": [
      { "id": "cdn", "label": "CDN / Edge", "kind": "external", "sub": "static assets" },
      { "id": "claude", "label": "Claude API", "kind": "external", "sub": "regional endpoint" }
    ],
    "edges": [
      { "from": "objp", "to": "objd", "label": "replication, 15 min", "kind": "async" },
      { "from": "pg", "to": "pgd", "label": "streaming replica", "kind": "async" },
      { "from": "objd", "to": "rb", "label": "rebuild on failover", "kind": "batch" }
    ],
    "note": "Vector and lexical indexes are not replicated. They are rebuilt from the derived zone, which is cheaper than paying to mirror them.",
    "meta": { "v": "1.0", "owner": "Platform Engineering" }
  },

  {
    "id": "12-cicd-environments",
    "title": "CI/CD and Environment Promotion",
    "layout": "flow",
    "canvas": { "width": 1560 },
    "chain": true,
    "stages": [
      { "title": "Source", "nodes": [
        { "id": "git", "label": "Git Repository", "sub": "trunk + short branches" },
        { "id": "iac", "label": "Infrastructure as Code" },
        { "id": "pa", "label": "Prompt & Eval Assets", "sub": "versioned with code" }
      ] },
      { "title": "Build", "nodes": [
        { "id": "ci", "label": "CI Pipeline" },
        { "id": "img", "label": "Container Build", "sub": "SBOM, signed" },
        { "id": "ut", "label": "Unit & Contract Tests" }
      ] },
      { "title": "Gates", "nodes": [
        { "id": "sec", "label": "Security Scan", "kind": "decision", "sub": "SAST, deps, image" },
        { "id": "ev", "label": "RAG Eval Gate", "kind": "decision", "sub": "recall, groundedness" },
        { "id": "cost", "label": "Cost Guard", "kind": "decision", "sub": "cost per query" }
      ] },
      { "title": "Environments", "nodes": [
        { "id": "dev", "label": "Development" },
        { "id": "stg", "label": "Staging", "sub": "production-like corpus" },
        { "id": "prd", "label": "Production", "sub": "canary 10%" }
      ] },
      { "title": "Operate", "nodes": [
        { "id": "gitops", "label": "GitOps Sync", "sub": "desired state" },
        { "id": "tel", "label": "Telemetry", "kind": "platform" },
        { "id": "rb", "label": "Rollback", "sub": "one revert commit" }
      ] }
    ],
    "edges": [
      { "from": "ev", "to": "ci", "label": "quality regression, block", "kind": "error" },
      { "from": "rb", "to": "prd", "label": "auto revert on SLO breach", "kind": "error" }
    ],
    "note": "A prompt or chunking change goes through the same gates as a code change. Both move answer quality.",
    "meta": { "v": "1.0", "owner": "Platform Engineering" }
  },

  {
    "id": "13-observability-evaluation",
    "title": "Observability & Evaluation Matrix",
    "layout": "grid",
    "canvas": { "width": 1620 },
    "laneHeaderWidth": 170,
    "columns": ["Emit", "Collect", "Store", "Analyse", "Act"],
    "rows": [
      { "title": "Service health", "cells": [
        [ { "label": "RED metrics" } ], [ { "label": "OTel Collector", "kind": "platform" } ],
        [ { "label": "Metric Store", "kind": "store" } ], [ { "label": "SLO dashboards" } ],
        [ { "label": "Page on burn rate" } ]
      ] },
      { "title": "Traces", "cells": [
        [ { "label": "Span per stage" } ], [ { "label": "OTel Collector", "kind": "platform" } ],
        [ { "label": "Trace Store", "kind": "store" } ], [ { "label": "Latency breakdown" } ],
        [ { "label": "Tune slow stage" } ]
      ] },
      { "title": "Retrieval quality", "cells": [
        [ { "label": "Hit rank logged" } ], [ { "label": "Eval Collector" } ],
        [ { "label": "Eval Store", "kind": "store" } ], [ { "label": "Recall@k, nDCG" } ],
        [ { "label": "Re-chunk or re-embed" } ]
      ] },
      { "title": "Answer quality", "cells": [
        [ { "label": "Citation coverage" } ], [ { "label": "LLM Trace", "kind": "platform" } ],
        [ { "label": "Trace Store", "kind": "store" } ], [ { "label": "Groundedness, refusal rate" } ],
        [ { "label": "Prompt or model change" } ]
      ] },
      { "title": "Cost", "cells": [
        [ { "label": "Tokens per request" } ], [ { "label": "Gateway Meter", "kind": "integration" } ],
        [ { "label": "Cost Ledger", "kind": "store" } ], [ { "label": "Cost per query, per tenant" } ],
        [ { "label": "Route or cache tune" } ]
      ] },
      { "title": "Safety & privacy", "cells": [
        [ { "label": "Guard verdicts", "kind": "security" } ], [ { "label": "Audit Stream", "kind": "security" } ],
        [ { "label": "Audit Log", "kind": "store", "sub": "write-once" } ], [ { "label": "Injection, PII rate" } ],
        [ { "label": "Policy update" } ]
      ] }
    ],
    "note": "Rows without an Act cell are telemetry nobody owns. Every row here has one.",
    "meta": { "v": "1.0", "owner": "SRE & Quality" }
  },

  {
    "id": "14-ragops-lifecycle",
    "title": "RAGOps — The Improvement Loop",
    "layout": "cycle",
    "canvas": { "width": 1300 },
    "rx": 430,
    "ry": 215,
    "centre": { "label": "RAGOps" },
    "nodes": [
      { "id": "obs", "label": "Observe", "sub": "traces, thumbs, escalations" },
      { "id": "diag", "label": "Diagnose", "sub": "retrieval or generation" },
      { "id": "cur", "label": "Curate", "sub": "add to golden set" },
      { "id": "chg", "label": "Change", "sub": "chunking, prompt, model" },
      { "id": "eval", "label": "Evaluate", "sub": "offline then shadow" },
      { "id": "rel", "label": "Release", "sub": "canary, gated" }
    ],
    "ringLabels": [
      "failure signals", "labelled cases", "hypothesis",
      "candidate build", "eval verdict", "new baseline"
    ],
    "note": "Diagnose first splits retrieval failure from generation failure. The two have different fixes.",
    "meta": { "v": "1.0", "owner": "AI Engineering" }
  },

  {
    "id": "15-query-sequence",
    "title": "Critical Flow — Question to Cited Answer",
    "layout": "sequence",
    "canvas": { "width": 1560 },
    "lifelines": [
      { "id": "user", "label": "User", "kind": "actor" },
      { "id": "ui", "label": "Web App" },
      { "id": "api", "label": "Query API" },
      { "id": "guard", "label": "Guardrails", "kind": "security" },
      { "id": "ret", "label": "Retriever" },
      { "id": "rr", "label": "Reranker" },
      { "id": "mgw", "label": "Model Gateway", "kind": "integration" },
      { "id": "llm", "label": "Claude API", "kind": "external" }
    ],
    "messages": [
      { "from": "user", "to": "ui", "label": "asks a question", "kind": "call" },
      { "from": "ui", "to": "api", "label": "POST /v1/query", "kind": "call" },
      { "from": "api", "to": "guard", "label": "screen input", "kind": "call" },
      { "from": "guard", "to": "api", "label": "clean, PII masked", "kind": "return" },
      { "from": "api", "to": "ret", "label": "hybrid search, k=50", "kind": "call" },
      { "from": "ret", "to": "ret", "label": "dense + BM25 + SQL, tenant filtered", "kind": "self" },
      { "from": "ret", "to": "rr", "label": "fused candidates", "kind": "call" },
      { "from": "rr", "to": "api", "label": "top 8 with parents", "kind": "return" },
      { "from": "api", "to": "mgw", "label": "assemble context", "kind": "call" },
      { "from": "mgw", "to": "llm", "label": "documents + question", "kind": "call" },
      { "from": "llm", "to": "mgw", "label": "answer with cited spans", "kind": "return" },
      { "from": "mgw", "to": "api", "label": "normalised result", "kind": "return" },
      { "from": "api", "to": "api", "label": "grounding gate", "kind": "self" },
      { "from": "api", "to": "ui", "label": "no supporting span, abstain", "kind": "error" },
      { "from": "api", "to": "ui", "label": "streamed answer + citations", "kind": "return" },
      { "from": "ui", "to": "user", "label": "renders with source links", "kind": "return" }
    ],
    "note": "Semantic cache hit and token streaming are omitted for clarity.",
    "meta": { "v": "1.0", "owner": "Solution Architecture" }
  },

  {
    "id": "16-data-model",
    "title": "Core Data Model",
    "layout": "er",
    "canvas": { "width": 1600, "cols": 4 },
    "rowGap": 200,
    "entities": [
      { "id": "tenant", "name": "tenant", "row": 0, "col": 0, "attrs": [
        "tenant_id  PK", "name", "retention_days", "region" ] },
      { "id": "source", "name": "source", "row": 0, "col": 1, "attrs": [
        "source_id  PK", "tenant_id  FK -> tenant", "kind", "uri", "acl_ref" ] },
      { "id": "document", "name": "document", "row": 0, "col": 2, "attrs": [
        "document_id  PK", "source_id  FK -> source", "title", "modality", "sha256", "version" ] },
      { "id": "query", "name": "query_log", "row": 1, "col": 0, "attrs": [
        "query_id  PK", "tenant_id  FK -> tenant", "user_id", "question", "latency_ms", "cost_usd" ] },
      { "id": "chunk", "name": "chunk", "row": 1, "col": 2, "attrs": [
        "chunk_id  PK", "document_id  FK -> document", "parent_chunk_id  FK -> chunk",
        "modality", "text", "page", "char_start", "char_end" ] },
      { "id": "asset", "name": "asset", "row": 1, "col": 3, "attrs": [
        "asset_id  PK", "document_id  FK -> document", "kind", "page", "bbox", "timecode_ms", "uri" ] },
      { "id": "citation", "name": "citation", "row": 2, "col": 1, "attrs": [
        "citation_id  PK", "query_id  FK -> query_log", "chunk_id  FK -> chunk", "span", "score" ] },
      { "id": "embedding", "name": "embedding", "kind": "store", "row": 2, "col": 2, "attrs": [
        "embedding_id  PK", "chunk_id  FK -> chunk", "space", "model", "dim", "vector_ref" ] },
      { "id": "tablefact", "name": "table_fact", "kind": "store", "row": 2, "col": 3, "attrs": [
        "table_id  PK", "asset_id  FK -> asset", "column_schema", "row_count", "storage_uri" ] }
    ],
    "relations": [
      { "from": "tenant", "to": "source", "label": "1 : N", "from_side": "e", "to_side": "w" },
      { "from": "source", "to": "document", "label": "1 : N", "from_side": "e", "to_side": "w" },
      { "from": "document", "to": "chunk", "label": "1 : N", "from_side": "s", "to_side": "n" },
      { "from": "document", "to": "asset", "label": "1 : N", "from_side": "e", "to_side": "n" },
      { "from": "asset", "to": "chunk", "label": "1 : N", "from_side": "w", "to_side": "e" },
      { "from": "chunk", "to": "embedding", "label": "1 : N", "from_side": "s", "to_side": "n" },
      { "from": "asset", "to": "tablefact", "label": "1 : 1", "kind": "optional", "from_side": "s", "to_side": "n" },
      { "from": "chunk", "to": "citation", "label": "1 : N", "from_side": "w", "to_side": "e" },
      { "from": "query", "to": "citation", "label": "1 : N", "from_side": "s", "to_side": "w" },
      { "from": "tenant", "to": "query", "label": "1 : N", "from_side": "s", "to_side": "n" }
    ],
    "note": "chunk.parent_chunk_id carries small-to-big retrieval. Provenance columns are what make a citation clickable.",
    "meta": { "v": "1.0", "owner": "Data Architecture" }
  }
]
