[
  {
    "id": "01-system-context",
    "title": "Consent & Privacy Service — System Context",
    "layout": "context",
    "canvas": {
      "width": 1720
    },
    "system": {
      "label": "Consent & Privacy Service",
      "sub": "Permission, rights, evidence"
    },
    "groups": [
      {
        "side": "left",
        "title": "People who act",
        "nodes": [
          {
            "id": "subject",
            "label": "Data subject",
            "kind": "actor",
            "sub": "180 M registered",
            "rel": "grants, withdraws, requests",
            "dir": "in"
          },
          {
            "id": "agent",
            "label": "Support agent",
            "kind": "actor",
            "sub": "case-bound access",
            "rel": "acts on request",
            "dir": "in"
          },
          {
            "id": "dpo",
            "label": "Privacy officer",
            "kind": "actor",
            "sub": "one per jurisdiction",
            "rel": "evidence, findings",
            "dir": "in"
          }
        ]
      },
      {
        "side": "right",
        "title": "First-party systems (40)",
        "nodes": [
          {
            "id": "product",
            "label": "Product services",
            "kind": "external",
            "sub": "decision on read path",
            "rel": "asks a decision"
          },
          {
            "id": "mktg",
            "label": "Marketing platform",
            "kind": "external",
            "sub": "campaign eligibility",
            "rel": "withdrawal feed",
            "kind2": "async"
          },
          {
            "id": "warehouse",
            "label": "Analytics warehouse",
            "kind": "external",
            "sub": "derived data",
            "rel": "suppression list",
            "kind2": "batch"
          },
          {
            "id": "ml",
            "label": "Feature store & models",
            "kind": "external",
            "sub": "re-derived on erasure",
            "rel": "rebuild trigger",
            "kind2": "async"
          }
        ]
      },
      {
        "side": "top",
        "title": "Governance",
        "nodes": [
          {
            "id": "owner",
            "label": "Purpose owner",
            "kind": "actor",
            "sub": "40 product teams",
            "rel": "declares purposes",
            "dir": "in"
          },
          {
            "id": "legal",
            "label": "Legal & privacy counsel",
            "kind": "actor",
            "sub": "approves the basis",
            "rel": "approves basis",
            "dir": "in"
          }
        ]
      },
      {
        "side": "bottom",
        "title": "Outside the company",
        "nodes": [
          {
            "id": "proc",
            "label": "Processors",
            "kind": "external",
            "sub": "60 recipients",
            "rel": "erasure",
            "kind2": "async"
          },
          {
            "id": "manual",
            "label": "Manual recipients",
            "kind": "external",
            "sub": "no API",
            "rel": "manual, tracked",
            "kind2": "batch"
          },
          {
            "id": "reg",
            "label": "Supervisory authority",
            "kind": "external",
            "sub": "3 jurisdictions",
            "rel": "requests evidence",
            "dir": "in"
          }
        ]
      }
    ],
    "note": "Out of scope: storing personal data itself, authentication, campaign execution, the banner's front-end.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture",
      "date": "2026-10"
    }
  },
  {
    "id": "02-high-level-architecture",
    "title": "Consent & Privacy Service — High-Level Architecture",
    "layout": "flow",
    "canvas": {
      "width": 1760
    },
    "chain": true,
    "align": "middle",
    "stages": [
      {
        "title": "Declare",
        "nodes": [
          {
            "id": "registry",
            "label": "Purpose registry",
            "kind": "platform",
            "sub": "Aurora Global"
          },
          {
            "id": "approval",
            "label": "Two-person approval",
            "kind": "decision"
          }
        ]
      },
      {
        "title": "Capture",
        "nodes": [
          {
            "id": "sdk",
            "label": "Consent SDK",
            "kind": "app",
            "sub": "web, iOS, Android"
          },
          {
            "id": "capture",
            "label": "Capture service",
            "kind": "app",
            "sub": "Fargate"
          },
          {
            "id": "ledger",
            "label": "Consent ledger",
            "kind": "store",
            "sub": "DynamoDB, append-only"
          }
        ]
      },
      {
        "title": "Decide",
        "nodes": [
          {
            "id": "proj",
            "label": "Current-state projection",
            "kind": "store",
            "sub": "rebuildable"
          },
          {
            "id": "decision",
            "label": "Decision API",
            "kind": "integration",
            "sub": "p99 10 ms"
          },
          {
            "id": "cache",
            "label": "In-process cache",
            "kind": "app",
            "sub": "last-known-good"
          }
        ]
      },
      {
        "title": "Act",
        "nodes": [
          {
            "id": "stream",
            "label": "Withdrawal stream",
            "kind": "queue",
            "sub": "EventBridge"
          },
          {
            "id": "cases",
            "label": "Case orchestrator",
            "kind": "app",
            "sub": "Step Functions"
          },
          {
            "id": "supp",
            "label": "Suppression list",
            "kind": "store",
            "sub": "consulted on ingest"
          }
        ]
      },
      {
        "title": "Prove",
        "nodes": [
          {
            "id": "prober",
            "label": "Verification prober",
            "kind": "app",
            "sub": "sampled absence"
          },
          {
            "id": "evidence",
            "label": "Evidence store",
            "kind": "store",
            "sub": "S3 Object Lock"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "registry",
        "to": "decision",
        "label": "policy bundle",
        "kind": "batch",
        "route": "gutter"
      },
      {
        "from": "ledger",
        "to": "proj",
        "label": "streams"
      },
      {
        "from": "ledger",
        "to": "stream",
        "label": "withdrawal",
        "kind": "async"
      },
      {
        "from": "cases",
        "to": "prober",
        "kind": "async"
      }
    ],
    "note": "The seam the set is about sits between Decide and Act: the platform knows the permission, other systems hold the data.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "03-actors-and-journeys",
    "title": "Actors and Their Core Journeys",
    "layout": "actors",
    "canvas": {
      "width": 1760
    },
    "groups": [
      {
        "title": "People whose data it is",
        "kind": "boundary",
        "actors": [
          {
            "id": "a-subject",
            "label": "Everyday user",
            "sub": "180 M registered",
            "goal": "When I say stop, I want it to actually stop — everywhere, not just on the screen where I said it.",
            "journeys": [
              {
                "id": "j-withdraw",
                "label": "Withdraw a consent"
              },
              {
                "id": "j-erase",
                "label": "Delete my account"
              },
              {
                "label": "Download my data"
              }
            ]
          },
          {
            "id": "a-visitor",
            "label": "Visitor, not signed in",
            "sub": "pre-identity",
            "goal": "I should be able to refuse before anyone knows who I am, and have that refusal survive signing in.",
            "journeys": [
              {
                "label": "Refuse before signing in"
              }
            ]
          }
        ]
      },
      {
        "title": "People accountable for it",
        "kind": "boundary",
        "actors": [
          {
            "id": "a-dpo",
            "label": "Privacy officer",
            "sub": "3 jurisdictions",
            "goal": "Prove what we were allowed to do on a given day without asking six teams and hoping.",
            "journeys": [
              {
                "id": "j-evidence",
                "label": "Answer a regulator"
              }
            ]
          },
          {
            "id": "a-owner",
            "label": "Purpose owner",
            "sub": "40 product teams",
            "goal": "Ship a new use of data without becoming the reason we are fined.",
            "journeys": [
              {
                "label": "Register a purpose"
              },
              {
                "label": "See my purpose's cost"
              }
            ]
          },
          {
            "id": "a-agent",
            "label": "Support agent",
            "sub": "case-bound, time-boxed",
            "goal": "Act on what the caller is asking for without being shown their whole life.",
            "journeys": [
              {
                "label": "Raise a case for a caller"
              }
            ]
          }
        ]
      },
      {
        "title": "Machines and third parties",
        "kind": "cloud",
        "actors": [
          {
            "id": "a-svc",
            "label": "Product service",
            "kind": "external",
            "sub": "40 integrated",
            "goal": "Tell me yes or no in under ten milliseconds, and never make me guess when you cannot.",
            "journeys": [
              {
                "label": "Ask for a decision"
              }
            ]
          },
          {
            "id": "a-proc",
            "label": "Processor",
            "kind": "external",
            "sub": "60 recipients",
            "goal": "Send me one instruction I can act on, and tell me exactly what you expect back.",
            "journeys": [
              {
                "label": "Act on an erasure instruction"
              }
            ]
          },
          {
            "id": "a-reg",
            "label": "Supervisory authority",
            "kind": "external",
            "sub": "statutory deadlines",
            "goal": "Show me the record as it stood, not a reconstruction assembled after my letter arrived.",
            "journeys": [
              {
                "label": "Request the evidence pack"
              }
            ]
          }
        ]
      }
    ],
    "note": "Three of these actors want the platform to say no. That is the product.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "04-journey-withdraw-a-consent",
    "title": "Journey — Withdraw a Consent",
    "layout": "journey",
    "canvas": {
      "width": 1700
    },
    "actor": {
      "label": "Everyday user",
      "sub": "mobile, 40 seconds of patience",
      "goal": "Stop the thing I just refused",
      "trigger": "An advert that felt far too accurate",
      "success": "It stops, and I can see for myself that it stopped"
    },
    "phases": [
      {
        "title": "Notice",
        "sub": "outside the app"
      },
      {
        "title": "Refuse"
      },
      {
        "title": "Doubt",
        "moment": true
      },
      {
        "title": "Verify"
      },
      {
        "title": "Live with it"
      }
    ],
    "lanes": [
      {
        "title": "What they do",
        "kind": "step",
        "cells": [
          [
            {
              "label": "Sees the advert"
            }
          ],
          [
            {
              "label": "Opens preferences"
            },
            {
              "label": "Toggles it off"
            }
          ],
          [
            {
              "label": "Waits"
            }
          ],
          [
            {
              "label": "Checks it took"
            }
          ],
          [
            {
              "label": "Reopens the app"
            }
          ]
        ]
      },
      {
        "title": "What the platform does",
        "kind": "system",
        "cells": [
          [],
          [
            {
              "label": "Ledger entry written"
            },
            {
              "label": "Receipt returned"
            }
          ],
          [
            {
              "label": "Stream fans out"
            }
          ],
          [
            {
              "label": "Decision returns DENY"
            }
          ],
          [
            {
              "label": "Processors instructed"
            }
          ]
        ]
      },
      {
        "title": "How it feels",
        "kind": "emotion",
        "levels": [
          "Reassured",
          "Neutral",
          "Suspicious"
        ],
        "points": [
          0,
          1,
          0,
          1,
          2
        ]
      },
      {
        "title": "Where it hurts",
        "kind": "pain",
        "cells": [
          [],
          [],
          [
            {
              "label": "Nothing visibly changes"
            }
          ],
          [
            {
              "label": "No sign vendors were told"
            }
          ],
          []
        ]
      },
      {
        "title": "What answers it",
        "kind": "gain",
        "cells": [
          [],
          [
            {
              "label": "Withdrawal as easy as grant"
            }
          ],
          [
            {
              "label": "Published 15 min ceiling"
            }
          ],
          [
            {
              "label": "Receipt names version + time"
            }
          ],
          [
            {
              "label": "Per-recipient status shown"
            }
          ]
        ]
      }
    ],
    "chain": true,
    "note": "The trough is the gap between the toggle and any visible consequence. The design answer is a receipt and a published ceiling, not a faster fan-out.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "05-journey-delete-my-account",
    "title": "Journey — Delete My Account",
    "layout": "journey",
    "canvas": {
      "width": 1700
    },
    "actor": {
      "label": "Departing user",
      "sub": "has already decided",
      "goal": "Be gone, and be told when it is actually done",
      "trigger": "Switching to a competitor, or one bad experience too many",
      "success": "A confirmation naming what was deleted and what legally stays"
    },
    "phases": [
      {
        "title": "Decide"
      },
      {
        "title": "Prove who I am"
      },
      {
        "title": "Wait",
        "moment": true
      },
      {
        "title": "Hear back"
      },
      {
        "title": "Stay gone",
        "moment": true
      }
    ],
    "lanes": [
      {
        "title": "What they do",
        "kind": "step",
        "cells": [
          [
            {
              "label": "Taps delete account"
            }
          ],
          [
            {
              "label": "Completes step-up"
            }
          ],
          [],
          [
            {
              "label": "Reads the outcome"
            }
          ],
          [
            {
              "label": "Watches their inbox"
            }
          ]
        ]
      },
      {
        "title": "What the platform does",
        "kind": "system",
        "cells": [
          [
            {
              "label": "Case opened"
            }
          ],
          [
            {
              "label": "Identifiers resolved"
            }
          ],
          [
            {
              "label": "Fan-out to 100 targets"
            }
          ],
          [
            {
              "label": "Attestations collected"
            }
          ],
          [
            {
              "label": "Suppression list holds"
            }
          ]
        ]
      },
      {
        "title": "How it feels",
        "kind": "emotion",
        "levels": [
          "Satisfied",
          "Uneasy",
          "Angry"
        ],
        "points": [
          1,
          1,
          0,
          2,
          2
        ]
      },
      {
        "title": "Where it hurts",
        "kind": "pain",
        "cells": [
          [],
          [
            {
              "label": "ID asked to be forgotten"
            }
          ],
          [
            {
              "label": "Days of silence"
            }
          ],
          [
            {
              "label": "Some data legally kept"
            }
          ],
          [
            {
              "label": "A vendor emails anyway"
            }
          ]
        ]
      },
      {
        "title": "What answers it",
        "kind": "gain",
        "cells": [
          [],
          [
            {
              "label": "Proportionate verification"
            }
          ],
          [
            {
              "label": "Acknowledged in 24 h"
            }
          ],
          [
            {
              "label": "Plain-language refusals"
            }
          ],
          [
            {
              "label": "Probing finds the vendor"
            }
          ]
        ]
      }
    ],
    "chain": true,
    "note": "Every phase after the second is somebody else's system behaving. That is why erasure is a protocol with four states rather than a call with a return code.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "06-journey-answer-a-regulator",
    "title": "Journey — Answer a Regulator",
    "layout": "journey",
    "canvas": {
      "width": 1700
    },
    "actor": {
      "label": "Privacy officer",
      "sub": "statutory clock running",
      "goal": "Answer in days, with evidence rather than a narrative",
      "trigger": "A subject complaint, or a routine audit letter",
      "success": "A pack accepted without a follow-up request"
    },
    "phases": [
      {
        "title": "Receive"
      },
      {
        "title": "Reconstruct",
        "moment": true
      },
      {
        "title": "Assemble"
      },
      {
        "title": "Respond"
      },
      {
        "title": "Fix"
      }
    ],
    "lanes": [
      {
        "title": "What they do",
        "kind": "step",
        "cells": [
          [
            {
              "label": "Reads the letter"
            }
          ],
          [
            {
              "label": "Asks for one date"
            }
          ],
          [
            {
              "label": "Reviews the pack"
            }
          ],
          [
            {
              "label": "Sends the response"
            }
          ],
          [
            {
              "label": "Closes the finding"
            }
          ]
        ]
      },
      {
        "title": "What the platform does",
        "kind": "system",
        "cells": [
          [
            {
              "label": "Evidence case opened"
            }
          ],
          [
            {
              "label": "Ledger replayed at T"
            }
          ],
          [
            {
              "label": "Notice text attached"
            }
          ],
          [
            {
              "label": "Signed pack exported"
            }
          ],
          [
            {
              "label": "Finding routed to owner"
            }
          ]
        ]
      },
      {
        "title": "How it feels",
        "kind": "emotion",
        "levels": [
          "Confident",
          "Tense",
          "Exposed"
        ],
        "points": [
          1,
          0,
          1,
          2,
          1
        ]
      },
      {
        "title": "Where it hurts",
        "kind": "pain",
        "cells": [
          [],
          [
            {
              "label": "Notice text never stored"
            }
          ],
          [
            {
              "label": "Six teams asked by hand"
            }
          ],
          [],
          [
            {
              "label": "Same gap next quarter"
            }
          ]
        ]
      },
      {
        "title": "What answers it",
        "kind": "gain",
        "cells": [
          [],
          [
            {
              "label": "Notice version on each entry"
            }
          ],
          [
            {
              "label": "One subject, one date, one query"
            }
          ],
          [
            {
              "label": "Tamper-evident export"
            }
          ],
          [
            {
              "label": "Findings have named owners"
            }
          ]
        ]
      }
    ],
    "chain": true,
    "note": "The trough is reconstruction. Storing the notice version with every ledger entry is what removes it, and it costs nothing at capture time.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "07-layered-architecture",
    "title": "Layered Architecture",
    "layout": "bands",
    "canvas": {
      "width": 1740
    },
    "layerHeaderWidth": 160,
    "bands": [
      {
        "name": "Surfaces",
        "nodes": [
          {
            "id": "l-banner",
            "label": "Consent banner",
            "kind": "app"
          },
          {
            "id": "l-pref",
            "label": "Preference centre",
            "kind": "app"
          },
          {
            "id": "l-portal",
            "label": "Rights portal",
            "kind": "app"
          },
          {
            "id": "l-console",
            "label": "Agent console",
            "kind": "app"
          },
          {
            "id": "l-svc",
            "label": "Product service SDK",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Edge & API",
        "nodes": [
          {
            "id": "l-cdn",
            "label": "CloudFront + WAF",
            "kind": "integration"
          },
          {
            "id": "l-apigw",
            "label": "API Gateway",
            "kind": "integration"
          },
          {
            "id": "l-authn",
            "label": "Subject authn & step-up",
            "kind": "security"
          },
          {
            "id": "l-juris",
            "label": "Jurisdiction router",
            "kind": "platform"
          }
        ]
      },
      {
        "name": "Ledger (SoR)",
        "nodes": [
          {
            "id": "l-ledger",
            "label": "Consent ledger",
            "kind": "store",
            "sub": "append-only"
          },
          {
            "id": "l-idx",
            "label": "Identity resolution index",
            "kind": "store"
          }
        ]
      },
      {
        "name": "Projection",
        "nodes": [
          {
            "id": "l-proj",
            "label": "Current state",
            "kind": "store"
          },
          {
            "id": "l-snap",
            "label": "Batch snapshot",
            "kind": "store"
          },
          {
            "id": "l-builder",
            "label": "Projection builder",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Decision",
        "nodes": [
          {
            "id": "l-api",
            "label": "Decision API",
            "kind": "integration"
          },
          {
            "id": "l-cache",
            "label": "Last-known-good cache",
            "kind": "app"
          },
          {
            "id": "l-batch",
            "label": "Batch evaluator",
            "kind": "app"
          },
          {
            "id": "l-stream",
            "label": "Withdrawal stream",
            "kind": "queue"
          }
        ]
      },
      {
        "name": "Rights",
        "nodes": [
          {
            "id": "l-intake",
            "label": "Case intake",
            "kind": "app"
          },
          {
            "id": "l-orch",
            "label": "Case orchestrator",
            "kind": "app"
          },
          {
            "id": "l-resolve",
            "label": "Identity resolver",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Propagation",
        "nodes": [
          {
            "id": "l-first",
            "label": "First-party adapters",
            "kind": "integration",
            "sub": "40"
          },
          {
            "id": "l-recip",
            "label": "Recipient adapters",
            "kind": "integration",
            "sub": "60"
          },
          {
            "id": "l-supp",
            "label": "Suppression list",
            "kind": "store"
          },
          {
            "id": "l-probe",
            "label": "Absence prober",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Evidence",
        "nodes": [
          {
            "id": "l-audit",
            "label": "Tamper-evident audit",
            "kind": "store"
          },
          {
            "id": "l-replay",
            "label": "Point-in-time replay",
            "kind": "app"
          },
          {
            "id": "l-ropa",
            "label": "Records of processing",
            "kind": "app"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "l-ledger",
        "to": "l-builder",
        "label": "streams"
      },
      {
        "from": "l-proj",
        "to": "l-api"
      },
      {
        "from": "l-api",
        "to": "l-cache",
        "label": "snapshot + version",
        "kind": "async"
      },
      {
        "from": "l-orch",
        "to": "l-first",
        "label": "instruction",
        "kind": "async"
      }
    ],
    "note": "Layers 3 to 8 are repeated per jurisdiction. Only the purpose registry, which holds no personal data, is global.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "08-platform-components",
    "title": "Platform Components — Regional Plane and Global Control Plane",
    "layout": "nested",
    "canvas": {
      "width": 1740
    },
    "boxes": [
      {
        "title": "Global control plane — no personal data",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "Registry",
            "kind": "boundary",
            "nodes": [
              {
                "id": "c-purpose",
                "label": "Purpose registry",
                "kind": "platform",
                "sub": "Aurora Global"
              },
              {
                "id": "c-notice",
                "label": "Notice text & translations",
                "kind": "store"
              }
            ]
          },
          {
            "title": "Change control",
            "kind": "boundary",
            "nodes": [
              {
                "id": "c-approve",
                "label": "Approval workflow",
                "kind": "security",
                "sub": "two-person"
              },
              {
                "id": "c-bundle",
                "label": "Signed policy bundle",
                "kind": "store",
                "sub": "S3 + CloudFront"
              }
            ]
          }
        ]
      },
      {
        "title": "Regional plane — eu-west-1 (repeated per jurisdiction)",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "Capture & ledger",
            "kind": "boundary",
            "nodes": [
              {
                "id": "c-capture",
                "label": "Capture service",
                "kind": "app"
              },
              {
                "id": "c-ledger",
                "label": "Consent ledger",
                "kind": "store",
                "sub": "DynamoDB"
              },
              {
                "id": "c-builder",
                "label": "Projection builder",
                "kind": "app"
              },
              {
                "id": "c-proj",
                "label": "Current state",
                "kind": "store"
              }
            ]
          },
          {
            "title": "Decision",
            "kind": "boundary",
            "nodes": [
              {
                "id": "c-api",
                "label": "Decision API",
                "kind": "integration"
              },
              {
                "id": "c-stream",
                "label": "Withdrawal stream",
                "kind": "queue"
              },
              {
                "id": "c-batch",
                "label": "Batch evaluator",
                "kind": "app"
              }
            ]
          },
          {
            "title": "Rights & propagation",
            "kind": "boundary",
            "nodes": [
              {
                "id": "c-orch",
                "label": "Case orchestrator",
                "kind": "app",
                "sub": "Step Functions"
              },
              {
                "id": "c-idx",
                "label": "Identity index",
                "kind": "store",
                "sub": "per-subject keys"
              },
              {
                "id": "c-adapt",
                "label": "Target adapters",
                "kind": "integration",
                "sub": "100"
              },
              {
                "id": "c-supp",
                "label": "Suppression list",
                "kind": "store"
              }
            ]
          },
          {
            "title": "Evidence",
            "kind": "trust",
            "nodes": [
              {
                "id": "c-audit",
                "label": "Audit store",
                "kind": "store",
                "sub": "Object Lock"
              },
              {
                "id": "c-kms",
                "label": "Per-subject keys",
                "kind": "security",
                "sub": "KMS"
              }
            ]
          }
        ]
      }
    ],
    "outside": [
      {
        "id": "c-product",
        "label": "Product services",
        "kind": "external",
        "sub": "40, in-process cache"
      },
      {
        "id": "c-recip",
        "label": "Processors",
        "kind": "external",
        "sub": "60"
      }
    ],
    "edges": [
      {
        "from": "c-bundle",
        "to": "c-api",
        "label": "policy",
        "kind": "batch"
      },
      {
        "from": "c-stream",
        "to": "c-product",
        "label": "withdrawal",
        "kind": "async"
      },
      {
        "from": "c-adapt",
        "to": "c-recip",
        "label": "erasure",
        "kind": "async"
      }
    ],
    "note": "The regional plane serves its jurisdiction with the global plane unreachable. There is no cross-jurisdiction failover, by design.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "09-interface-catalogue",
    "title": "Interface Catalogue",
    "layout": "hub",
    "canvas": {
      "width": 1700
    },
    "left": {
      "title": "In",
      "nodes": [
        {
          "id": "i-capture",
          "label": "Capture a decision",
          "kind": "integration",
          "rel": "subjects"
        },
        {
          "id": "i-decide",
          "label": "Evaluate a decision",
          "kind": "integration",
          "rel": "services"
        },
        {
          "id": "i-rights",
          "label": "Raise a rights case",
          "kind": "integration",
          "rel": "portal"
        }
      ]
    },
    "centre": {
      "title": "Consent & Privacy Service",
      "nodes": [
        {
          "id": "h-core",
          "label": "Permission & rights plane",
          "kind": "app",
          "sub": "one contract each way"
        }
      ]
    },
    "right": {
      "title": "Out",
      "nodes": [
        {
          "id": "o-withdraw",
          "label": "Withdrawal events",
          "kind": "queue",
          "rel": "events",
          "dir": "out",
          "kind2": "async"
        },
        {
          "id": "o-instruct",
          "label": "Erasure instruction",
          "kind": "integration",
          "rel": "targets",
          "dir": "out",
          "kind2": "async"
        },
        {
          "id": "o-supp",
          "label": "Suppression feed",
          "kind": "store",
          "rel": "ingest",
          "dir": "out",
          "kind2": "batch"
        }
      ]
    },
    "note": "Three surfaces each way. Two further contracts are drawn where they are decided rather than here: purpose declaration in the release path, evidence export in the failure-class view.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "10-decision-and-withdrawal-flow",
    "title": "Data Flow — From a Toggle to a Denied Read",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": true,
    "align": "middle",
    "stages": [
      {
        "title": "Capture",
        "nodes": [
          {
            "id": "f-toggle",
            "label": "Subject toggles off",
            "kind": "actor"
          },
          {
            "id": "f-capture",
            "label": "Capture service",
            "kind": "app",
            "sub": "validates purpose"
          }
        ]
      },
      {
        "title": "Commit",
        "nodes": [
          {
            "id": "f-ledger",
            "label": "Ledger entry",
            "kind": "store",
            "sub": "durable before ack"
          },
          {
            "id": "f-receipt",
            "label": "Receipt to subject",
            "kind": "app",
            "sub": "version + time"
          }
        ]
      },
      {
        "title": "Derive",
        "nodes": [
          {
            "id": "f-builder",
            "label": "Projection builder",
            "kind": "app",
            "sub": "streams"
          },
          {
            "id": "f-proj",
            "label": "Current state",
            "kind": "store"
          }
        ]
      },
      {
        "title": "Distribute",
        "nodes": [
          {
            "id": "f-stream",
            "label": "Withdrawal event",
            "kind": "queue",
            "sub": "EventBridge"
          },
          {
            "id": "f-cache",
            "label": "In-process caches",
            "kind": "app",
            "sub": "40 services"
          }
        ]
      },
      {
        "title": "Enforce",
        "nodes": [
          {
            "id": "f-read",
            "label": "Product read path",
            "kind": "external",
            "sub": "asks before use"
          },
          {
            "id": "f-deny",
            "label": "DENY + version",
            "kind": "decision"
          }
        ]
      },
      {
        "title": "Prove",
        "nodes": [
          {
            "id": "f-lag",
            "label": "Propagation lag metric",
            "kind": "platform",
            "sub": "per enforcement point"
          },
          {
            "id": "f-audit",
            "label": "Audit entry",
            "kind": "store"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "f-ledger",
        "to": "f-audit",
        "kind": "async",
        "route": "gutter"
      },
      {
        "from": "f-stream",
        "to": "f-lag",
        "kind": "async"
      }
    ],
    "note": "The receipt is issued at Commit, before anything has propagated. It states the version and time, which is the only honest thing to say at that moment.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "11-state-classes",
    "title": "State Classes — Ordered by What Happens If It Is Lost",
    "layout": "nested",
    "canvas": {
      "width": 1720
    },
    "boxes": [
      {
        "title": "Irreplaceable — RPO 0, never rebuilt",
        "kind": "trust",
        "dir": "row",
        "children": [
          {
            "title": "Consent ledger",
            "kind": "boundary",
            "nodes": [
              {
                "id": "s-ledger",
                "label": "Decision entries",
                "kind": "store",
                "sub": "7 yr, append-only"
              }
            ]
          },
          {
            "title": "Evidence",
            "kind": "boundary",
            "nodes": [
              {
                "id": "s-audit",
                "label": "Audit records",
                "kind": "store",
                "sub": "write-once"
              },
              {
                "id": "s-closed",
                "label": "Case outcomes",
                "kind": "store",
                "sub": "3 yr"
              }
            ]
          },
          {
            "title": "Keys",
            "kind": "boundary",
            "nodes": [
              {
                "id": "s-keys",
                "label": "Per-subject data keys",
                "kind": "security",
                "sub": "loss = erasure"
              }
            ]
          }
        ]
      },
      {
        "title": "Reconstructible — rebuilt from the ledger at 20x real time",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "Derived reads",
            "kind": "plain",
            "nodes": [
              {
                "id": "s-proj",
                "label": "Current state",
                "kind": "store",
                "sub": "RPO 60 s"
              },
              {
                "id": "s-snap",
                "label": "Batch snapshot",
                "kind": "store"
              },
              {
                "id": "s-cache",
                "label": "Enforcement caches",
                "kind": "app",
                "sub": "RPO n/a"
              }
            ]
          }
        ]
      },
      {
        "title": "Operationally durable — losing it reopens work, not truth",
        "kind": "boundary",
        "dir": "row",
        "children": [
          {
            "title": "In flight",
            "kind": "plain",
            "nodes": [
              {
                "id": "s-case",
                "label": "Open case state",
                "kind": "store",
                "sub": "resumable"
              },
              {
                "id": "s-idx",
                "label": "Identity index",
                "kind": "store",
                "sub": "re-derivable, slowly"
              },
              {
                "id": "s-supp",
                "label": "Suppression list",
                "kind": "store",
                "sub": "rebuilt from cases"
              }
            ]
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "s-ledger",
        "to": "s-proj",
        "label": "rebuild",
        "kind": "batch"
      },
      {
        "from": "s-case",
        "to": "s-supp",
        "label": "on completion",
        "kind": "async"
      }
    ],
    "note": "Only the top row has an RPO worth arguing about. Everything in the middle row is deliberately disposable, which is what makes a bad deploy survivable.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "12-data-model",
    "title": "Data Model — Permission, Not People",
    "layout": "er",
    "canvas": {
      "width": 1700,
      "cols": 4
    },
    "rowGap": 240,
    "entities": [
      {
        "id": "purpose",
        "name": "purpose",
        "kind": "platform",
        "row": 0,
        "col": 0,
        "attrs": [
          "purpose_id  PK",
          "parent_id  FK -> purpose",
          "owner",
          "data_categories"
        ]
      },
      {
        "id": "pver",
        "name": "purpose_version",
        "kind": "platform",
        "row": 0,
        "col": 1,
        "attrs": [
          "purpose_id  PK FK",
          "version  PK",
          "widening  bool",
          "retention_days"
        ]
      },
      {
        "id": "basis",
        "name": "lawful_basis",
        "kind": "platform",
        "row": 0,
        "col": 2,
        "attrs": [
          "purpose_id  PK FK",
          "version  PK FK",
          "jurisdiction  PK",
          "basis",
          "notice_version"
        ]
      },
      {
        "id": "target",
        "name": "processing_target",
        "kind": "integration",
        "row": 0,
        "col": 3,
        "attrs": [
          "target_id  PK",
          "purpose_id  FK",
          "class  first|recipient",
          "erasure_window",
          "technique"
        ]
      },
      {
        "id": "subject",
        "name": "subject",
        "kind": "store",
        "row": 1,
        "col": 0,
        "attrs": [
          "subject_key  PK",
          "jurisdiction",
          "jurisdiction_version",
          "key_arn"
        ]
      },
      {
        "id": "entry",
        "name": "consent_entry",
        "kind": "store",
        "row": 1,
        "col": 1,
        "attrs": [
          "subject_key  PK FK",
          "captured_at  PK",
          "purpose_id  FK",
          "version  FK",
          "decision",
          "surface",
          "actor"
        ]
      },
      {
        "id": "state",
        "name": "current_state",
        "kind": "store",
        "row": 1,
        "col": 2,
        "attrs": [
          "subject_key  PK FK",
          "purpose_id  PK FK",
          "jurisdiction  PK",
          "decision",
          "ledger_version"
        ]
      },
      {
        "id": "ident",
        "name": "identifier",
        "kind": "store",
        "row": 1,
        "col": 3,
        "attrs": [
          "identifier_hash  PK",
          "subject_key  FK",
          "system",
          "linked_at"
        ]
      },
      {
        "id": "case",
        "name": "rights_case",
        "kind": "store",
        "row": 2,
        "col": 0,
        "attrs": [
          "case_id  PK",
          "subject_key  FK",
          "type",
          "verification",
          "state",
          "sla_due"
        ]
      },
      {
        "id": "instr",
        "name": "target_outcome",
        "kind": "store",
        "row": 2,
        "col": 1,
        "attrs": [
          "case_id  PK FK",
          "target_id  PK FK",
          "state  4-valued",
          "attested_at",
          "refusal_reason"
        ]
      },
      {
        "id": "supp",
        "name": "suppression",
        "kind": "store",
        "row": 3,
        "col": 0,
        "attrs": [
          "subject_key_hash  PK",
          "erased_at",
          "case_id  FK"
        ]
      },
      {
        "id": "audit",
        "name": "audit_record",
        "kind": "store",
        "row": 3,
        "col": 1,
        "attrs": [
          "record_id  PK",
          "subject_key  FK",
          "kind",
          "at",
          "prev_hash"
        ]
      }
    ],
    "relations": [
      {
        "from": "purpose",
        "to": "pver",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "pver",
        "to": "basis",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "basis",
        "to": "target",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "subject",
        "to": "entry",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "entry",
        "to": "state",
        "label": "N : 1",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "subject",
        "to": "ident",
        "label": "1 : N",
        "from_side": "n3",
        "to_side": "n"
      },
      {
        "from": "pver",
        "to": "entry",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "basis",
        "to": "state",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "subject",
        "to": "case",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "case",
        "to": "instr",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "case",
        "to": "supp",
        "label": "1 : 1",
        "kind": "optional",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "instr",
        "to": "audit",
        "label": "1 : N",
        "kind": "optional",
        "from_side": "s",
        "to_side": "n"
      }
    ],
    "note": "What is missing is the point: no profile, no behaviour, no content. Only a pseudonymous key, what it may be used for, and what was done about it.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "13-critical-flow-withdrawal",
    "title": "Critical Flow — A Withdrawal Reaches the Read Path",
    "layout": "sequence",
    "canvas": {
      "width": 1740
    },
    "lifelines": [
      {
        "id": "sub",
        "label": "Subject",
        "kind": "actor"
      },
      {
        "id": "cap",
        "label": "Capture API",
        "kind": "integration"
      },
      {
        "id": "led",
        "label": "Consent ledger",
        "kind": "store"
      },
      {
        "id": "bus",
        "label": "Withdrawal stream",
        "kind": "queue"
      },
      {
        "id": "svc",
        "label": "Product service",
        "kind": "external"
      },
      {
        "id": "dec",
        "label": "Decision API",
        "kind": "integration"
      },
      {
        "id": "aud",
        "label": "Audit store",
        "kind": "store"
      }
    ],
    "messages": [
      {
        "from": "sub",
        "to": "cap",
        "label": "POST /withdraw",
        "kind": "call"
      },
      {
        "from": "cap",
        "to": "cap",
        "label": "purpose registered?",
        "kind": "self"
      },
      {
        "from": "cap",
        "to": "led",
        "label": "append entry",
        "kind": "call"
      },
      {
        "from": "led",
        "to": "cap",
        "label": "committed, v=1841",
        "kind": "return"
      },
      {
        "from": "cap",
        "to": "sub",
        "label": "receipt: v=1841, 12:04:07Z",
        "kind": "return"
      },
      {
        "from": "led",
        "to": "bus",
        "label": "WithdrawalRecorded",
        "kind": "async"
      },
      {
        "from": "bus",
        "to": "svc",
        "label": "invalidate subject",
        "kind": "async"
      },
      {
        "from": "svc",
        "to": "svc",
        "label": "drop cached ALLOW",
        "kind": "self"
      },
      {
        "from": "svc",
        "to": "dec",
        "label": "evaluate(S, ads.personalised)",
        "kind": "call"
      },
      {
        "from": "dec",
        "to": "dec",
        "label": "projection v >= 1841?",
        "kind": "self"
      },
      {
        "from": "dec",
        "to": "svc",
        "label": "DENY, basis=consent, v=1841",
        "kind": "return"
      },
      {
        "from": "svc",
        "to": "svc",
        "label": "serve unpersonalised",
        "kind": "self"
      },
      {
        "from": "dec",
        "to": "aud",
        "label": "sampled outcome",
        "kind": "async"
      },
      {
        "from": "bus",
        "to": "aud",
        "label": "propagation lag",
        "kind": "async"
      }
    ],
    "note": "Message 10 is the whole design: the cache may be stale, so the decision carries the version it was computed from and the caller can tell.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "14-erasure-fan-out",
    "title": "Erasure Fan-Out — Four States Per Target, Per Class",
    "layout": "swimlane",
    "canvas": {
      "width": 1780
    },
    "laneHeaderWidth": 180,
    "stages": [
      "Instructed",
      "Acknowledged",
      "Attested",
      "Verified"
    ],
    "lanes": [
      {
        "title": "Transactional stores",
        "cells": [
          [
            {
              "label": "Hard delete",
              "kind": "integration"
            }
          ],
          [
            {
              "label": "Row count returned",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Signed attestation",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Key probe absent",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Immutable logs",
        "cells": [
          [
            {
              "label": "Destroy subject key",
              "kind": "security"
            }
          ],
          [
            {
              "label": "Key version gone",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Ciphertext retained",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Decrypt fails",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Analytics & derived",
        "cells": [
          [
            {
              "label": "Filter + re-derive",
              "kind": "integration"
            }
          ],
          [
            {
              "label": "Rebuild queued",
              "kind": "queue"
            }
          ],
          [
            {
              "label": "Aggregate re-issued",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Sampled scan clean",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Programmatic recipients",
        "cells": [
          [
            {
              "label": "API instruction",
              "kind": "integration"
            }
          ],
          [
            {
              "label": "202 with job id",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Callback attested",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Reconciled export",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Manual recipients",
        "cells": [
          [
            {
              "label": "Tracked obligation",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "Owner acknowledges",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Human attestation",
              "kind": "risk"
            }
          ],
          []
        ]
      },
      {
        "title": "Legally retained",
        "cells": [
          [
            {
              "label": "Refusal recorded",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "Reason to subject",
              "kind": "app"
            }
          ],
          [],
          [
            {
              "label": "Re-reviewed at expiry",
              "kind": "opportunity"
            }
          ]
        ]
      }
    ],
    "note": "Two cells are deliberately empty. A manual recipient cannot be verified by the platform, and a legal retention has nothing to attest — both are visible gaps rather than hidden ones.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "15-purpose-limitation-path",
    "title": "Purpose Limitation — The Decision Path on a Read",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": false,
    "align": "middle",
    "stages": [
      {
        "title": "Asked",
        "nodes": [
          {
            "id": "p-call",
            "label": "evaluate(S, P, J)",
            "kind": "integration"
          }
        ]
      },
      {
        "title": "Known?",
        "nodes": [
          {
            "id": "p-reg",
            "label": "Purpose registered?",
            "kind": "decision"
          },
          {
            "id": "p-rej",
            "label": "Reject the call",
            "kind": "risk",
            "sub": "not a DENY"
          }
        ]
      },
      {
        "title": "Basis",
        "nodes": [
          {
            "id": "p-basis",
            "label": "Basis in J?",
            "kind": "decision"
          },
          {
            "id": "p-li",
            "label": "Legitimate interest",
            "kind": "app",
            "sub": "until objection"
          },
          {
            "id": "p-consent",
            "label": "Consent",
            "kind": "app",
            "sub": "grant required"
          }
        ]
      },
      {
        "title": "State",
        "nodes": [
          {
            "id": "p-cache",
            "label": "Cache fresh?",
            "kind": "decision"
          },
          {
            "id": "p-remote",
            "label": "Remote evaluate",
            "kind": "app",
            "sub": "p99 40 ms"
          },
          {
            "id": "p-stale",
            "label": "Past staleness ceiling",
            "kind": "risk"
          }
        ]
      },
      {
        "title": "Verdict",
        "nodes": [
          {
            "id": "p-allow",
            "label": "ALLOW + version",
            "kind": "opportunity"
          },
          {
            "id": "p-deny",
            "label": "DENY + reason",
            "kind": "decision"
          },
          {
            "id": "p-unknown",
            "label": "UNKNOWN",
            "kind": "risk",
            "sub": "never read as ALLOW"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "p-call",
        "to": "p-reg"
      },
      {
        "from": "p-reg",
        "to": "p-rej",
        "label": "no",
        "kind": "error"
      },
      {
        "from": "p-reg",
        "to": "p-basis",
        "label": "yes"
      },
      {
        "from": "p-basis",
        "to": "p-li"
      },
      {
        "from": "p-basis",
        "to": "p-consent"
      },
      {
        "from": "p-li",
        "to": "p-cache",
        "route": "gutter"
      },
      {
        "from": "p-consent",
        "to": "p-cache"
      },
      {
        "from": "p-cache",
        "to": "p-allow",
        "label": "yes"
      },
      {
        "from": "p-cache",
        "to": "p-remote",
        "label": "no"
      },
      {
        "from": "p-remote",
        "to": "p-deny"
      },
      {
        "from": "p-cache",
        "to": "p-stale",
        "kind": "error"
      },
      {
        "from": "p-stale",
        "to": "p-unknown",
        "kind": "error"
      }
    ],
    "note": "An unregistered purpose is a caller error, not a denial — answering DENY would let a typo look like a lawful refusal.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "16-deployment-architecture",
    "title": "Deployment — Three Jurisdictions, No Cross-Border Failover",
    "layout": "nested",
    "canvas": {
      "width": 1780
    },
    "boxes": [
      {
        "title": "Global — definitions only, no personal data",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "Control plane",
            "kind": "boundary",
            "nodes": [
              {
                "id": "d-aurora",
                "label": "Aurora Global",
                "kind": "store",
                "sub": "purpose registry"
              },
              {
                "id": "d-bundle",
                "label": "Signed bundle",
                "kind": "store",
                "sub": "S3 + CloudFront"
              }
            ]
          }
        ]
      },
      {
        "title": "EU boundary — eu-west-1 / eu-central-1",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "AZ a / b / c",
            "kind": "boundary",
            "nodes": [
              {
                "id": "d-eu-api",
                "label": "Decision & capture",
                "kind": "app",
                "sub": "Fargate, 3 AZ"
              },
              {
                "id": "d-eu-ddb",
                "label": "Ledger + projection",
                "kind": "store",
                "sub": "DynamoDB"
              },
              {
                "id": "d-eu-sfn",
                "label": "Case orchestrator",
                "kind": "app"
              }
            ]
          },
          {
            "title": "Keys & evidence",
            "kind": "trust",
            "nodes": [
              {
                "id": "d-eu-kms",
                "label": "Regional CMK",
                "kind": "security"
              },
              {
                "id": "d-eu-s3",
                "label": "Object Lock audit",
                "kind": "store"
              }
            ]
          }
        ]
      },
      {
        "title": "US boundary — us-east-1 / us-west-2",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "AZ a / b / c",
            "kind": "boundary",
            "nodes": [
              {
                "id": "d-us-api",
                "label": "Decision & capture",
                "kind": "app",
                "sub": "Fargate, 3 AZ"
              },
              {
                "id": "d-us-ddb",
                "label": "Ledger + projection",
                "kind": "store"
              },
              {
                "id": "d-us-sfn",
                "label": "Case orchestrator",
                "kind": "app"
              }
            ]
          },
          {
            "title": "Keys & evidence",
            "kind": "trust",
            "nodes": [
              {
                "id": "d-us-kms",
                "label": "Regional CMK",
                "kind": "security"
              },
              {
                "id": "d-us-s3",
                "label": "Object Lock audit",
                "kind": "store"
              }
            ]
          }
        ]
      },
      {
        "title": "IN boundary — ap-south-1",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "AZ a / b / c",
            "kind": "boundary",
            "nodes": [
              {
                "id": "d-in-api",
                "label": "Decision & capture",
                "kind": "app",
                "sub": "Fargate, 3 AZ"
              },
              {
                "id": "d-in-ddb",
                "label": "Ledger + projection",
                "kind": "store"
              },
              {
                "id": "d-in-kms",
                "label": "Regional CMK",
                "kind": "security"
              }
            ]
          }
        ]
      }
    ],
    "outside": [
      {
        "id": "d-router",
        "label": "Jurisdiction router",
        "kind": "integration",
        "sub": "Route 53 + edge policy"
      }
    ],
    "edges": [
      {
        "from": "d-bundle",
        "to": "d-eu-api",
        "label": "policy",
        "kind": "batch"
      },
      {
        "from": "d-bundle",
        "to": "d-us-api",
        "kind": "batch"
      },
      {
        "from": "d-bundle",
        "to": "d-in-api",
        "kind": "batch"
      }
    ],
    "note": "Nothing crosses a boundary: no replica, no key, no failover. A region's unavailability denies its subjects' consent-based purposes, which is the correct answer.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "17-observability",
    "title": "Observability — Signal Families by Stage",
    "layout": "grid",
    "canvas": {
      "width": 1800
    },
    "laneHeaderWidth": 180,
    "columns": [
      "Capture",
      "Projection",
      "Decision",
      "Propagation",
      "Rights cases",
      "Evidence"
    ],
    "lanes": [
      {
        "title": "Availability & latency",
        "cells": [
          [
            {
              "label": "ack p99",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "build lag",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "p99 by cache hit",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "dispatch rate",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "intake errors",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "replay time",
              "kind": "platform"
            }
          ]
        ]
      },
      {
        "title": "Freshness",
        "cells": [
          [],
          [
            {
              "label": "projection age",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "cache staleness",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "lag per point",
              "kind": "risk"
            }
          ],
          [],
          []
        ]
      },
      {
        "title": "Correctness",
        "cells": [
          [
            {
              "label": "rejected purposes",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "rebuild diff",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "late ALLOW count",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "unconsumed events",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "reopened cases",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "hash chain breaks",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Compliance SLA",
        "cells": [
          [],
          [],
          [],
          [
            {
              "label": "recipients overdue",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "case clock at risk",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "retention overdue",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Security",
        "cells": [
          [
            {
              "label": "forged-grant score",
              "kind": "security"
            }
          ],
          [],
          [
            {
              "label": "purpose scope denials",
              "kind": "security"
            }
          ],
          [],
          [
            {
              "label": "index reads per case",
              "kind": "security"
            }
          ],
          [
            {
              "label": "admin overrides",
              "kind": "security"
            }
          ]
        ]
      },
      {
        "title": "Cost",
        "cells": [
          [
            {
              "label": "writes per tenant",
              "kind": "app"
            }
          ],
          [],
          [
            {
              "label": "remote-eval ratio",
              "kind": "app"
            }
          ],
          [
            {
              "label": "fan-out per purpose",
              "kind": "app"
            }
          ],
          [
            {
              "label": "cost per case",
              "kind": "app"
            }
          ],
          [
            {
              "label": "archive retrieval",
              "kind": "app"
            }
          ]
        ]
      }
    ],
    "note": "Four alarms page a human: propagation lag past the ceiling, a late ALLOW, a case clock at risk, and a broken hash chain. Everything else is a dashboard.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "18-consent-lifecycle",
    "title": "Consent Lifecycle — The Loop That Has To Close",
    "layout": "cycle",
    "canvas": {
      "width": 1560
    },
    "centre": {
      "label": "Consent lifecycle"
    },
    "nodes": [
      {
        "id": "y-declared",
        "label": "Purpose declared",
        "kind": "platform",
        "sub": "basis + retention"
      },
      {
        "id": "y-asked",
        "label": "Permission asked",
        "kind": "app",
        "sub": "notice version stored"
      },
      {
        "id": "y-held",
        "label": "Permission held",
        "kind": "store",
        "sub": "ledger entry"
      },
      {
        "id": "y-relied",
        "label": "Relied on",
        "kind": "integration",
        "sub": "decision at read time"
      },
      {
        "id": "y-ended",
        "label": "Withdrawn or expired",
        "kind": "decision",
        "sub": "validity period"
      },
      {
        "id": "y-prop",
        "label": "Propagated & verified",
        "kind": "app",
        "sub": "within the ceiling"
      },
      {
        "id": "y-proved",
        "label": "Evidence retained",
        "kind": "store",
        "sub": "7 years"
      }
    ],
    "ringLabels": [
      "notice shown",
      "decision captured",
      "evaluated",
      "the subject acts",
      "fan-out",
      "attested",
      "re-ask on new version"
    ],
    "rx": 470,
    "ry": 230,
    "note": "The closing arrow is the one usually missing: a widened purpose version returns the subject to being asked, rather than inheriting a grant given for something narrower.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "19-purpose-release-path",
    "title": "Purpose Change — The Release Path",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": true,
    "align": "middle",
    "stages": [
      {
        "title": "Propose",
        "nodes": [
          {
            "id": "r-owner",
            "label": "Purpose owner",
            "kind": "actor"
          },
          {
            "id": "r-pr",
            "label": "Policy as code",
            "kind": "app",
            "sub": "git, reviewed"
          }
        ]
      },
      {
        "title": "Check",
        "nodes": [
          {
            "id": "r-lint",
            "label": "Completeness gate",
            "kind": "decision",
            "sub": "basis, categories, retention"
          },
          {
            "id": "r-window",
            "label": "Recipient window gate",
            "kind": "decision",
            "sub": "refuses the impossible"
          }
        ]
      },
      {
        "title": "Approve",
        "nodes": [
          {
            "id": "r-legal",
            "label": "Counsel approval",
            "kind": "security"
          },
          {
            "id": "r-two",
            "label": "Two-person sign-off",
            "kind": "security",
            "sub": "both recorded"
          }
        ]
      },
      {
        "title": "Publish",
        "nodes": [
          {
            "id": "r-sign",
            "label": "Signed bundle",
            "kind": "store",
            "sub": "versioned"
          },
          {
            "id": "r-widen",
            "label": "Widening?",
            "kind": "decision",
            "sub": "new version, re-ask"
          }
        ]
      },
      {
        "title": "Adopt",
        "nodes": [
          {
            "id": "r-region",
            "label": "Regions pull",
            "kind": "app",
            "sub": "visible in 120 s"
          },
          {
            "id": "r-sdk",
            "label": "Enforcement points refresh",
            "kind": "app"
          }
        ]
      },
      {
        "title": "Watch",
        "nodes": [
          {
            "id": "r-unreg",
            "label": "Unregistered-use findings",
            "kind": "risk"
          },
          {
            "id": "r-cost",
            "label": "Cost per purpose",
            "kind": "platform"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "r-widen",
        "to": "r-sdk",
        "kind": "async"
      }
    ],
    "note": "The two gates refuse at design time what would otherwise be discovered at audit: an incomplete purpose, and a recipient that cannot meet the jurisdiction's erasure window.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "20-trust-zones",
    "title": "Trust Zones — What Crosses, and What Is Checked",
    "layout": "zones",
    "canvas": {
      "width": 1760
    },
    "zones": [
      {
        "title": "Internet",
        "kind": "trust",
        "nodes": [
          {
            "id": "z-sub",
            "label": "Subject device",
            "kind": "actor"
          },
          {
            "id": "z-recip",
            "label": "Processor",
            "kind": "external",
            "sub": "60"
          },
          {
            "id": "z-reg",
            "label": "Supervisory authority",
            "kind": "external"
          }
        ]
      },
      {
        "title": "Perimeter",
        "kind": "trust",
        "nodes": [
          {
            "id": "z-waf",
            "label": "CloudFront + WAF",
            "kind": "integration"
          },
          {
            "id": "z-apigw",
            "label": "API Gateway",
            "kind": "integration"
          },
          {
            "id": "z-authn",
            "label": "Subject authn + step-up",
            "kind": "security"
          },
          {
            "id": "z-rate",
            "label": "Rate & anomaly scoring",
            "kind": "security"
          }
        ]
      },
      {
        "title": "Application — regional",
        "kind": "trust",
        "nodes": [
          {
            "id": "z-capture",
            "label": "Capture",
            "kind": "app"
          },
          {
            "id": "z-decide",
            "label": "Decision",
            "kind": "app"
          },
          {
            "id": "z-case",
            "label": "Case orchestrator",
            "kind": "app"
          },
          {
            "id": "z-adapt",
            "label": "Target adapters",
            "kind": "integration"
          }
        ]
      },
      {
        "title": "Data — separately authorised",
        "kind": "trust",
        "nodes": [
          {
            "id": "z-ledger",
            "label": "Consent ledger",
            "kind": "store"
          },
          {
            "id": "z-kms",
            "label": "Per-subject keys",
            "kind": "security"
          },
          {
            "id": "z-idx",
            "label": "Identity index",
            "kind": "store",
            "sub": "crown jewels"
          }
        ]
      },
      {
        "title": "Evidence — write-once",
        "kind": "trust",
        "nodes": [
          {
            "id": "z-audit",
            "label": "Audit store",
            "kind": "store",
            "sub": "Object Lock"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "z-sub",
        "to": "z-waf",
        "label": "TLS"
      },
      {
        "from": "z-authn",
        "to": "z-capture",
        "label": "verified subject"
      },
      {
        "from": "z-rate",
        "to": "z-case",
        "label": "step-up proof"
      },
      {
        "from": "z-decide",
        "to": "z-ledger",
        "label": "purpose-scoped"
      },
      {
        "from": "z-case",
        "to": "z-idx",
        "label": "case-bound"
      },
      {
        "from": "z-case",
        "to": "z-kms",
        "label": "shred"
      },
      {
        "from": "z-capture",
        "to": "z-audit",
        "label": "append only",
        "kind": "async"
      },
      {
        "from": "z-adapt",
        "to": "z-recip",
        "label": "signed instruction",
        "kind": "async"
      }
    ],
    "note": "The decision path and the identity index are authorised separately. An attacker holding decision credentials learns what a subject refused, not who they are elsewhere.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "21-identity-and-authorisation",
    "title": "Identity & Authorisation — An Agent Acts On a Caller's Behalf",
    "layout": "sequence",
    "canvas": {
      "width": 1760
    },
    "lifelines": [
      {
        "id": "caller",
        "label": "Subject on the phone",
        "kind": "actor"
      },
      {
        "id": "agent",
        "label": "Support agent",
        "kind": "actor"
      },
      {
        "id": "console",
        "label": "Agent console",
        "kind": "app"
      },
      {
        "id": "idp",
        "label": "Workforce IdP",
        "kind": "security"
      },
      {
        "id": "intake",
        "label": "Case intake",
        "kind": "app"
      },
      {
        "id": "resolver",
        "label": "Identity resolver",
        "kind": "app"
      },
      {
        "id": "audit",
        "label": "Audit store",
        "kind": "store"
      }
    ],
    "messages": [
      {
        "from": "caller",
        "to": "agent",
        "label": "\"delete my account\"",
        "kind": "call"
      },
      {
        "from": "agent",
        "to": "console",
        "label": "open a case",
        "kind": "call"
      },
      {
        "from": "console",
        "to": "idp",
        "label": "step-up, agent role",
        "kind": "call"
      },
      {
        "from": "idp",
        "to": "console",
        "label": "assertion, 30 min",
        "kind": "return"
      },
      {
        "from": "console",
        "to": "intake",
        "label": "create case (acting for)",
        "kind": "call"
      },
      {
        "from": "intake",
        "to": "intake",
        "label": "verify the caller",
        "kind": "self"
      },
      {
        "from": "intake",
        "to": "caller",
        "label": "one-time code",
        "kind": "async"
      },
      {
        "from": "caller",
        "to": "intake",
        "label": "code",
        "kind": "call"
      },
      {
        "from": "intake",
        "to": "resolver",
        "label": "resolve, case-bound",
        "kind": "call"
      },
      {
        "from": "resolver",
        "to": "resolver",
        "label": "scope to this case",
        "kind": "self"
      },
      {
        "from": "resolver",
        "to": "intake",
        "label": "identifier set",
        "kind": "return"
      },
      {
        "from": "intake",
        "to": "console",
        "label": "case open, fields masked",
        "kind": "return"
      },
      {
        "from": "intake",
        "to": "audit",
        "label": "who, what, for whom",
        "kind": "async"
      },
      {
        "from": "resolver",
        "to": "audit",
        "label": "every record read",
        "kind": "async"
      },
      {
        "from": "console",
        "to": "agent",
        "label": "access expires in 30 min",
        "kind": "return"
      }
    ],
    "note": "The agent never holds standing access. Message 10 is the control: the resolver answers only for the identifiers this case needs, and logs each one.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  },
  {
    "id": "22-failure-classes",
    "title": "Failure Classes — What Catches Each, and What It Costs",
    "layout": "grid",
    "canvas": {
      "width": 1720
    },
    "laneHeaderWidth": 230,
    "columns": [
      "Caught by",
      "Bounded by",
      "Cost when the bound fails"
    ],
    "lanes": [
      {
        "title": "Decision plane unreachable",
        "cells": [
          [
            {
              "label": "cache staleness age",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "per-purpose posture",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "purposes deny; reads degrade",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Stale consent at the edge",
        "cells": [
          [
            {
              "label": "lag per enforcement point",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "15 min ceiling",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "unlawful processing, reportable",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Partial erasure",
        "cells": [
          [
            {
              "label": "four-state per target",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "case stays open",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "statutory deadline missed",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Silent target",
        "cells": [
          [
            {
              "label": "no ack in window",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "treated as failed",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "a closed case that is not done",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Resurrection after erasure",
        "cells": [
          [
            {
              "label": "absence probing",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "suppression on ingest",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "the subject is back, and knows",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Identity resolution miss",
        "cells": [
          [
            {
              "label": "post-case re-resolution",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "case reopens",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "erasure that looked complete",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Jurisdiction misdetermined",
        "cells": [
          [
            {
              "label": "versioned determination",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "audited re-location",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "unlawful transfer",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Forged grant",
        "cells": [
          [
            {
              "label": "anomaly scoring",
              "kind": "security"
            }
          ],
          [
            {
              "label": "surface + actor on entry",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "processing legalised by an attacker",
              "kind": "risk"
            }
          ]
        ]
      },
      {
        "title": "Regional isolation",
        "cells": [
          [
            {
              "label": "regional health",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "no cross-border failover",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "region-wide denial, by design",
              "kind": "opportunity"
            }
          ]
        ]
      },
      {
        "title": "Control plane unavailable",
        "cells": [
          [
            {
              "label": "bundle age",
              "kind": "platform"
            }
          ],
          [
            {
              "label": "last-known-good snapshot",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "no new purposes; decisions continue",
              "kind": "opportunity"
            }
          ]
        ]
      }
    ],
    "note": "The last two rows are green on purpose: the design chooses them. Everything above is a defect with a named owner.",
    "meta": {
      "v": "1.0",
      "owner": "Security & Identity Architecture"
    }
  }
]
