[
  {
    "id": "01-system-context",
    "title": "API Gateway Platform — System Context",
    "layout": "context",
    "canvas": {
      "width": 1700
    },
    "colWidth": 280,
    "system": {
      "label": "API Gateway Platform",
      "sub": "The only ingress path"
    },
    "groups": [
      {
        "side": "left",
        "title": "Callers outside the boundary",
        "nodes": [
          {
            "id": "partner",
            "label": "Partner backend",
            "kind": "external",
            "sub": "mTLS, 40 partners",
            "rel": "server-to-server calls",
            "dir": "in"
          },
          {
            "id": "custapp",
            "label": "Customer integration",
            "kind": "external",
            "sub": "50,000 orgs, 6 SDKs",
            "rel": "key or OAuth",
            "dir": "in"
          },
          {
            "id": "dev",
            "label": "Integration developer",
            "kind": "actor",
            "rel": "portal, keys, docs",
            "dir": "in"
          }
        ]
      },
      {
        "side": "right",
        "title": "Inside the product",
        "nodes": [
          {
            "id": "svc",
            "label": "Upstream services",
            "sub": "120 services, 800 routes",
            "rel": "mTLS, signed identity"
          },
          {
            "id": "sandbox",
            "label": "Sandbox estate",
            "sub": "same policy path",
            "rel": "sandbox credentials"
          },
          {
            "id": "webhooks",
            "label": "Webhook delivery",
            "kind": "external",
            "sub": "separate platform",
            "rel": "outbound, out of scope",
            "kind2": "async"
          }
        ]
      },
      {
        "side": "top",
        "title": "Who changes it",
        "nodes": [
          {
            "id": "sre",
            "label": "Platform SRE",
            "kind": "actor",
            "rel": "rollout, revert",
            "dir": "in"
          },
          {
            "id": "apiowner",
            "label": "API product owner",
            "kind": "actor",
            "rel": "products, plans",
            "dir": "in"
          },
          {
            "id": "sec",
            "label": "Security engineer",
            "kind": "actor",
            "rel": "edge rules",
            "dir": "in"
          }
        ]
      },
      {
        "side": "bottom",
        "title": "Dependencies it cannot be independent of",
        "nodes": [
          {
            "id": "authsrv",
            "label": "Authorisation server",
            "kind": "security",
            "sub": "token issue",
            "rel": "introspection",
            "kind2": "bidirectional"
          },
          {
            "id": "billing",
            "label": "Billing and plans",
            "kind": "external",
            "sub": "plan tiers",
            "rel": "usage records",
            "kind2": "async"
          },
          {
            "id": "dns",
            "label": "Public DNS + anycast",
            "kind": "external",
            "sub": "global edge",
            "rel": "traffic arrives here",
            "dir": "in"
          }
        ]
      }
    ],
    "note": "East-west service-to-service traffic belongs to the service mesh and is deliberately outside this boundary.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "02-high-level-architecture",
    "title": "API Gateway Platform — High-Level Architecture",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Arrive",
        "nodes": [
          {
            "id": "anycast",
            "label": "Global anycast",
            "kind": "integration",
            "sub": "Cloud Load Balancing"
          },
          {
            "id": "armor",
            "label": "Edge protection",
            "kind": "security",
            "sub": "Cloud Armor"
          }
        ]
      },
      {
        "title": "Admit",
        "nodes": [
          {
            "id": "tls",
            "label": "TLS termination",
            "kind": "security",
            "sub": "TLS 1.2 / 1.3"
          },
          {
            "id": "protect",
            "label": "Connection limits",
            "kind": "app",
            "sub": "body 10 MB, slow-read"
          }
        ]
      },
      {
        "title": "Identify",
        "nodes": [
          {
            "id": "authn",
            "label": "Authenticate",
            "kind": "security",
            "sub": "key / OAuth / JWT"
          },
          {
            "id": "princ",
            "label": "Resolve principal",
            "kind": "app",
            "sub": "tenant, scopes, tier"
          }
        ]
      },
      {
        "title": "Decide",
        "nodes": [
          {
            "id": "quota",
            "label": "Quota and limits",
            "kind": "decision",
            "sub": "4 scopes, all must pass"
          },
          {
            "id": "shed",
            "label": "Tier-aware shed",
            "kind": "decision",
            "sub": "free before paid"
          }
        ]
      },
      {
        "title": "Route",
        "nodes": [
          {
            "id": "route",
            "label": "Route and version",
            "kind": "app",
            "sub": "host, path, method"
          },
          {
            "id": "split",
            "label": "Variant split",
            "kind": "app",
            "sub": "sticky, 1% steps"
          }
        ]
      },
      {
        "title": "Forward",
        "nodes": [
          {
            "id": "upstream",
            "label": "Upstream group",
            "sub": "mTLS, health-checked"
          },
          {
            "id": "cache",
            "label": "Response cache",
            "kind": "store",
            "sub": "cacheable routes"
          }
        ]
      },
      {
        "title": "Account",
        "nodes": [
          {
            "id": "emit",
            "label": "Emit usage",
            "kind": "queue",
            "sub": "Pub/Sub, non-blocking"
          },
          {
            "id": "analytics",
            "label": "Analytics",
            "kind": "store",
            "sub": "BigQuery"
          }
        ]
      }
    ],
    "note": "Every stage reads state already resident in the proxy, and no stage calls the control plane. Rejections are emitted as usage too; the arrow is omitted to keep the spine clean.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "03-actors-and-journeys",
    "title": "Actors and Their Core Journeys",
    "layout": "actors",
    "canvas": {
      "width": 1760
    },
    "cardWidth": 290,
    "groups": [
      {
        "title": "People outside the company",
        "kind": "boundary",
        "actors": [
          {
            "id": "intdev",
            "label": "Integration developer",
            "sub": "~4,000 active / month",
            "goal": "Get a key and make a call that works before I lose interest in your product.",
            "journeys": [
              {
                "id": "j-first-call",
                "label": "First successful call",
                "sub": "target < 10 min"
              },
              {
                "label": "Debug a 429 without filing a ticket"
              },
              {
                "label": "Rotate a key with no downtime"
              }
            ]
          },
          {
            "id": "partnereng",
            "label": "Partner engineer",
            "sub": "40 partners, mTLS",
            "goal": "Know months ahead if you are going to change something under me, and be able to stay put if I cannot move yet.",
            "journeys": [
              {
                "id": "j-ship-v2-partner",
                "label": "Survive a version migration"
              },
              {
                "label": "Pin to a version by agreement"
              }
            ]
          }
        ]
      },
      {
        "title": "People inside the company",
        "kind": "boundary",
        "actors": [
          {
            "id": "apiown",
            "label": "API product owner",
            "sub": "120 services",
            "goal": "Ship v2 and retire v1 without finding out who was still calling it by breaking them.",
            "journeys": [
              {
                "id": "j-ship-v2",
                "label": "Publish, canary, deprecate, sunset"
              },
              {
                "label": "See who is still on the old version"
              }
            ]
          },
          {
            "id": "sre2",
            "label": "Platform SRE",
            "sub": "on call, 24/7",
            "goal": "Tell in one glance whether this is the gateway's fault or an upstream's, and revert in one action if it is mine.",
            "journeys": [
              {
                "label": "Revert a bad config in 30 s"
              },
              {
                "label": "Evacuate a region"
              },
              {
                "label": "Separate a 502 from a 429"
              }
            ]
          },
          {
            "id": "secops",
            "label": "Security engineer",
            "sub": "policy owner",
            "goal": "Revoke a leaked credential everywhere in under a minute, and prove afterwards what it did.",
            "journeys": [
              {
                "label": "Revoke a credential globally"
              },
              {
                "label": "Answer an audit from the log"
              }
            ]
          }
        ]
      },
      {
        "title": "Actors that are not people",
        "kind": "cloud",
        "actors": [
          {
            "id": "rollout",
            "label": "Rollout controller",
            "kind": "platform",
            "sub": "continuous",
            "goal": "Halt a canary on the evidence, before anyone is paged about it.",
            "journeys": [
              {
                "label": "Score a canary window"
              },
              {
                "label": "Revert to last known good"
              }
            ]
          },
          {
            "id": "healthcheck",
            "label": "Health checker",
            "kind": "platform",
            "sub": "every backend",
            "goal": "Take an unhealthy backend out of rotation before a caller finds it.",
            "journeys": [
              {
                "label": "Eject and re-admit a backend"
              }
            ]
          },
          {
            "id": "configpush",
            "label": "Config distributor",
            "kind": "platform",
            "sub": "versioned snapshots",
            "goal": "Get a new configuration version onto every proxy, and know which ones have it.",
            "journeys": [
              {
                "label": "Distribute and confirm a version"
              }
            ]
          }
        ]
      }
    ],
    "note": "Three of the actors are machines. Two of them can break production faster than any of the people.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "04-journey-first-successful-call",
    "title": "Journey — The First Successful Call",
    "layout": "journey",
    "canvas": {
      "width": 1720
    },
    "actor": {
      "label": "Integration developer",
      "sub": "has never used this API",
      "goal": "Make one call that returns 200, then decide whether to build on this",
      "trigger": "A ticket that says \"integrate with their API by Friday\"",
      "success": "A 200 with real data, from their own code, inside ten minutes"
    },
    "phases": [
      {
        "title": "Sign up",
        "sub": "portal"
      },
      {
        "title": "Get a key"
      },
      {
        "title": "First call",
        "moment": true
      },
      {
        "title": "First rejection",
        "moment": true
      },
      {
        "title": "Build"
      }
    ],
    "lanes": [
      {
        "title": "What they do",
        "kind": "step",
        "cells": [
          [
            {
              "label": "Registers an org"
            }
          ],
          [
            {
              "label": "Creates an app"
            },
            {
              "label": "Copies the secret once"
            }
          ],
          [
            {
              "label": "Pastes the curl"
            }
          ],
          [
            {
              "label": "Reads the error body"
            }
          ],
          [
            {
              "label": "Moves to sandbox"
            }
          ]
        ]
      },
      {
        "title": "What the platform does",
        "kind": "system",
        "cells": [
          [
            {
              "label": "Issues sandbox creds",
              "kind": "system"
            }
          ],
          [
            {
              "label": "Stores a verifier only",
              "kind": "system"
            }
          ],
          [
            {
              "label": "Authn, quota, route",
              "kind": "system"
            }
          ],
          [
            {
              "label": "429 naming the limit",
              "kind": "system"
            }
          ],
          [
            {
              "label": "Live quota view",
              "kind": "system"
            }
          ]
        ]
      },
      {
        "title": "How it feels",
        "kind": "emotion",
        "levels": [
          "Convinced",
          "Fine",
          "Gone"
        ],
        "points": [
          1,
          1,
          0,
          2,
          1
        ]
      },
      {
        "title": "Where it hurts",
        "kind": "pain",
        "cells": [
          [],
          [
            {
              "label": "Secret shown once only"
            }
          ],
          [
            {
              "label": "A bare 401 ends it here"
            }
          ],
          [
            {
              "label": "\"Which of four limits?\""
            }
          ],
          []
        ]
      },
      {
        "title": "What answers it",
        "kind": "gain",
        "cells": [
          [
            {
              "label": "Self-serve, no human"
            }
          ],
          [
            {
              "label": "Rotation with overlap"
            }
          ],
          [
            {
              "label": "Typed auth error code"
            }
          ],
          [
            {
              "label": "Scope, limit, reset, retry"
            }
          ],
          [
            {
              "label": "Same path as production"
            }
          ]
        ]
      }
    ],
    "chain": true,
    "note": "The trough is at the third phase and it is an error message, not a screen.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "05-journey-shipping-v2",
    "title": "Journey — Shipping v2 Without Breaking Anyone",
    "layout": "journey",
    "canvas": {
      "width": 1780
    },
    "actor": {
      "label": "API product owner",
      "sub": "owns one of 120 services",
      "goal": "Get everyone onto v2 and turn v1 off, without an incident carrying my name",
      "trigger": "A schema change v1 cannot express",
      "success": "v1 sunset on the published date with zero callers left on it"
    },
    "phases": [
      {
        "title": "Publish v2",
        "sub": "preview"
      },
      {
        "title": "Canary",
        "moment": true
      },
      {
        "title": "Deprecate"
      },
      {
        "title": "Chase the tail",
        "moment": true
      },
      {
        "title": "Sunset"
      }
    ],
    "lanes": [
      {
        "title": "What they do",
        "kind": "step",
        "cells": [
          [
            {
              "label": "Registers v2 route"
            }
          ],
          [
            {
              "label": "Splits 1% to v2"
            }
          ],
          [
            {
              "label": "Marks v1 deprecated"
            }
          ],
          [
            {
              "label": "Reads active callers"
            },
            {
              "label": "Grants 3 version pins"
            }
          ],
          [
            {
              "label": "Requests sunset"
            }
          ]
        ]
      },
      {
        "title": "What the platform does",
        "kind": "system",
        "cells": [
          [
            {
              "label": "Schema becomes the docs",
              "kind": "system"
            }
          ],
          [
            {
              "label": "Sticky per credential",
              "kind": "system"
            }
          ],
          [
            {
              "label": "Deprecation + Sunset hdrs",
              "kind": "system"
            }
          ],
          [
            {
              "label": "Names every live caller",
              "kind": "system"
            }
          ],
          [
            {
              "label": "Refuses while callers remain",
              "kind": "system"
            }
          ]
        ]
      },
      {
        "title": "How it feels",
        "kind": "emotion",
        "levels": [
          "Confident",
          "Watchful",
          "Exposed"
        ],
        "points": [
          1,
          0,
          1,
          0,
          2
        ]
      },
      {
        "title": "Where it hurts",
        "kind": "pain",
        "cells": [
          [],
          [
            {
              "label": "1% may never signal"
            }
          ],
          [
            {
              "label": "Headers nobody reads"
            }
          ],
          [
            {
              "label": "Two orgs will not move"
            }
          ],
          []
        ]
      },
      {
        "title": "What answers it",
        "kind": "gain",
        "cells": [
          [
            {
              "label": "Two live versions allowed"
            }
          ],
          [
            {
              "label": "Auto-revert in 90 s"
            }
          ],
          [
            {
              "label": "Portal + per-app usage"
            }
          ],
          [
            {
              "label": "Per-tenant pin, dated"
            }
          ],
          [
            {
              "label": "Sunset gated on evidence"
            }
          ]
        ]
      }
    ],
    "chain": true,
    "note": "The second trough is social, not technical: the platform's answer is a dated per-tenant pin rather than a slipped date.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "06-layered-architecture",
    "title": "Layered Architecture",
    "layout": "bands",
    "canvas": {
      "width": 1740
    },
    "layerHeaderWidth": 170,
    "bands": [
      {
        "name": "Callers",
        "nodes": [
          {
            "id": "l-int",
            "label": "Customer integrations",
            "kind": "external"
          },
          {
            "id": "l-part",
            "label": "Partner backends",
            "kind": "external"
          },
          {
            "id": "l-sdk",
            "label": "First-party SDKs",
            "kind": "external"
          },
          {
            "id": "l-port",
            "label": "Developer portal",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Edge",
        "nodes": [
          {
            "id": "l-any",
            "label": "Anycast + global LB",
            "kind": "integration"
          },
          {
            "id": "l-tls",
            "label": "TLS termination",
            "kind": "security"
          },
          {
            "id": "l-waf",
            "label": "WAF and DDoS",
            "kind": "security"
          },
          {
            "id": "l-geo",
            "label": "Geo / IP policy",
            "kind": "security"
          }
        ]
      },
      {
        "name": "Policy",
        "nodes": [
          {
            "id": "l-authn",
            "label": "Authentication",
            "kind": "security"
          },
          {
            "id": "l-authz",
            "label": "Scope authorisation",
            "kind": "security"
          },
          {
            "id": "l-quota",
            "label": "Quota and limits",
            "kind": "app"
          },
          {
            "id": "l-shed",
            "label": "Tier-aware shedding",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Routing",
        "nodes": [
          {
            "id": "l-match",
            "label": "Route matching",
            "kind": "app"
          },
          {
            "id": "l-ver",
            "label": "Version selection",
            "kind": "app"
          },
          {
            "id": "l-split",
            "label": "Variant split",
            "kind": "app"
          },
          {
            "id": "l-trans",
            "label": "Transform and validate",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Proxy runtime",
        "nodes": [
          {
            "id": "l-conn",
            "label": "Connection pools",
            "kind": "app"
          },
          {
            "id": "l-cb",
            "label": "Circuit breakers",
            "kind": "app"
          },
          {
            "id": "l-retry",
            "label": "Retry budget",
            "kind": "app"
          },
          {
            "id": "l-cache",
            "label": "Response cache",
            "kind": "store"
          }
        ]
      },
      {
        "name": "Resident state",
        "nodes": [
          {
            "id": "l-snap",
            "label": "Config snapshot",
            "kind": "store"
          },
          {
            "id": "l-cred",
            "label": "Credential cache",
            "kind": "store"
          },
          {
            "id": "l-cnt",
            "label": "Local counters",
            "kind": "store"
          },
          {
            "id": "l-deny",
            "label": "Revocation denylist",
            "kind": "store"
          }
        ]
      },
      {
        "name": "Upstreams",
        "nodes": [
          {
            "id": "l-svc",
            "label": "Service groups v1 / v2",
            "kind": "app"
          },
          {
            "id": "l-canary",
            "label": "Canary group",
            "kind": "app"
          },
          {
            "id": "l-sand",
            "label": "Sandbox estate",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Control plane",
        "nodes": [
          {
            "id": "l-cfg",
            "label": "Config store",
            "kind": "store"
          },
          {
            "id": "l-cat",
            "label": "Product catalogue",
            "kind": "app"
          },
          {
            "id": "l-roll",
            "label": "Rollout controller",
            "kind": "platform"
          },
          {
            "id": "l-aud",
            "label": "Audit and analytics",
            "kind": "store"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "l-cfg",
        "to": "l-snap",
        "label": "push, versioned",
        "kind": "async"
      },
      {
        "from": "l-cat",
        "to": "l-cred",
        "label": "verifiers + denylist",
        "kind": "async"
      }
    ],
    "note": "The control plane sits below resident state and writes to it asynchronously. Nothing above ever calls down into it.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "07-platform-components",
    "title": "Platform Components — Three Planes That May Not Become Each Other",
    "layout": "nested",
    "canvas": {
      "width": 1780
    },
    "boxes": [
      {
        "title": "Request plane — per region, stateless on the hot path",
        "kind": "boundary",
        "dir": "col",
        "children": [
          {
            "title": "Edge tier (Google-managed)",
            "kind": "cloud",
            "nodes": [
              {
                "id": "c-glb",
                "label": "Global external ALB",
                "kind": "integration",
                "sub": "anycast, TLS"
              },
              {
                "id": "c-armor",
                "label": "Cloud Armor",
                "kind": "security",
                "sub": "WAF, DDoS, geo"
              },
              {
                "id": "c-cert",
                "label": "Managed certificates",
                "kind": "security",
                "sub": "per API hostname"
              }
            ]
          },
          {
            "title": "Proxy fleet — GKE regional node pools",
            "kind": "boundary",
            "nodes": [
              {
                "id": "c-envoy",
                "label": "Envoy proxy",
                "sub": "10k rps / instance"
              },
              {
                "id": "c-authf",
                "label": "Auth filter",
                "kind": "security",
                "sub": "in-process"
              },
              {
                "id": "c-quotaf",
                "label": "Quota filter",
                "kind": "app",
                "sub": "local + shared"
              },
              {
                "id": "c-routef",
                "label": "Router filter",
                "kind": "app",
                "sub": "version + variant"
              },
              {
                "id": "c-telf",
                "label": "Telemetry filter",
                "kind": "app",
                "sub": "fire and forget"
              }
            ]
          },
          {
            "title": "Resident state — in the pod, never a network hop to the control plane",
            "kind": "trust",
            "nodes": [
              {
                "id": "c-snap",
                "label": "Config snapshot",
                "kind": "store",
                "sub": "signed, versioned"
              },
              {
                "id": "c-credc",
                "label": "Credential cache",
                "kind": "store",
                "sub": "verifiers, 5 min TTL"
              },
              {
                "id": "c-denyl",
                "label": "Revocation denylist",
                "kind": "store",
                "sub": "pushed, 30 s SLO"
              },
              {
                "id": "c-local",
                "label": "Local counters",
                "kind": "store",
                "sub": "per-instance buckets"
              }
            ]
          }
        ]
      },
      {
        "title": "Shared runtime state — the one deliberate hot-path dependency",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "Counters",
            "kind": "plain",
            "nodes": [
              {
                "id": "c-redis",
                "label": "Memorystore Redis",
                "kind": "store",
                "sub": "sharded, in-region"
              }
            ]
          },
          {
            "title": "Cache",
            "kind": "plain",
            "nodes": [
              {
                "id": "c-rcache",
                "label": "Response cache",
                "kind": "store",
                "sub": "cacheable routes only"
              }
            ]
          },
          {
            "title": "Upstreams",
            "kind": "plain",
            "nodes": [
              {
                "id": "c-v1",
                "label": "Service group v1",
                "sub": "stable"
              },
              {
                "id": "c-v2",
                "label": "Service group v2",
                "sub": "canary weight"
              }
            ]
          }
        ]
      },
      {
        "title": "Control plane — an outage here stops change, not traffic",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "Configuration",
            "kind": "plain",
            "nodes": [
              {
                "id": "c-cfgapi",
                "label": "Config API",
                "kind": "app",
                "sub": "RBAC, reviewed"
              },
              {
                "id": "c-spanner",
                "label": "Config store",
                "kind": "store",
                "sub": "Spanner, versioned"
              },
              {
                "id": "c-dist",
                "label": "Snapshot publisher",
                "kind": "platform",
                "sub": "signs + uploads"
              }
            ]
          },
          {
            "title": "Product and identity",
            "kind": "plain",
            "nodes": [
              {
                "id": "c-cat",
                "label": "API product catalogue",
                "kind": "app",
                "sub": "plans, scopes"
              },
              {
                "id": "c-credstore",
                "label": "Credential store",
                "kind": "store",
                "sub": "verifiers only"
              },
              {
                "id": "c-portal",
                "label": "Developer portal",
                "kind": "app",
                "sub": "self-service"
              }
            ]
          },
          {
            "title": "Delivery and evidence",
            "kind": "plain",
            "nodes": [
              {
                "id": "c-roll",
                "label": "Rollout controller",
                "kind": "platform",
                "sub": "scores, halts"
              },
              {
                "id": "c-bq",
                "label": "Analytics store",
                "kind": "store",
                "sub": "BigQuery"
              },
              {
                "id": "c-audit",
                "label": "Audit ledger",
                "kind": "store",
                "sub": "immutable, 7 yr"
              }
            ]
          }
        ]
      }
    ],
    "outside": [
      {
        "id": "c-auth",
        "label": "Authorisation server",
        "kind": "external",
        "sub": "issues tokens"
      },
      {
        "id": "c-bill",
        "label": "Billing",
        "kind": "external",
        "sub": "consumes usage"
      }
    ],
    "edges": [
      {
        "from": "c-dist",
        "to": "c-snap",
        "label": "signed snapshot, pull",
        "kind": "async"
      },
      {
        "from": "c-credstore",
        "to": "c-denyl",
        "label": "revocation push",
        "kind": "async"
      },
      {
        "from": "c-quotaf",
        "to": "c-redis",
        "label": "shared counters",
        "kind": "sync"
      },
      {
        "from": "c-telf",
        "to": "c-bq",
        "label": "usage, sampled",
        "kind": "async"
      },
      {
        "from": "c-roll",
        "to": "c-dist",
        "label": "promote / revert",
        "kind": "sync"
      },
      {
        "from": "c-bq",
        "to": "c-bill",
        "label": "daily rollup",
        "kind": "batch"
      }
    ],
    "note": "Redis is the only synchronous dependency on the request path, and it is designed to be degradable rather than highly available.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "08-integration-surface",
    "title": "Integration Surface — Every Way In and Out",
    "layout": "hub",
    "canvas": {
      "width": 1740
    },
    "left": {
      "title": "Inbound",
      "nodes": [
        {
          "id": "i-key",
          "label": "API key callers",
          "kind": "external",
          "sub": "server-side",
          "rel": "api key"
        },
        {
          "id": "i-oauth",
          "label": "OAuth clients",
          "kind": "external",
          "sub": "bearer token",
          "rel": "bearer"
        },
        {
          "id": "i-mtls",
          "label": "Partner backends",
          "kind": "external",
          "sub": "40, mTLS or signed JWT",
          "rel": "mTLS"
        },
        {
          "id": "i-portal",
          "label": "Developer portal",
          "kind": "app",
          "sub": "self-service",
          "rel": "session"
        },
        {
          "id": "i-ops",
          "label": "Config API clients",
          "kind": "app",
          "sub": "CI and operators",
          "rel": "RBAC"
        }
      ]
    },
    "centre": {
      "title": "API Gateway Platform",
      "nodes": [
        {
          "id": "h-edge",
          "label": "Edge and admission",
          "kind": "integration"
        },
        {
          "id": "h-policy",
          "label": "Policy enforcement",
          "kind": "security"
        },
        {
          "id": "h-route",
          "label": "Routing and versioning",
          "kind": "app"
        },
        {
          "id": "h-state",
          "label": "Resident state",
          "kind": "store"
        },
        {
          "id": "h-tel",
          "label": "Usage emission",
          "kind": "queue"
        }
      ]
    },
    "right": {
      "title": "Outbound and dependencies",
      "nodes": [
        {
          "id": "o-svc",
          "label": "Upstream services",
          "sub": "mTLS + signed identity",
          "rel": "mTLS",
          "dir": "out"
        },
        {
          "id": "o-auth",
          "label": "Authorisation server",
          "kind": "security",
          "sub": "off the hot path",
          "rel": "refill",
          "dir": "out",
          "kind2": "async"
        },
        {
          "id": "o-cnt",
          "label": "Counter store",
          "kind": "store",
          "sub": "in-region",
          "rel": "counters",
          "dir": "out"
        },
        {
          "id": "o-bus",
          "label": "Usage bus",
          "kind": "queue",
          "sub": "Pub/Sub",
          "rel": "records",
          "dir": "out",
          "kind2": "async"
        },
        {
          "id": "o-log",
          "label": "Audit ledger",
          "kind": "store",
          "sub": "7-year retention",
          "rel": "audit",
          "dir": "out",
          "kind2": "async"
        }
      ]
    },
    "note": "One genuinely synchronous obligation leaves this platform: the call to the upstream group. Everything else is cached, pushed or asynchronous. Analytics and billing read from the usage bus and are not a gateway integration.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "09-data-flow",
    "title": "Data Flow — Configuration Down, Evidence Up",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Authored",
        "nodes": [
          {
            "id": "d-route",
            "label": "Route definition",
            "kind": "app",
            "sub": "reviewed in CI"
          },
          {
            "id": "d-plan",
            "label": "Plan and product",
            "kind": "app",
            "sub": "limits, scopes"
          },
          {
            "id": "d-cred",
            "label": "Credential created",
            "kind": "security",
            "sub": "portal"
          }
        ]
      },
      {
        "title": "Committed",
        "nodes": [
          {
            "id": "d-cfg",
            "label": "Config version N",
            "kind": "store",
            "sub": "immutable, signed"
          },
          {
            "id": "d-ver",
            "label": "Verifier written",
            "kind": "store",
            "sub": "no secret stored"
          }
        ]
      },
      {
        "title": "Distributed",
        "nodes": [
          {
            "id": "d-snap",
            "label": "Snapshot published",
            "kind": "platform",
            "sub": "object store"
          },
          {
            "id": "d-pull",
            "label": "Proxies pull",
            "kind": "app",
            "sub": "99% in 10 s"
          },
          {
            "id": "d-ack",
            "label": "Version reported",
            "kind": "app",
            "sub": "per instance"
          }
        ]
      },
      {
        "title": "Applied",
        "nodes": [
          {
            "id": "d-res",
            "label": "Resident snapshot",
            "kind": "store",
            "sub": "in-process"
          },
          {
            "id": "d-dec",
            "label": "Per-request decisions",
            "kind": "decision",
            "sub": "no network hop"
          }
        ]
      },
      {
        "title": "Observed",
        "nodes": [
          {
            "id": "d-acc",
            "label": "Access record",
            "kind": "queue",
            "sub": "~1 KB, sampled"
          },
          {
            "id": "d-met",
            "label": "RED metrics",
            "kind": "queue",
            "sub": "per route / tier"
          },
          {
            "id": "d-aud",
            "label": "Auth + config events",
            "kind": "queue",
            "sub": "never sampled"
          }
        ]
      },
      {
        "title": "Landed",
        "nodes": [
          {
            "id": "d-bq",
            "label": "Analytics store",
            "kind": "store",
            "sub": "2 TB/day"
          },
          {
            "id": "d-tsdb",
            "label": "Metric store",
            "kind": "store",
            "sub": "13 months"
          },
          {
            "id": "d-ledger",
            "label": "Audit ledger",
            "kind": "store",
            "sub": "immutable"
          }
        ]
      },
      {
        "title": "Used",
        "nodes": [
          {
            "id": "d-devview",
            "label": "Developer analytics",
            "kind": "app",
            "sub": "30 days"
          },
          {
            "id": "d-roll",
            "label": "Rollout scoring",
            "kind": "platform",
            "sub": "canary verdict"
          },
          {
            "id": "d-billing",
            "label": "Billing rollup",
            "kind": "external",
            "sub": "daily"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "d-roll",
        "to": "d-cfg",
        "label": "revert to N-1",
        "kind": "error",
        "route": "gutter"
      },
      {
        "from": "d-ack",
        "to": "d-roll",
        "label": "coverage",
        "kind": "async",
        "route": "gutter"
      }
    ],
    "note": "The only upward arrow on the request path is evidence. Configuration never travels up, and a request never waits on anything on this diagram except its own upstream.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "10-data-ownership-zones",
    "title": "Data Architecture — Four Classes, Four Write Rules",
    "layout": "nested",
    "canvas": {
      "width": 1780
    },
    "boxes": [
      {
        "title": "Configuration — strongly consistent, globally replicated, immutable per version",
        "kind": "trust",
        "dir": "row",
        "children": [
          {
            "title": "Written only by the Config API, under review",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-routes",
                "label": "Routes and upstreams",
                "kind": "store",
                "sub": "800 routes"
              },
              {
                "id": "z-pol",
                "label": "Policies and limits",
                "kind": "store",
                "sub": "per plan + override"
              },
              {
                "id": "z-prod",
                "label": "API products",
                "kind": "store",
                "sub": "versions, lifecycle"
              }
            ]
          },
          {
            "title": "Derived, rebuildable",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-snapo",
                "label": "Signed snapshots",
                "kind": "store",
                "sub": "object store, N and N-1"
              }
            ]
          }
        ]
      },
      {
        "title": "Credential — strongly consistent on write, eventually consistent at the edge",
        "kind": "trust",
        "dir": "row",
        "children": [
          {
            "title": "Authoritative",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-ver",
                "label": "Key verifiers",
                "kind": "store",
                "sub": "500k, no secrets"
              },
              {
                "id": "z-grant",
                "label": "Scope grants",
                "kind": "store",
                "sub": "per application"
              },
              {
                "id": "z-revoke",
                "label": "Revocation list",
                "kind": "store",
                "sub": "push source"
              }
            ]
          },
          {
            "title": "Projected to the edge",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-cache",
                "label": "Edge credential cache",
                "kind": "store",
                "sub": "5 min TTL"
              },
              {
                "id": "z-deny",
                "label": "Edge denylist",
                "kind": "store",
                "sub": "30 s propagation"
              }
            ]
          }
        ]
      },
      {
        "title": "Counter — approximate by design, bounded overshoot, loss tolerated",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "In-region, ephemeral",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-shared",
                "label": "Shared counters",
                "kind": "store",
                "sub": "sharded by principal"
              },
              {
                "id": "z-locl",
                "label": "Local buckets",
                "kind": "store",
                "sub": "per proxy instance"
              }
            ]
          },
          {
            "title": "Never authoritative for money",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-meter",
                "label": "Billable usage",
                "kind": "store",
                "sub": "from access records"
              }
            ]
          }
        ]
      },
      {
        "title": "Evidence — append-only, eventually consistent, retention by class",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "Sampled",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-acc",
                "label": "Access records",
                "kind": "store",
                "sub": "90 days"
              },
              {
                "id": "z-met",
                "label": "Aggregated metrics",
                "kind": "store",
                "sub": "13 months"
              }
            ]
          },
          {
            "title": "Never sampled",
            "kind": "plain",
            "nodes": [
              {
                "id": "z-authl",
                "label": "Auth decisions",
                "kind": "store",
                "sub": "7 years"
              },
              {
                "id": "z-cfgl",
                "label": "Config changes",
                "kind": "store",
                "sub": "7 years, immutable"
              }
            ]
          }
        ]
      }
    ],
    "outside": [
      {
        "id": "z-absent1",
        "label": "Request bodies",
        "kind": "risk",
        "sub": "deliberately not stored"
      },
      {
        "id": "z-absent2",
        "label": "Credential secrets",
        "kind": "risk",
        "sub": "never recoverable"
      },
      {
        "id": "z-absent3",
        "label": "Response payloads",
        "kind": "risk",
        "sub": "cache excepted, per route"
      }
    ],
    "edges": [
      {
        "from": "z-revoke",
        "to": "z-deny",
        "label": "push",
        "kind": "async"
      },
      {
        "from": "z-acc",
        "to": "z-meter",
        "label": "derived",
        "kind": "batch"
      }
    ],
    "note": "The three red boxes are the data this platform deliberately does not hold. A gateway that logs bodies becomes the largest breach surface in the company.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "11-data-model",
    "title": "Core Data Model",
    "layout": "er",
    "canvas": {
      "width": 1760,
      "cols": 4
    },
    "rowGap": 240,
    "entities": [
      {
        "id": "org",
        "name": "developer_org",
        "kind": "store",
        "row": 0,
        "col": 0,
        "attrs": [
          "org_id  PK",
          "tenant_id  FK",
          "plan_tier",
          "residency_set",
          "created_at"
        ]
      },
      {
        "id": "app",
        "name": "application",
        "kind": "store",
        "row": 0,
        "col": 1,
        "attrs": [
          "app_id  PK",
          "org_id  FK -> developer_org",
          "environment",
          "status"
        ]
      },
      {
        "id": "cred",
        "name": "credential",
        "kind": "store",
        "row": 0,
        "col": 2,
        "attrs": [
          "cred_id  PK",
          "app_id  FK -> application",
          "type",
          "verifier",
          "not_after",
          "revoked_at"
        ]
      },
      {
        "id": "sub",
        "name": "subscription",
        "kind": "store",
        "row": 0,
        "col": 3,
        "attrs": [
          "sub_id  PK",
          "app_id  FK -> application",
          "product_id  FK",
          "version_pin",
          "scopes"
        ]
      },
      {
        "id": "prod",
        "name": "api_product",
        "kind": "store",
        "row": 1,
        "col": 3,
        "attrs": [
          "product_id  PK",
          "name",
          "owner_team",
          "default_plan_id  FK"
        ]
      },
      {
        "id": "ver",
        "name": "api_version",
        "kind": "store",
        "row": 1,
        "col": 2,
        "attrs": [
          "version_id  PK",
          "product_id  FK -> api_product",
          "label",
          "lifecycle_state",
          "sunset_at",
          "schema_ref"
        ]
      },
      {
        "id": "route",
        "name": "route",
        "kind": "store",
        "row": 1,
        "col": 1,
        "attrs": [
          "route_id  PK",
          "version_id  FK -> api_version",
          "host",
          "path_pattern",
          "method",
          "upstream_group_id  FK"
        ]
      },
      {
        "id": "ug",
        "name": "upstream_group",
        "kind": "store",
        "row": 1,
        "col": 0,
        "attrs": [
          "group_id  PK",
          "service",
          "health_policy",
          "timeout_ms",
          "retry_budget"
        ]
      },
      {
        "id": "plan",
        "name": "plan",
        "kind": "store",
        "row": 2,
        "col": 3,
        "attrs": [
          "plan_id  PK",
          "tier",
          "burst_rps",
          "sustained_per_hour",
          "concurrency"
        ]
      },
      {
        "id": "ovr",
        "name": "limit_override",
        "kind": "store",
        "row": 2,
        "col": 2,
        "attrs": [
          "override_id  PK",
          "scope_type",
          "scope_ref",
          "plan_id  FK -> plan",
          "expires_at",
          "approver"
        ]
      },
      {
        "id": "cfg",
        "name": "config_version",
        "kind": "store",
        "row": 2,
        "col": 1,
        "attrs": [
          "config_version  PK",
          "author",
          "approved_by",
          "created_at",
          "digest",
          "parent_version"
        ]
      },
      {
        "id": "rollout",
        "name": "rollout",
        "kind": "store",
        "row": 2,
        "col": 0,
        "attrs": [
          "rollout_id  PK",
          "config_version  FK -> config_version",
          "route_id  FK",
          "weight",
          "state",
          "verdict"
        ]
      },
      {
        "id": "acc",
        "name": "access_record",
        "kind": "store",
        "row": 3,
        "col": 1,
        "attrs": [
          "request_id  PK",
          "cred_id  FK -> credential",
          "route_id  FK -> route",
          "config_version  FK",
          "status",
          "gw_latency_ms",
          "up_latency_ms"
        ]
      },
      {
        "id": "audit",
        "name": "audit_event",
        "kind": "store",
        "row": 3,
        "col": 2,
        "attrs": [
          "event_id  PK",
          "actor",
          "subject_type",
          "subject_ref",
          "action",
          "outcome",
          "at"
        ]
      }
    ],
    "relations": [
      {
        "from": "org",
        "to": "app",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "app",
        "to": "cred",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "app",
        "to": "sub",
        "label": "1 : N",
        "from_side": "n",
        "to_side": "n"
      },
      {
        "from": "prod",
        "to": "sub",
        "label": "1 : N",
        "from_side": "n",
        "to_side": "s"
      },
      {
        "from": "prod",
        "to": "ver",
        "label": "1 : N",
        "from_side": "w",
        "to_side": "e"
      },
      {
        "from": "ver",
        "to": "route",
        "label": "1 : N",
        "from_side": "w",
        "to_side": "e"
      },
      {
        "from": "ug",
        "to": "route",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "plan",
        "to": "ovr",
        "label": "1 : N",
        "from_side": "w",
        "to_side": "e"
      },
      {
        "from": "plan",
        "to": "prod",
        "label": "1 : N",
        "from_side": "n",
        "to_side": "s"
      },
      {
        "from": "cfg",
        "to": "rollout",
        "label": "1 : N",
        "from_side": "w",
        "to_side": "e"
      },
      {
        "from": "cfg",
        "to": "acc",
        "label": "1 : N",
        "from_side": "s1",
        "to_side": "n"
      },
      {
        "from": "cfg",
        "to": "audit",
        "label": "1 : N",
        "from_side": "s3",
        "to_side": "n"
      },
      {
        "from": "route",
        "to": "rollout",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      }
    ],
    "note": "credential -> access_record and credential -> audit_event are real foreign keys, omitted from the drawing to keep the lower half readable.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "12-request-lifecycle",
    "title": "A Request From TLS to Upstream",
    "layout": "sequence",
    "canvas": {
      "width": 1760
    },
    "lifelines": [
      {
        "id": "client",
        "label": "Caller",
        "kind": "external"
      },
      {
        "id": "edge",
        "label": "Global LB + Armor",
        "kind": "integration"
      },
      {
        "id": "proxy",
        "label": "Envoy proxy",
        "kind": "app"
      },
      {
        "id": "resident",
        "label": "Resident state",
        "kind": "store"
      },
      {
        "id": "counter",
        "label": "Counter store",
        "kind": "store"
      },
      {
        "id": "up",
        "label": "Upstream group",
        "kind": "app"
      },
      {
        "id": "bus",
        "label": "Usage bus",
        "kind": "queue"
      }
    ],
    "messages": [
      {
        "from": "client",
        "to": "edge",
        "label": "TLS 1.3, POST /v2/orders",
        "kind": "call"
      },
      {
        "from": "edge",
        "to": "edge",
        "label": "WAF, geo, DDoS",
        "kind": "self"
      },
      {
        "from": "edge",
        "to": "proxy",
        "label": "forward, region-local",
        "kind": "call"
      },
      {
        "from": "proxy",
        "to": "proxy",
        "label": "admit: size, headers, timeouts",
        "kind": "self"
      },
      {
        "from": "proxy",
        "to": "resident",
        "label": "verifier + denylist lookup",
        "kind": "call"
      },
      {
        "from": "resident",
        "to": "proxy",
        "label": "principal: tenant, scopes, tier",
        "kind": "return"
      },
      {
        "from": "proxy",
        "to": "proxy",
        "label": "scope check for this route",
        "kind": "self"
      },
      {
        "from": "proxy",
        "to": "counter",
        "label": "4 scopes, one round trip",
        "kind": "call"
      },
      {
        "from": "counter",
        "to": "proxy",
        "label": "allow, remaining 812",
        "kind": "return"
      },
      {
        "from": "proxy",
        "to": "resident",
        "label": "route + version + variant",
        "kind": "call"
      },
      {
        "from": "resident",
        "to": "proxy",
        "label": "v2 stable, 95% weight",
        "kind": "return"
      },
      {
        "from": "proxy",
        "to": "up",
        "label": "mTLS + signed identity header",
        "kind": "call"
      },
      {
        "from": "up",
        "to": "proxy",
        "label": "201 Created",
        "kind": "return"
      },
      {
        "from": "proxy",
        "to": "bus",
        "label": "access record, non-blocking",
        "kind": "async"
      },
      {
        "from": "proxy",
        "to": "client",
        "label": "201 + limit headers + request id",
        "kind": "return"
      }
    ],
    "note": "Two of the fifteen messages leave the pod: the counter round trip and the upstream call. Nothing on this page reaches the control plane.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "13-degradation-paths",
    "title": "Degradation Paths — What Each Dependency Failure Costs",
    "layout": "swimlane",
    "canvas": {
      "width": 1780
    },
    "laneHeaderWidth": 190,
    "stages": [
      "What fails",
      "How it is detected",
      "What the request plane does",
      "What is given up",
      "How it recovers"
    ],
    "lanes": [
      {
        "title": "Counter store",
        "cells": [
          [
            {
              "label": "Memorystore shard down",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "call timeout 5 ms",
              "kind": "app"
            }
          ],
          [
            {
              "label": "local buckets only",
              "kind": "app"
            },
            {
              "label": "ceiling tightened",
              "kind": "app"
            }
          ],
          [
            {
              "label": "limit accuracy",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "shard back, counters reset",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Credential store",
        "cells": [
          [
            {
              "label": "identity backend down",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "cache refill fails",
              "kind": "app"
            }
          ],
          [
            {
              "label": "serve on cached verifier",
              "kind": "app"
            },
            {
              "label": "write routes fail closed",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "revocation freshness",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "denylist replay on reconnect",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Control plane",
        "cells": [
          [
            {
              "label": "config API unavailable",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "snapshot poll fails",
              "kind": "app"
            }
          ],
          [
            {
              "label": "keep serving version N",
              "kind": "app"
            }
          ],
          [
            {
              "label": "the ability to change",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "resume polling, no restart",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "One upstream group",
        "cells": [
          [
            {
              "label": "all backends unhealthy",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "active health check 10 s",
              "kind": "app"
            }
          ],
          [
            {
              "label": "circuit break, fail fast",
              "kind": "app"
            },
            {
              "label": "cached response if allowed",
              "kind": "app"
            }
          ],
          [
            {
              "label": "that route only",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "half-open probe",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "A slow upstream",
        "cells": [
          [
            {
              "label": "p99 collapse, no errors",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "concurrency cap hit",
              "kind": "app"
            }
          ],
          [
            {
              "label": "shed before pool exhausts",
              "kind": "app"
            }
          ],
          [
            {
              "label": "some requests, not all callers",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "cap released on recovery",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Telemetry pipeline",
        "cells": [
          [
            {
              "label": "Pub/Sub backpressure",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "publish buffer full",
              "kind": "app"
            }
          ],
          [
            {
              "label": "sample down, then drop",
              "kind": "app"
            }
          ],
          [
            {
              "label": "evidence fidelity",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "audit events never dropped",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "A whole region",
        "cells": [
          [
            {
              "label": "region loss",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "LB health check fails",
              "kind": "app"
            }
          ],
          [
            {
              "label": "anycast withdraws region",
              "kind": "app"
            }
          ],
          [
            {
              "label": "in-flight requests only",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "re-admit after drill criteria",
              "kind": "opportunity"
            }
          ]
        ]
      }
    ],
    "note": "Every row gives up a dimension in column four. None of them gives up the front door.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "14-quota-enforcement",
    "title": "Quota Enforcement — Four Scopes, One Verdict",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Resolve",
        "nodes": [
          {
            "id": "q-princ",
            "label": "Principal",
            "kind": "app",
            "sub": "cred, app, tenant, tier"
          },
          {
            "id": "q-plan",
            "label": "Effective plan",
            "kind": "app",
            "sub": "tier + override"
          }
        ]
      },
      {
        "title": "Evaluate — all four must pass",
        "nodes": [
          {
            "id": "q-cred",
            "label": "Per credential",
            "kind": "decision",
            "sub": "burst rps"
          },
          {
            "id": "q-app",
            "label": "Per application",
            "kind": "decision",
            "sub": "sustained / hour"
          },
          {
            "id": "q-ten",
            "label": "Per tenant",
            "kind": "decision",
            "sub": "plan ceiling"
          },
          {
            "id": "q-route",
            "label": "Per route",
            "kind": "decision",
            "sub": "protects an upstream"
          }
        ]
      },
      {
        "title": "Count",
        "nodes": [
          {
            "id": "q-local",
            "label": "Local bucket",
            "kind": "store",
            "sub": "admits optimistically"
          },
          {
            "id": "q-shared",
            "label": "Shared counter",
            "kind": "store",
            "sub": "≤ 2% overshoot"
          },
          {
            "id": "q-conc",
            "label": "Concurrency slot",
            "kind": "store",
            "sub": "long-running routes"
          }
        ]
      },
      {
        "title": "Pressure test",
        "nodes": [
          {
            "id": "q-glob",
            "label": "Global overload?",
            "kind": "decision",
            "sub": "fleet saturation"
          },
          {
            "id": "q-shed",
            "label": "Tier-aware shed",
            "kind": "app",
            "sub": "free → paid → enterprise"
          }
        ]
      },
      {
        "title": "Verdict",
        "nodes": [
          {
            "id": "q-allow",
            "label": "Allow",
            "kind": "opportunity",
            "sub": "forward"
          },
          {
            "id": "q-deny",
            "label": "429 typed",
            "kind": "risk",
            "sub": "names the scope"
          }
        ]
      },
      {
        "title": "Tell the caller",
        "nodes": [
          {
            "id": "q-hdr",
            "label": "Limit headers",
            "kind": "app",
            "sub": "on every response"
          },
          {
            "id": "q-retry",
            "label": "Retry-After",
            "kind": "app",
            "sub": "computed, not guessed"
          }
        ]
      },
      {
        "title": "Account",
        "nodes": [
          {
            "id": "q-rec",
            "label": "Access record",
            "kind": "queue",
            "sub": "allows and denies"
          },
          {
            "id": "q-bill",
            "label": "Billable usage",
            "kind": "store",
            "sub": "from records, not counters"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "q-deny",
        "to": "q-rec",
        "label": "rejections counted",
        "kind": "async",
        "route": "gutter"
      },
      {
        "from": "q-shared",
        "to": "q-local",
        "label": "reconcile",
        "kind": "async"
      }
    ],
    "note": "Counters are approximate and are never the billing source. Billing is derived from access records, which are durable.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "15-revocation-propagation",
    "title": "Revoking a Leaked Credential in Under Thirty Seconds",
    "layout": "sequence",
    "canvas": {
      "width": 1760
    },
    "lifelines": [
      {
        "id": "sec",
        "label": "Security engineer",
        "kind": "actor"
      },
      {
        "id": "portal",
        "label": "Config API",
        "kind": "app"
      },
      {
        "id": "cstore",
        "label": "Credential store",
        "kind": "store"
      },
      {
        "id": "pub",
        "label": "Revocation bus",
        "kind": "queue"
      },
      {
        "id": "proxy",
        "label": "Proxy fleet",
        "kind": "app"
      },
      {
        "id": "deny",
        "label": "Edge denylist",
        "kind": "store"
      },
      {
        "id": "audit",
        "label": "Audit ledger",
        "kind": "store"
      }
    ],
    "messages": [
      {
        "from": "sec",
        "to": "portal",
        "label": "revoke cred_id",
        "kind": "call"
      },
      {
        "from": "portal",
        "to": "cstore",
        "label": "set revoked_at, strong write",
        "kind": "call"
      },
      {
        "from": "cstore",
        "to": "portal",
        "label": "committed",
        "kind": "return"
      },
      {
        "from": "portal",
        "to": "audit",
        "label": "who, what, when",
        "kind": "async"
      },
      {
        "from": "portal",
        "to": "sec",
        "label": "accepted, propagating",
        "kind": "return"
      },
      {
        "from": "cstore",
        "to": "pub",
        "label": "revocation event",
        "kind": "async"
      },
      {
        "from": "pub",
        "to": "proxy",
        "label": "fan out, every region",
        "kind": "async"
      },
      {
        "from": "proxy",
        "to": "deny",
        "label": "insert, no restart",
        "kind": "call"
      },
      {
        "from": "proxy",
        "to": "pub",
        "label": "ack with version",
        "kind": "async"
      },
      {
        "from": "pub",
        "to": "portal",
        "label": "coverage: 100% at 11 s",
        "kind": "async"
      },
      {
        "from": "proxy",
        "to": "proxy",
        "label": "next call with that key: 401",
        "kind": "self"
      },
      {
        "from": "proxy",
        "to": "audit",
        "label": "denial recorded",
        "kind": "async"
      },
      {
        "from": "pub",
        "to": "portal",
        "label": "if coverage < 100% at 60 s: page",
        "kind": "error"
      }
    ],
    "note": "Revocation is a push with a measured coverage figure, not a lookup with a consistency guarantee. The coverage number is what makes the 30 s SLO falsifiable.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "16-deployment-architecture",
    "title": "Deployment Architecture",
    "layout": "nested",
    "canvas": {
      "width": 1780
    },
    "boxes": [
      {
        "title": "Google Cloud — global",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "Anycast edge",
            "kind": "plain",
            "nodes": [
              {
                "id": "g-lb",
                "label": "Global external ALB",
                "kind": "integration",
                "sub": "one VIP"
              },
              {
                "id": "g-armor",
                "label": "Cloud Armor",
                "kind": "security",
                "sub": "edge policy"
              }
            ]
          },
          {
            "title": "Global state",
            "kind": "plain",
            "nodes": [
              {
                "id": "g-span",
                "label": "Spanner",
                "kind": "store",
                "sub": "config + credentials"
              },
              {
                "id": "g-gcs",
                "label": "Snapshot bucket",
                "kind": "store",
                "sub": "signed, dual-region"
              }
            ]
          }
        ]
      },
      {
        "title": "europe-west1 — serving",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "Zone b",
            "kind": "boundary",
            "nodes": [
              {
                "id": "e-gke1",
                "label": "GKE node pool",
                "sub": "proxy pods"
              },
              {
                "id": "e-redis1",
                "label": "Memorystore",
                "kind": "store",
                "sub": "primary"
              }
            ]
          },
          {
            "title": "Zone c",
            "kind": "boundary",
            "nodes": [
              {
                "id": "e-gke2",
                "label": "GKE node pool",
                "sub": "proxy pods"
              },
              {
                "id": "e-redis2",
                "label": "Memorystore",
                "kind": "store",
                "sub": "replica"
              }
            ]
          },
          {
            "title": "Zone d",
            "kind": "boundary",
            "nodes": [
              {
                "id": "e-gke3",
                "label": "GKE node pool",
                "sub": "headroom for one zone loss"
              }
            ]
          }
        ]
      },
      {
        "title": "us-east4 — serving",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "Zone a",
            "kind": "boundary",
            "nodes": [
              {
                "id": "u-gke1",
                "label": "GKE node pool",
                "sub": "proxy pods"
              },
              {
                "id": "u-redis1",
                "label": "Memorystore",
                "kind": "store",
                "sub": "primary"
              }
            ]
          },
          {
            "title": "Zone b",
            "kind": "boundary",
            "nodes": [
              {
                "id": "u-gke2",
                "label": "GKE node pool",
                "sub": "proxy pods"
              },
              {
                "id": "u-redis2",
                "label": "Memorystore",
                "kind": "store",
                "sub": "replica"
              }
            ]
          },
          {
            "title": "Zone c",
            "kind": "boundary",
            "nodes": [
              {
                "id": "u-gke3",
                "label": "GKE node pool",
                "sub": "headroom"
              }
            ]
          }
        ]
      },
      {
        "title": "Control plane — single logical deployment, 99.9% target",
        "kind": "trust",
        "dir": "row",
        "children": [
          {
            "title": "Management",
            "kind": "plain",
            "nodes": [
              {
                "id": "m-cfg",
                "label": "Config API",
                "kind": "app",
                "sub": "Cloud Run"
              },
              {
                "id": "m-portal",
                "label": "Developer portal",
                "kind": "app",
                "sub": "Cloud Run"
              },
              {
                "id": "m-roll",
                "label": "Rollout controller",
                "kind": "platform",
                "sub": "scores canaries"
              }
            ]
          },
          {
            "title": "Evidence",
            "kind": "plain",
            "nodes": [
              {
                "id": "m-ps",
                "label": "Pub/Sub",
                "kind": "queue",
                "sub": "usage spine"
              },
              {
                "id": "m-bq",
                "label": "BigQuery",
                "kind": "store",
                "sub": "analytics"
              },
              {
                "id": "m-log",
                "label": "Audit ledger",
                "kind": "store",
                "sub": "retention lock"
              }
            ]
          }
        ]
      }
    ],
    "outside": [
      {
        "id": "o-up",
        "label": "Upstream service estate",
        "kind": "external",
        "sub": "120 services, same regions"
      }
    ],
    "edges": [
      {
        "from": "g-gcs",
        "to": "e-gke1",
        "label": "snapshot pull",
        "kind": "async"
      },
      {
        "from": "g-span",
        "to": "g-gcs",
        "label": "publish snapshot",
        "kind": "async"
      },
      {
        "from": "u-gke1",
        "to": "m-ps",
        "label": "usage",
        "kind": "async"
      }
    ],
    "note": "Snapshot pull and usage emission are drawn once; both regions do both. Each region is sized to serve the whole global load at burst, which is what makes a 120 s evacuation a capacity decision already taken rather than one taken during the incident.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "17-config-rollout-and-canary",
    "title": "Configuration Rollout and Canary",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Author",
        "nodes": [
          {
            "id": "r-pr",
            "label": "Change in Git",
            "kind": "app",
            "sub": "routes, policies"
          },
          {
            "id": "r-rev",
            "label": "Review + approval",
            "kind": "decision",
            "sub": "second pair of eyes"
          }
        ]
      },
      {
        "title": "Validate",
        "nodes": [
          {
            "id": "r-lint",
            "label": "Schema + policy lint",
            "kind": "app",
            "sub": "CI"
          },
          {
            "id": "r-sim",
            "label": "Replay against samples",
            "kind": "app",
            "sub": "routing diff"
          }
        ]
      },
      {
        "title": "Commit",
        "nodes": [
          {
            "id": "r-ver",
            "label": "Config version N",
            "kind": "store",
            "sub": "immutable, signed"
          },
          {
            "id": "r-snap",
            "label": "Snapshot published",
            "kind": "platform",
            "sub": "N and N-1 retained"
          }
        ]
      },
      {
        "title": "Canary fleet",
        "nodes": [
          {
            "id": "r-c1",
            "label": "1 pod per region",
            "kind": "app",
            "sub": "pulls N"
          },
          {
            "id": "r-score1",
            "label": "Score 5 min",
            "kind": "decision",
            "sub": "error, p99, 5xx"
          }
        ]
      },
      {
        "title": "Canary traffic",
        "nodes": [
          {
            "id": "r-w1",
            "label": "1% → 5% → 25%",
            "kind": "app",
            "sub": "sticky per credential"
          },
          {
            "id": "r-score2",
            "label": "Rolling verdict",
            "kind": "decision",
            "sub": "halt on breach"
          }
        ]
      },
      {
        "title": "Fleet",
        "nodes": [
          {
            "id": "r-all",
            "label": "100% of pods on N",
            "kind": "app",
            "sub": "99% in 10 s"
          },
          {
            "id": "r-cov",
            "label": "Version coverage",
            "kind": "app",
            "sub": "reported per pod"
          }
        ]
      },
      {
        "title": "Revert path",
        "nodes": [
          {
            "id": "r-rb",
            "label": "Revert to N-1",
            "kind": "risk",
            "sub": "≤ 30 s, one action"
          },
          {
            "id": "r-auto",
            "label": "Auto-revert",
            "kind": "platform",
            "sub": "≤ 90 s of breach"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "r-score2",
        "to": "r-auto",
        "label": "breach",
        "kind": "error"
      },
      {
        "from": "r-auto",
        "to": "r-snap",
        "label": "pin N-1",
        "kind": "error",
        "route": "gutter"
      }
    ],
    "note": "The same pipeline promotes a routing change and an upstream canary, because both are the same artefact: a configuration version.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "18-observability",
    "title": "Observability — Signal Family by Pipeline Stage",
    "layout": "grid",
    "canvas": {
      "width": 1780
    },
    "laneHeaderWidth": 200,
    "columns": [
      "Emitted at the edge",
      "Buffered",
      "Stored",
      "Alerts on",
      "Who reads it"
    ],
    "rows": [
      {
        "title": "Traffic (RED)",
        "cells": [
          [
            {
              "label": "rate / errors / duration",
              "kind": "app"
            }
          ],
          [
            {
              "label": "in-process aggregation",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "metric store, 13 mo",
              "kind": "store"
            }
          ],
          [
            {
              "label": "SLO burn, 60 s",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "SRE + API owner",
              "kind": "actor"
            }
          ]
        ]
      },
      {
        "title": "Fault attribution",
        "cells": [
          [
            {
              "label": "gateway vs upstream code",
              "kind": "app"
            }
          ],
          [
            {
              "label": "tagged at source",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "split series",
              "kind": "store"
            }
          ],
          [
            {
              "label": "5xx we caused",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "SRE",
              "kind": "actor"
            }
          ]
        ]
      },
      {
        "title": "Policy decisions",
        "cells": [
          [
            {
              "label": "429 by scope, 401 by cause",
              "kind": "security"
            }
          ],
          [
            {
              "label": "never sampled",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "analytics + audit",
              "kind": "store"
            }
          ],
          [
            {
              "label": "denial spike per tenant",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "Security + support",
              "kind": "actor"
            }
          ]
        ]
      },
      {
        "title": "Config state",
        "cells": [
          [
            {
              "label": "resident version per pod",
              "kind": "app"
            }
          ],
          [
            {
              "label": "heartbeat",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "coverage table",
              "kind": "store"
            }
          ],
          [
            {
              "label": "split-brain > 60 s",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "Rollout controller",
              "kind": "platform"
            }
          ]
        ]
      },
      {
        "title": "Dependency health",
        "cells": [
          [
            {
              "label": "counter, cache, upstream",
              "kind": "app"
            }
          ],
          [
            {
              "label": "circuit state",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "per-dependency series",
              "kind": "store"
            }
          ],
          [
            {
              "label": "degraded mode entered",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "SRE",
              "kind": "actor"
            }
          ]
        ]
      },
      {
        "title": "Traces",
        "cells": [
          [
            {
              "label": "W3C context, originated",
              "kind": "app"
            }
          ],
          [
            {
              "label": "tail sample",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "trace store, 7 days",
              "kind": "store"
            }
          ],
          [
            {
              "label": "not alerted on",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "Whoever is debugging",
              "kind": "actor"
            }
          ]
        ]
      },
      {
        "title": "Developer-facing",
        "cells": [
          [
            {
              "label": "per-app usage + errors",
              "kind": "app"
            }
          ],
          [
            {
              "label": "same records",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "30-day window",
              "kind": "store"
            }
          ],
          [
            {
              "label": "quota near ceiling",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "The integrator",
              "kind": "actor"
            }
          ]
        ]
      },
      {
        "title": "Synthetic canary",
        "cells": [
          [
            {
              "label": "known call, every region",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "out of band",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "availability series",
              "kind": "store"
            }
          ],
          [
            {
              "label": "silence is a failure",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "SRE",
              "kind": "actor"
            }
          ]
        ]
      }
    ],
    "note": "Row three is never sampled and row seven is the same data shown to the person it is about. The last row exists so a quiet dashboard cannot be mistaken for a healthy one.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "19-api-version-lifecycle",
    "title": "The API Version Lifecycle",
    "layout": "cycle",
    "canvas": {
      "width": 1600
    },
    "centre": {
      "label": "API product",
      "sub": "outlives versions"
    },
    "nodes": [
      {
        "id": "v1",
        "label": "Preview",
        "sub": "schema published",
        "kind": "app"
      },
      {
        "id": "v2",
        "label": "General availability",
        "sub": "supported",
        "kind": "app"
      },
      {
        "id": "v3",
        "label": "Successor canaried",
        "sub": "sticky split",
        "kind": "app"
      },
      {
        "id": "v4",
        "label": "Deprecated",
        "sub": "headers + date",
        "kind": "decision"
      },
      {
        "id": "v5",
        "label": "Tail tracked",
        "sub": "callers named",
        "kind": "app"
      },
      {
        "id": "v6",
        "label": "Sunset",
        "sub": "zero callers",
        "kind": "security"
      }
    ],
    "ringLabels": [
      "promoted",
      "successor",
      "100% weight",
      "date set",
      "pins expire",
      "surface freed"
    ],
    "rx": 440,
    "ry": 225,
    "note": "The loop closes at the centre: the product persists, versions do not. A sunset is reached by evidence of zero callers, or by a recorded override with a name on it.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "20-security-trust-zones",
    "title": "Security Trust Zones — Where Trust Is Established",
    "layout": "zones",
    "canvas": {
      "width": 1780
    },
    "zones": [
      {
        "title": "Internet — nothing here is trusted",
        "kind": "trust",
        "nodes": [
          {
            "id": "s-caller",
            "label": "Any caller",
            "kind": "external",
            "sub": "credential unverified"
          },
          {
            "id": "s-hostile",
            "label": "Hostile traffic",
            "kind": "risk",
            "sub": "flood, stuffing"
          },
          {
            "id": "s-leaked",
            "label": "Leaked credential",
            "kind": "risk",
            "sub": "valid until revoked"
          }
        ]
      },
      {
        "title": "Edge zone — absorbs, does not authenticate",
        "kind": "trust",
        "nodes": [
          {
            "id": "s-lb",
            "label": "Global LB",
            "kind": "integration",
            "sub": "TLS ends here"
          },
          {
            "id": "s-armor",
            "label": "Cloud Armor",
            "kind": "security",
            "sub": "WAF, rate, geo"
          },
          {
            "id": "s-conn",
            "label": "Connection limits",
            "kind": "app",
            "sub": "before policy"
          }
        ]
      },
      {
        "title": "Policy zone — the trust boundary itself",
        "kind": "trust",
        "nodes": [
          {
            "id": "s-authn",
            "label": "Authentication",
            "kind": "security",
            "sub": "key / token / mTLS"
          },
          {
            "id": "s-deny",
            "label": "Denylist check",
            "kind": "security",
            "sub": "30 s SLO"
          },
          {
            "id": "s-authz",
            "label": "Scope authorisation",
            "kind": "security",
            "sub": "per route"
          },
          {
            "id": "s-strip",
            "label": "Header strip + sign",
            "kind": "security",
            "sub": "client identity discarded"
          }
        ]
      },
      {
        "title": "Service zone — trusts the signed context and nothing else",
        "kind": "trust",
        "nodes": [
          {
            "id": "s-up",
            "label": "Upstream services",
            "sub": "mTLS peer"
          },
          {
            "id": "s-sand",
            "label": "Sandbox estate",
            "sub": "separate project"
          }
        ]
      },
      {
        "title": "Management zone — no path from the internet",
        "kind": "trust",
        "nodes": [
          {
            "id": "s-cfg",
            "label": "Config API",
            "kind": "app",
            "sub": "RBAC + approval"
          },
          {
            "id": "s-cred",
            "label": "Credential store",
            "kind": "store",
            "sub": "verifiers only"
          },
          {
            "id": "s-aud",
            "label": "Audit ledger",
            "kind": "store",
            "sub": "append-only"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "s-caller",
        "to": "s-lb",
        "label": "TLS 1.2 / 1.3",
        "kind": "sync"
      },
      {
        "from": "s-hostile",
        "to": "s-armor",
        "label": "absorbed",
        "kind": "error"
      },
      {
        "from": "s-lb",
        "to": "s-authn",
        "label": "unauthenticated",
        "kind": "sync"
      },
      {
        "from": "s-leaked",
        "to": "s-deny",
        "label": "denied",
        "kind": "error"
      },
      {
        "from": "s-strip",
        "to": "s-up",
        "label": "mTLS + signed identity",
        "kind": "sync"
      },
      {
        "from": "s-authn",
        "to": "s-cred",
        "label": "cache refill only",
        "kind": "async"
      },
      {
        "from": "s-authz",
        "to": "s-aud",
        "label": "allow and deny",
        "kind": "async"
      },
      {
        "from": "s-cfg",
        "to": "s-aud",
        "label": "every change",
        "kind": "async"
      }
    ],
    "note": "Raw client credentials never cross into the service zone, and no arrow enters the management zone from the left.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "21-identity-and-authorisation",
    "title": "Identity and Authorisation — What Gets Refused",
    "layout": "sequence",
    "canvas": {
      "width": 1760
    },
    "lifelines": [
      {
        "id": "caller",
        "label": "Caller",
        "kind": "external"
      },
      {
        "id": "proxy",
        "label": "Proxy",
        "kind": "app"
      },
      {
        "id": "cache",
        "label": "Credential cache",
        "kind": "store"
      },
      {
        "id": "authsrv",
        "label": "Authorisation server",
        "kind": "security"
      },
      {
        "id": "up",
        "label": "Upstream",
        "kind": "app"
      },
      {
        "id": "audit",
        "label": "Audit ledger",
        "kind": "store"
      }
    ],
    "messages": [
      {
        "from": "caller",
        "to": "proxy",
        "label": "Bearer token, POST /v2/payouts",
        "kind": "call"
      },
      {
        "from": "proxy",
        "to": "proxy",
        "label": "verify signature, iss, aud, exp",
        "kind": "self"
      },
      {
        "from": "proxy",
        "to": "cache",
        "label": "denylist + grants for jti",
        "kind": "call"
      },
      {
        "from": "cache",
        "to": "proxy",
        "label": "miss",
        "kind": "return"
      },
      {
        "from": "proxy",
        "to": "authsrv",
        "label": "introspect (cache refill)",
        "kind": "call"
      },
      {
        "from": "authsrv",
        "to": "proxy",
        "label": "scopes: payouts.read",
        "kind": "return"
      },
      {
        "from": "proxy",
        "to": "proxy",
        "label": "route requires payouts.write",
        "kind": "self"
      },
      {
        "from": "proxy",
        "to": "audit",
        "label": "denied: insufficient_scope",
        "kind": "async"
      },
      {
        "from": "proxy",
        "to": "caller",
        "label": "403 + required scope named",
        "kind": "error"
      },
      {
        "from": "caller",
        "to": "proxy",
        "label": "retry with correct token",
        "kind": "call"
      },
      {
        "from": "proxy",
        "to": "cache",
        "label": "hit, scopes sufficient",
        "kind": "call"
      },
      {
        "from": "proxy",
        "to": "up",
        "label": "signed identity: tenant, app, scopes",
        "kind": "call"
      },
      {
        "from": "up",
        "to": "proxy",
        "label": "202 Accepted",
        "kind": "return"
      },
      {
        "from": "proxy",
        "to": "audit",
        "label": "allowed, recorded",
        "kind": "async"
      }
    ],
    "note": "The refusal is the point of the page: a 403 that names the scope it wanted is the difference between a support ticket and a fix.",
    "meta": {
      "v": "1.0",
      "owner": "Integration Platform Architecture",
      "date": "2026-09"
    }
  }
]
