[
  {
    "id": "01-system-context",
    "title": "Cost Allocation & Showback Platform — System Context",
    "layout": "context",
    "canvas": {
      "width": 1700
    },
    "colWidth": 260,
    "system": {
      "label": "Cost Allocation & Showback Platform",
      "sub": "Bill in, accountable owner out"
    },
    "groups": [
      {
        "side": "left",
        "title": "People who read the number",
        "nodes": [
          {
            "id": "eng",
            "label": "Engineering lead",
            "kind": "actor",
            "sub": "450 teams",
            "rel": "team bill",
            "dir": "in"
          },
          {
            "id": "prod",
            "label": "Product owner",
            "kind": "actor",
            "sub": "28 product lines",
            "rel": "unit cost",
            "dir": "in"
          },
          {
            "id": "finops",
            "label": "FinOps analyst",
            "kind": "actor",
            "sub": "policy owner",
            "rel": "policy",
            "dir": "in"
          },
          {
            "id": "fin",
            "label": "Finance controller",
            "kind": "actor",
            "sub": "close owner",
            "rel": "statements",
            "dir": "in"
          }
        ]
      },
      {
        "side": "right",
        "title": "Where the spend is billed",
        "nodes": [
          {
            "id": "aws",
            "label": "AWS billing export",
            "kind": "external",
            "sub": "CUR, hourly",
            "rel": "CUR daily",
            "kind2": "batch"
          },
          {
            "id": "az",
            "label": "Azure Cost Management",
            "kind": "external",
            "sub": "FOCUS export",
            "rel": "FOCUS daily",
            "kind2": "batch"
          },
          {
            "id": "gcp",
            "label": "Google Cloud billing",
            "kind": "external",
            "sub": "BigQuery export",
            "rel": "BQ daily",
            "kind2": "batch"
          },
          {
            "id": "saas",
            "label": "Licence & SaaS vendors",
            "kind": "external",
            "sub": "40M USD/yr",
            "rel": "invoices",
            "kind2": "batch"
          }
        ]
      },
      {
        "side": "top",
        "title": "Who owns what (read only)",
        "nodes": [
          {
            "id": "cmdb",
            "label": "Service catalogue",
            "kind": "external",
            "sub": "CMDB",
            "rel": "catalogue",
            "kind2": "batch"
          },
          {
            "id": "hr",
            "label": "Org & cost-centre system",
            "kind": "external",
            "sub": "effective-dated",
            "rel": "org tree",
            "kind2": "batch"
          },
          {
            "id": "k8s",
            "label": "Cluster metrics",
            "kind": "external",
            "sub": "60k workloads",
            "rel": "samples",
            "kind2": "async"
          }
        ]
      },
      {
        "side": "bottom",
        "title": "What it feeds",
        "nodes": [
          {
            "id": "gl",
            "label": "ERP general ledger",
            "kind": "external",
            "sub": "chargeback only",
            "rel": "postings",
            "dir": "out",
            "kind2": "batch"
          },
          {
            "id": "chat",
            "label": "Collaboration digest",
            "kind": "external",
            "sub": "Teams",
            "rel": "alerts",
            "dir": "out",
            "kind2": "async"
          },
          {
            "id": "bi",
            "label": "Enterprise BI",
            "kind": "external",
            "sub": "Power BI",
            "rel": "marts",
            "dir": "out"
          }
        ]
      }
    ],
    "note": "The provider is the only source of truth for what was charged. Everything this platform adds is an answer to 'by whom'.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "02-high-level-architecture",
    "title": "High-Level Architecture — Six Stages From Invoice to Accountability",
    "layout": "flow",
    "canvas": {
      "width": 1780
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "1 · Collect",
        "nodes": [
          {
            "id": "readers",
            "label": "Provider export readers",
            "kind": "integration",
            "sub": "3 clouds, T+1"
          },
          {
            "id": "usage",
            "label": "Container usage collector",
            "kind": "integration",
            "sub": "60 s samples"
          },
          {
            "id": "raw",
            "label": "Raw landing zone",
            "kind": "store",
            "sub": "immutable, as given"
          }
        ]
      },
      {
        "title": "2 · Conform",
        "nodes": [
          {
            "id": "focus",
            "label": "FOCUS conformer",
            "kind": "app",
            "sub": "one cost record"
          },
          {
            "id": "recon",
            "label": "Invoice reconciler",
            "kind": "app",
            "sub": "0.1% tolerance"
          },
          {
            "id": "restate",
            "label": "Restatement detector",
            "kind": "app",
            "sub": "record-grain delta"
          }
        ]
      },
      {
        "title": "3 · Own",
        "nodes": [
          {
            "id": "ownres",
            "label": "Ownership resolver",
            "kind": "app",
            "sub": "effective-dated"
          },
          {
            "id": "cover",
            "label": "Coverage scorer",
            "kind": "app",
            "sub": "gap in currency"
          }
        ]
      },
      {
        "title": "4 · Allocate",
        "nodes": [
          {
            "id": "policy",
            "label": "Policy registry",
            "kind": "security",
            "sub": "versioned"
          },
          {
            "id": "run",
            "label": "Allocation run",
            "kind": "app",
            "sub": "pure, re-runnable"
          },
          {
            "id": "alloc",
            "label": "Allocated facts",
            "kind": "store",
            "sub": "derived, disposable"
          }
        ]
      },
      {
        "title": "5 · Publish",
        "nodes": [
          {
            "id": "freeze",
            "label": "Statement publisher",
            "kind": "app",
            "sub": "freeze at close"
          },
          {
            "id": "stmt",
            "label": "Statement store",
            "kind": "store",
            "sub": "immutable, 7 yr"
          }
        ]
      },
      {
        "title": "6 · Act",
        "nodes": [
          {
            "id": "dash",
            "label": "Team dashboard",
            "kind": "app",
            "sub": "13-month history"
          },
          {
            "id": "alerts",
            "label": "Budgets & anomalies",
            "kind": "app",
            "sub": "24 h detection"
          },
          {
            "id": "post",
            "label": "GL posting file",
            "kind": "integration",
            "sub": "chargeback only"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "raw",
        "to": "focus",
        "label": "rebuild source",
        "kind": "batch"
      },
      {
        "from": "policy",
        "to": "run",
        "label": "version pinned"
      },
      {
        "from": "restate",
        "to": "run",
        "label": "re-run trigger",
        "kind": "async"
      },
      {
        "from": "stmt",
        "to": "post",
        "label": "frozen only",
        "kind": "batch"
      }
    ],
    "note": "Stage 4 is a pure function of three versioned inputs. Stage 5 freezes its output; nothing downstream reads anything that can still move.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "03-actors-and-journeys",
    "title": "Actors and Their Core Journeys",
    "layout": "actors",
    "canvas": {
      "width": 1740
    },
    "cardWidth": 280,
    "groups": [
      {
        "title": "Engineering",
        "kind": "boundary",
        "actors": [
          {
            "id": "englead",
            "label": "Engineering lead",
            "sub": "one of 450",
            "goal": "Tell me what my team costs, and let me prove to my own engineers which change caused the number to move.",
            "journeys": [
              {
                "id": "j-spike",
                "label": "Explain a cost spike",
                "sub": "the load-bearing journey"
              },
              {
                "label": "Fix my team's tag gaps"
              },
              {
                "label": "Set a budget for next quarter"
              }
            ]
          },
          {
            "id": "platlead",
            "label": "Shared platform owner",
            "sub": "clusters, warehouse",
            "goal": "Do not hand me the whole cluster bill. Split it by a rule my tenants can read and argue with.",
            "journeys": [
              {
                "label": "Publish an apportionment rule"
              },
              {
                "label": "Defend the idle line"
              }
            ]
          }
        ]
      },
      {
        "title": "Finance and FinOps",
        "kind": "boundary",
        "actors": [
          {
            "id": "controller",
            "label": "Finance controller",
            "sub": "monthly close",
            "goal": "Give me one frozen number per cost centre that reconciles to the invoice and does not change after I have reported it.",
            "journeys": [
              {
                "id": "j-close",
                "label": "Close and publish the month",
                "sub": "5 business days"
              },
              {
                "label": "Absorb a restatement"
              }
            ]
          },
          {
            "id": "analyst",
            "label": "FinOps analyst",
            "sub": "policy owner",
            "goal": "Let me change an allocation rule and see, before I adopt it, exactly whose bill it moves and by how much.",
            "journeys": [
              {
                "label": "Simulate a policy change"
              },
              {
                "label": "Chase the unallocated remainder"
              }
            ]
          },
          {
            "id": "prodowner",
            "label": "Product owner",
            "sub": "28 lines",
            "goal": "Show me cost per order, and tell me whether it went up because we grew or because we got worse.",
            "journeys": [
              {
                "label": "Review unit economics"
              }
            ]
          }
        ]
      },
      {
        "title": "Machines and feeds",
        "kind": "cloud",
        "actors": [
          {
            "id": "exporter",
            "label": "Provider billing export",
            "kind": "external",
            "sub": "3 clouds, daily",
            "goal": "I deliver yesterday, and I silently rewrite last week. Cope with that.",
            "journeys": [
              {
                "label": "Deliver a restated period"
              }
            ]
          },
          {
            "id": "driver",
            "label": "Business driver feed",
            "kind": "platform",
            "sub": "team-owned",
            "goal": "I am a denominator somebody else maintains, and I go stale without telling anyone.",
            "journeys": [
              {
                "label": "Post a daily driver value"
              }
            ]
          }
        ]
      }
    ],
    "note": "The shared platform owner is in the cast because apportionment is negotiated with them, not imposed on them.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "04-journey-explain-a-spike",
    "title": "Journey — An Engineering Lead Explains a Cost Spike",
    "layout": "journey",
    "canvas": {
      "width": 1720
    },
    "actor": {
      "label": "Engineering lead",
      "sub": "owns 9 services",
      "goal": "Find out what moved, why, and whether it was us — before the review meeting",
      "trigger": "An anomaly alert, or a finance question about last month's number",
      "success": "A one-sentence explanation naming a resource, a day and a cause"
    },
    "phases": [
      {
        "title": "Notice",
        "sub": "alert or question"
      },
      {
        "title": "Locate",
        "sub": "which dimension moved"
      },
      {
        "title": "Explain",
        "moment": true
      },
      {
        "title": "Act"
      },
      {
        "title": "Defend",
        "moment": true,
        "sub": "at the review"
      }
    ],
    "lanes": [
      {
        "title": "What they do",
        "kind": "step",
        "cells": [
          [
            {
              "label": "Opens the alert"
            }
          ],
          [
            {
              "label": "Filters to the delta"
            },
            {
              "label": "Compares to baseline"
            }
          ],
          [
            {
              "label": "Drills to resources"
            },
            {
              "label": "Reads the rule that fired"
            }
          ],
          [
            {
              "label": "Fixes tags or workload"
            },
            {
              "label": "Sets a budget alert"
            }
          ],
          [
            {
              "label": "Shows the statement"
            }
          ]
        ]
      },
      {
        "title": "What the platform gives",
        "kind": "system",
        "cells": [
          [
            {
              "label": "Alert names the service"
            }
          ],
          [
            {
              "label": "Attributed dimension"
            }
          ],
          [
            {
              "label": "Drill to cost records"
            },
            {
              "label": "Apportionment maths"
            }
          ],
          [
            {
              "label": "Coverage reconciler"
            }
          ],
          [
            {
              "label": "Frozen statement v1"
            },
            {
              "label": "Input versions shown"
            }
          ]
        ]
      },
      {
        "title": "How it feels",
        "kind": "emotion",
        "levels": [
          "Confident",
          "Uneasy",
          "Exposed"
        ],
        "points": [
          1,
          1,
          0,
          2,
          2
        ]
      },
      {
        "title": "Where it hurts",
        "kind": "pain",
        "cells": [
          [
            {
              "label": "Alert 3 days late"
            }
          ],
          [
            {
              "label": "Spike is in 'untagged'"
            }
          ],
          [
            {
              "label": "Shared cluster: no answer"
            },
            {
              "label": "Number changed since"
            }
          ],
          [],
          [
            {
              "label": "Finance has a different figure"
            }
          ]
        ]
      },
      {
        "title": "What must be true",
        "kind": "gain",
        "cells": [
          [
            {
              "label": "Detect within 24 h"
            }
          ],
          [
            {
              "label": "Remainder under 2%"
            }
          ],
          [
            {
              "label": "Drill-through p95 10 s"
            },
            {
              "label": "Input versions on view"
            }
          ],
          [
            {
              "label": "Owner-facing gap list"
            }
          ],
          [
            {
              "label": "One frozen number"
            }
          ]
        ]
      }
    ],
    "note": "The trough is 'Explain'. Every structural decision in this set exists to make that phase survivable.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "05-journey-close-the-month",
    "title": "Journey — A Finance Controller Closes and Publishes the Month",
    "layout": "journey",
    "canvas": {
      "width": 1720
    },
    "actor": {
      "label": "Finance controller",
      "sub": "28 cost centres",
      "goal": "Publish one defensible number per cost centre within five business days of close",
      "trigger": "Period close; the last provider invoice has landed",
      "success": "Every cost centre reconciled, frozen, versioned and reportable"
    },
    "phases": [
      {
        "title": "Wait",
        "sub": "for the last export"
      },
      {
        "title": "Reconcile",
        "moment": true
      },
      {
        "title": "Freeze"
      },
      {
        "title": "Absorb disputes"
      },
      {
        "title": "Report",
        "moment": true
      }
    ],
    "lanes": [
      {
        "title": "What they do",
        "kind": "step",
        "cells": [
          [
            {
              "label": "Watches export status"
            }
          ],
          [
            {
              "label": "Checks invoice match"
            },
            {
              "label": "Reviews remainder"
            }
          ],
          [
            {
              "label": "Publishes statements"
            }
          ],
          [
            {
              "label": "Triages disputes"
            },
            {
              "label": "Approves restatements"
            }
          ],
          [
            {
              "label": "Posts to the ledger"
            }
          ]
        ]
      },
      {
        "title": "What the platform gives",
        "kind": "system",
        "cells": [
          [
            {
              "label": "Per-provider landing state"
            }
          ],
          [
            {
              "label": "Reconciliation report"
            },
            {
              "label": "Remainder by team"
            }
          ],
          [
            {
              "label": "Freeze with input versions"
            }
          ],
          [
            {
              "label": "Dispute ledger"
            },
            {
              "label": "Supersede, not replace"
            }
          ],
          [
            {
              "label": "Idempotent posting file"
            }
          ]
        ]
      },
      {
        "title": "How it feels",
        "kind": "emotion",
        "levels": [
          "In control",
          "Watchful",
          "Blocked"
        ],
        "points": [
          1,
          0,
          2,
          1,
          2
        ]
      },
      {
        "title": "Where it hurts",
        "kind": "pain",
        "cells": [
          [
            {
              "label": "One provider is late"
            }
          ],
          [
            {
              "label": "Variance over tolerance"
            }
          ],
          [],
          [
            {
              "label": "Restatement after report"
            }
          ],
          [
            {
              "label": "Double posting on retry"
            }
          ]
        ]
      },
      {
        "title": "What must be true",
        "kind": "gain",
        "cells": [
          [
            {
              "label": "Incomplete, never short"
            }
          ],
          [
            {
              "label": "Publication blocked, loudly"
            }
          ],
          [
            {
              "label": "Frozen in 5 days, p95 3"
            }
          ],
          [
            {
              "label": "Both versions retrievable"
            }
          ],
          [
            {
              "label": "Idempotent re-delivery"
            }
          ]
        ]
      }
    ],
    "note": "Two phases are marked as moments: a wrong reconciliation and a wrong posting are both unrecoverable inside the close.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "06-layered-architecture",
    "title": "Layered Architecture — Eight Layers, Three of Them Immutable",
    "layout": "bands",
    "canvas": {
      "width": 1740
    },
    "layerHeaderWidth": 170,
    "bands": [
      {
        "name": "Experience",
        "nodes": [
          {
            "id": "dash",
            "label": "Team dashboard",
            "kind": "app",
            "sub": "13 months"
          },
          {
            "id": "viewer",
            "label": "Statement viewer",
            "kind": "app"
          },
          {
            "id": "drill",
            "label": "Drill-through explorer",
            "kind": "app"
          },
          {
            "id": "disputeui",
            "label": "Dispute desk",
            "kind": "app"
          },
          {
            "id": "api",
            "label": "Query & export API",
            "kind": "integration"
          }
        ]
      },
      {
        "name": "Statement\n(immutable)",
        "nodes": [
          {
            "id": "pub",
            "label": "Statement publisher",
            "kind": "app",
            "sub": "freeze at close"
          },
          {
            "id": "vreg",
            "label": "Version register",
            "kind": "store"
          },
          {
            "id": "rest",
            "label": "Restatement controller",
            "kind": "app",
            "sub": "supersede only"
          },
          {
            "id": "dispute",
            "label": "Dispute ledger",
            "kind": "store"
          },
          {
            "id": "gl",
            "label": "GL posting builder",
            "kind": "integration"
          }
        ]
      },
      {
        "name": "Analytics",
        "nodes": [
          {
            "id": "unit",
            "label": "Unit-economics engine",
            "kind": "app"
          },
          {
            "id": "budget",
            "label": "Budget & forecast",
            "kind": "app"
          },
          {
            "id": "anom",
            "label": "Anomaly detection",
            "kind": "app"
          },
          {
            "id": "sim",
            "label": "Policy what-if simulator",
            "kind": "app"
          }
        ]
      },
      {
        "name": "Allocation\n(pure function)",
        "nodes": [
          {
            "id": "orch",
            "label": "Run orchestrator",
            "kind": "app"
          },
          {
            "id": "direct",
            "label": "Direct attribution",
            "kind": "app"
          },
          {
            "id": "apport",
            "label": "Shared-cost apportioner",
            "kind": "app"
          },
          {
            "id": "amort",
            "label": "Commitment amortiser",
            "kind": "app"
          },
          {
            "id": "remain",
            "label": "Remainder handler",
            "kind": "app"
          },
          {
            "id": "preg",
            "label": "Policy registry",
            "kind": "security",
            "sub": "versioned"
          }
        ]
      },
      {
        "name": "Ownership",
        "nodes": [
          {
            "id": "orgtree",
            "label": "Effective-dated org tree",
            "kind": "store"
          },
          {
            "id": "resolver",
            "label": "Tag & mapping resolver",
            "kind": "app"
          },
          {
            "id": "excep",
            "label": "Exception registry",
            "kind": "store"
          },
          {
            "id": "cover",
            "label": "Coverage scorer",
            "kind": "app",
            "sub": "gap in currency"
          }
        ]
      },
      {
        "name": "Normalisation",
        "nodes": [
          {
            "id": "focus",
            "label": "FOCUS conformer",
            "kind": "app"
          },
          {
            "id": "tax",
            "label": "Service & SKU taxonomy",
            "kind": "store"
          },
          {
            "id": "fx",
            "label": "FX fixing",
            "kind": "app",
            "sub": "fixed at close"
          },
          {
            "id": "rdet",
            "label": "Restatement detector",
            "kind": "app"
          },
          {
            "id": "recon",
            "label": "Invoice reconciler",
            "kind": "app"
          },
          {
            "id": "quar",
            "label": "Schema quarantine",
            "kind": "risk"
          }
        ]
      },
      {
        "name": "Ingestion",
        "nodes": [
          {
            "id": "readers",
            "label": "Provider export readers",
            "kind": "integration"
          },
          {
            "id": "lic",
            "label": "Licence & SaaS feeds",
            "kind": "integration"
          },
          {
            "id": "usage",
            "label": "Container usage collector",
            "kind": "integration"
          },
          {
            "id": "drv",
            "label": "Business driver intake",
            "kind": "integration"
          },
          {
            "id": "raw",
            "label": "Raw landing zone",
            "kind": "store",
            "sub": "as given, forever"
          }
        ]
      },
      {
        "name": "Consumed\n(not owned)",
        "nodes": [
          {
            "id": "prov",
            "label": "Provider billing APIs",
            "kind": "external"
          },
          {
            "id": "cmdb",
            "label": "Service catalogue",
            "kind": "external"
          },
          {
            "id": "hr",
            "label": "Org & cost-centre system",
            "kind": "external"
          },
          {
            "id": "idp",
            "label": "Identity provider",
            "kind": "external"
          },
          {
            "id": "metrics",
            "label": "Cluster metrics",
            "kind": "external"
          },
          {
            "id": "erp",
            "label": "ERP general ledger",
            "kind": "external"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "preg",
        "to": "orch",
        "label": "version pinned"
      },
      {
        "from": "orch",
        "to": "pub",
        "label": "allocated facts"
      }
    ],
    "note": "Ownership sits below allocation on purpose: allocation reads a snapshot of it, never the live table. A detected restatement re-enters at the run orchestrator, not at the statement.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "07-platform-components",
    "title": "Platform Components — What Is Deployed, and Where State Lives",
    "layout": "nested",
    "canvas": {
      "width": 1740
    },
    "boxes": [
      {
        "title": "Azure — platform subscription (primary region)",
        "kind": "cloud",
        "dir": "col",
        "children": [
          {
            "title": "Serving tier — AKS, autoscaled",
            "kind": "boundary",
            "nodes": [
              {
                "id": "webapp",
                "label": "Dashboard & statement UI",
                "kind": "app",
                "sub": "React on AKS"
              },
              {
                "id": "qapi",
                "label": "Query API",
                "kind": "integration",
                "sub": "REST + OData"
              },
              {
                "id": "drillsvc",
                "label": "Drill-through service",
                "kind": "app",
                "sub": "p95 10 s"
              },
              {
                "id": "dispsvc",
                "label": "Dispute & statement service",
                "kind": "app"
              }
            ]
          },
          {
            "title": "Batch tier — elastic, interruption-tolerant",
            "kind": "boundary",
            "nodes": [
              {
                "id": "adf",
                "label": "Ingestion orchestrator",
                "kind": "platform",
                "sub": "Data Factory"
              },
              {
                "id": "conf",
                "label": "Conformer jobs",
                "kind": "app",
                "sub": "Databricks"
              },
              {
                "id": "runner",
                "label": "Allocation runner",
                "kind": "app",
                "sub": "Databricks, spot"
              },
              {
                "id": "scorer",
                "label": "Anomaly & forecast scorer",
                "kind": "app"
              }
            ]
          },
          {
            "title": "State — separated by mutability",
            "kind": "boundary",
            "nodes": [
              {
                "id": "adls",
                "label": "Raw landing zone",
                "kind": "store",
                "sub": "ADLS Gen2, WORM"
              },
              {
                "id": "adx",
                "label": "Cost fact store",
                "kind": "store",
                "sub": "Azure Data Explorer"
              },
              {
                "id": "sqlown",
                "label": "Ownership & policy",
                "kind": "store",
                "sub": "Azure SQL"
              },
              {
                "id": "sqlstmt",
                "label": "Statement & dispute store",
                "kind": "store",
                "sub": "Azure SQL, RPO 0"
              }
            ]
          },
          {
            "title": "Platform services",
            "kind": "boundary",
            "nodes": [
              {
                "id": "entra",
                "label": "Entra ID",
                "kind": "security",
                "sub": "workload identity"
              },
              {
                "id": "kv",
                "label": "Key Vault",
                "kind": "security",
                "sub": "CMK, rotation"
              },
              {
                "id": "eh",
                "label": "Event Hubs",
                "kind": "queue",
                "sub": "usage telemetry"
              },
              {
                "id": "mon",
                "label": "Azure Monitor",
                "kind": "security",
                "sub": "platform SLOs"
              }
            ]
          }
        ]
      }
    ],
    "outside": [
      {
        "id": "exp",
        "label": "Provider billing exports",
        "kind": "external",
        "sub": "3 clouds"
      },
      {
        "id": "kmet",
        "label": "Cluster metrics",
        "kind": "external",
        "sub": "60k workloads"
      },
      {
        "id": "cmdbx",
        "label": "Service catalogue & org system",
        "kind": "external"
      },
      {
        "id": "erpx",
        "label": "ERP general ledger",
        "kind": "external",
        "sub": "posting only"
      }
    ],
    "edges": [
      {
        "from": "exp",
        "to": "adf",
        "label": "daily pull",
        "kind": "batch"
      },
      {
        "from": "kmet",
        "to": "eh",
        "label": "usage samples",
        "kind": "async"
      },
      {
        "from": "adf",
        "to": "adls",
        "label": "land as given",
        "kind": "batch"
      },
      {
        "from": "runner",
        "to": "adx",
        "label": "allocated facts",
        "kind": "batch"
      },
      {
        "from": "dispsvc",
        "to": "sqlstmt",
        "label": "freeze"
      },
      {
        "from": "dispsvc",
        "to": "erpx",
        "label": "posting file",
        "kind": "batch"
      }
    ],
    "note": "Four stores because four mutabilities. The fact store is rebuildable; the statement store is not, and is the only one at RPO 0 alongside ownership and policy.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "08-integration-surface",
    "title": "Integration Surface — Five Things It Reads, Three It Tells",
    "layout": "hub",
    "canvas": {
      "width": 1700
    },
    "left": {
      "title": "Read (the platform never writes back)",
      "nodes": [
        {
          "id": "exports",
          "label": "Provider billing exports",
          "kind": "external",
          "sub": "AWS CUR · Azure · GCP",
          "rel": "daily",
          "kind2": "batch"
        },
        {
          "id": "licfeed",
          "label": "Licence & SaaS invoices",
          "kind": "external",
          "sub": "file + API",
          "rel": "monthly",
          "kind2": "batch"
        },
        {
          "id": "kube",
          "label": "Cluster metrics",
          "kind": "external",
          "sub": "60 s samples",
          "rel": "streamed",
          "kind2": "async"
        },
        {
          "id": "own",
          "label": "Catalogue & org system",
          "kind": "external",
          "sub": "effective-dated",
          "rel": "ownership",
          "kind2": "batch"
        },
        {
          "id": "drvfeed",
          "label": "Business driver feeds",
          "kind": "external",
          "sub": "team-owned",
          "rel": "daily push",
          "kind2": "sync"
        }
      ]
    },
    "centre": {
      "title": "Cost Allocation & Showback Platform",
      "nodes": [
        {
          "id": "core",
          "label": "Cost Allocation & Showback",
          "kind": "app",
          "sub": "read-only to the estate"
        }
      ]
    },
    "right": {
      "title": "Tell and act",
      "nodes": [
        {
          "id": "erpout",
          "label": "ERP general ledger",
          "kind": "external",
          "sub": "chargeback only",
          "rel": "postings",
          "dir": "out",
          "kind2": "batch"
        },
        {
          "id": "teamsout",
          "label": "Collaboration digest",
          "kind": "external",
          "sub": "Teams",
          "rel": "alerts",
          "dir": "out",
          "kind2": "async"
        },
        {
          "id": "biout",
          "label": "BI & team tooling",
          "kind": "external",
          "sub": "Power BI, budget gates",
          "rel": "marts, API",
          "dir": "out",
          "kind2": "batch"
        }
      ]
    },
    "note": "Five read surfaces, three write surfaces, and nothing written back to the estate. The provider invoice API is read once per period to reconcile. A platform that measured cost and also changed resources would be disbelieved by the teams it measures.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "09-cost-data-flow",
    "title": "Cost Data Flow — From a Provider File to a Frozen Line",
    "layout": "flow",
    "canvas": {
      "width": 1800
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Source",
        "nodes": [
          {
            "id": "s1",
            "label": "Provider export file",
            "kind": "external",
            "sub": "mutable for weeks"
          },
          {
            "id": "s2",
            "label": "Usage sample stream",
            "kind": "external",
            "sub": "60 s"
          },
          {
            "id": "s3",
            "label": "Vendor invoice",
            "kind": "external",
            "sub": "monthly PDF/API"
          }
        ]
      },
      {
        "title": "Land — immutable",
        "nodes": [
          {
            "id": "l1",
            "label": "Raw zone partition",
            "kind": "store",
            "sub": "provider/period/version"
          },
          {
            "id": "l2",
            "label": "Landing manifest",
            "kind": "store",
            "sub": "what arrived, when"
          }
        ]
      },
      {
        "title": "Conform",
        "nodes": [
          {
            "id": "c1",
            "label": "FOCUS cost record",
            "kind": "app",
            "sub": "provider fields kept"
          },
          {
            "id": "c2",
            "label": "FX fixed",
            "kind": "app",
            "sub": "rate at close"
          },
          {
            "id": "c3",
            "label": "Reconciled to invoice",
            "kind": "decision",
            "sub": "0.1% or $500"
          }
        ]
      },
      {
        "title": "Resolve ownership",
        "nodes": [
          {
            "id": "o1",
            "label": "Rule chain applied",
            "kind": "app",
            "sub": "tag, scope, map, exception"
          },
          {
            "id": "o2",
            "label": "Unattributed bucket",
            "kind": "risk",
            "sub": "measured, not hidden"
          }
        ]
      },
      {
        "title": "Allocate",
        "nodes": [
          {
            "id": "a1",
            "label": "Direct attribution",
            "kind": "app"
          },
          {
            "id": "a2",
            "label": "Shared apportionment",
            "kind": "app",
            "sub": "usage or request"
          },
          {
            "id": "a3",
            "label": "Commitment amortised",
            "kind": "app"
          },
          {
            "id": "a4",
            "label": "Allocated fact row",
            "kind": "store",
            "sub": "3 input versions"
          }
        ]
      },
      {
        "title": "Serve & freeze",
        "nodes": [
          {
            "id": "f1",
            "label": "Roll-up marts",
            "kind": "store",
            "sub": "dashboard reads"
          },
          {
            "id": "f2",
            "label": "Frozen statement line",
            "kind": "store",
            "sub": "immutable, 7 yr"
          },
          {
            "id": "f3",
            "label": "GL posting row",
            "kind": "integration",
            "sub": "chargeback only"
          }
        ]
      }
    ],
    "edges": [],
    "note": "Reconciliation is a gate, not a metric: a period that does not match the invoice never reaches the frozen line. Usage samples past 90 days and allocated facts past 13 months are discarded on purpose, both rebuildable from the immutable raw zone on the left.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "10-data-ownership-zones",
    "title": "Data Ownership Zones — Graded by Who Wrote It and What Losing It Costs",
    "layout": "nested",
    "canvas": {
      "width": 1760
    },
    "boxes": [
      {
        "title": "Zone 1 — Provider truth · written by the provider · RPO 24 h · re-fetchable · 37 months",
        "kind": "trust",
        "nodes": [
          {
            "id": "z1a",
            "label": "Raw export partitions",
            "kind": "store",
            "sub": "never edited"
          },
          {
            "id": "z1b",
            "label": "Invoice summaries",
            "kind": "store"
          },
          {
            "id": "z1c",
            "label": "Landing manifests",
            "kind": "store"
          }
        ]
      },
      {
        "title": "Zone 2 — Conformed facts · written by the platform · derived · rebuildable · 37 months",
        "kind": "boundary",
        "nodes": [
          {
            "id": "z2a",
            "label": "FOCUS cost records",
            "kind": "store",
            "sub": "1.2 bn/month"
          },
          {
            "id": "z2b",
            "label": "Restatement revisions",
            "kind": "store"
          },
          {
            "id": "z2c",
            "label": "Usage samples",
            "kind": "store",
            "sub": "90 d native"
          }
        ]
      },
      {
        "title": "Zone 3 — Human assertions · written by people · RPO 0 · NOT rebuildable · 7 years",
        "kind": "trust",
        "nodes": [
          {
            "id": "z3a",
            "label": "Ownership assignments",
            "kind": "store",
            "sub": "effective-dated"
          },
          {
            "id": "z3b",
            "label": "Allocation policy versions",
            "kind": "store"
          },
          {
            "id": "z3c",
            "label": "Exception registry",
            "kind": "store"
          },
          {
            "id": "z3d",
            "label": "Driver definitions",
            "kind": "store"
          }
        ]
      },
      {
        "title": "Zone 4 — Allocated facts · derived and disposable · RPO best-effort · 13 months",
        "kind": "boundary",
        "nodes": [
          {
            "id": "z4a",
            "label": "Allocated cost rows",
            "kind": "store",
            "sub": "rebuild in 24 h"
          },
          {
            "id": "z4b",
            "label": "Roll-up marts",
            "kind": "store"
          }
        ]
      },
      {
        "title": "Zone 5 — Published record · immutable · RPO 0 · legally retained · 7 years",
        "kind": "trust",
        "nodes": [
          {
            "id": "z5a",
            "label": "Frozen statements",
            "kind": "store"
          },
          {
            "id": "z5b",
            "label": "Dispute ledger",
            "kind": "store"
          },
          {
            "id": "z5c",
            "label": "GL postings",
            "kind": "store"
          },
          {
            "id": "z5d",
            "label": "Audit log",
            "kind": "store"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "z1a",
        "to": "z2a",
        "label": "conform",
        "kind": "batch"
      },
      {
        "from": "z3a",
        "to": "z4a",
        "label": "snapshot",
        "kind": "batch"
      },
      {
        "from": "z4a",
        "to": "z5a",
        "label": "freeze"
      }
    ],
    "note": "The largest and hottest store, zone 4, has the weakest durability requirement — because it is the only one that can be recomputed exactly.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "11-data-model",
    "title": "Data Model — The Spine Is Period, Cost Record, Ownership, Run, Statement",
    "layout": "er",
    "canvas": {
      "width": 1760,
      "cols": 4
    },
    "rowGap": 230,
    "entities": [
      {
        "id": "period",
        "name": "billing_period",
        "kind": "store",
        "row": 0,
        "col": 0,
        "attrs": [
          "period_id  PK",
          "provider",
          "start_date / end_date",
          "state  open|closed|restated",
          "fx_rate_fixed_at"
        ]
      },
      {
        "id": "export",
        "name": "raw_export",
        "kind": "store",
        "row": 0,
        "col": 1,
        "attrs": [
          "export_id  PK",
          "period_id  FK",
          "provider_version",
          "landed_at",
          "sha256"
        ]
      },
      {
        "id": "cost",
        "name": "cost_record",
        "kind": "store",
        "row": 0,
        "col": 2,
        "attrs": [
          "cost_record_id  PK",
          "export_id  FK",
          "resource_id  FK",
          "charge_period_start",
          "billed / effective / amortised",
          "revision_no"
        ]
      },
      {
        "id": "resource",
        "name": "resource",
        "kind": "store",
        "row": 0,
        "col": 3,
        "attrs": [
          "resource_id  PK",
          "provider_scope_id",
          "service / sku",
          "tags  jsonb",
          "first_seen / last_seen"
        ]
      },
      {
        "id": "assign",
        "name": "ownership_assignment",
        "kind": "store",
        "row": 1,
        "col": 3,
        "attrs": [
          "assignment_id  PK",
          "resource_id  FK",
          "team_id  FK",
          "valid_from / valid_to",
          "rule_fired",
          "confidence"
        ]
      },
      {
        "id": "team",
        "name": "team",
        "kind": "store",
        "row": 2,
        "col": 3,
        "attrs": [
          "team_id  PK",
          "cost_centre_id  FK",
          "product_line_id  FK",
          "valid_from / valid_to"
        ]
      },
      {
        "id": "policy",
        "name": "policy_version",
        "kind": "store",
        "row": 1,
        "col": 0,
        "attrs": [
          "policy_version_id  PK",
          "adopted_at",
          "apportionment_rules  jsonb",
          "remainder_strategy",
          "savings_attribution"
        ]
      },
      {
        "id": "pool",
        "name": "shared_pool",
        "kind": "store",
        "row": 2,
        "col": 0,
        "attrs": [
          "pool_id  PK",
          "policy_version_id  FK",
          "scope_selector",
          "basis  usage|request|even|weighted",
          "idle_treatment"
        ]
      },
      {
        "id": "run",
        "name": "allocation_run",
        "kind": "store",
        "row": 1,
        "col": 1,
        "attrs": [
          "run_id  PK",
          "period_id  FK",
          "billing_snapshot_id",
          "ownership_snapshot_id",
          "policy_version_id  FK",
          "started_at / digest"
        ]
      },
      {
        "id": "allocated",
        "name": "allocated_cost",
        "kind": "store",
        "row": 1,
        "col": 2,
        "attrs": [
          "allocated_id  PK",
          "run_id  FK",
          "cost_record_id  FK",
          "team_id  FK",
          "basis / share",
          "amount  amortised"
        ]
      },
      {
        "id": "commit",
        "name": "commitment",
        "kind": "store",
        "row": 2,
        "col": 2,
        "attrs": [
          "commitment_id  PK",
          "purchased_at",
          "term / prepaid_amount",
          "covered_scope",
          "attribution_mode"
        ]
      },
      {
        "id": "driver",
        "name": "business_driver",
        "kind": "store",
        "row": 3,
        "col": 3,
        "attrs": [
          "driver_id  PK",
          "team_id  FK",
          "definition_version",
          "reported_for_date",
          "value / cadence"
        ]
      },
      {
        "id": "stmt",
        "name": "statement",
        "kind": "store",
        "row": 2,
        "col": 1,
        "attrs": [
          "statement_id  PK",
          "team_id  FK",
          "period_id  FK",
          "version_no",
          "run_id  FK",
          "frozen_at / supersedes"
        ]
      },
      {
        "id": "line",
        "name": "statement_line",
        "kind": "store",
        "row": 3,
        "col": 0,
        "attrs": [
          "line_id  PK",
          "statement_id  FK",
          "category",
          "amount",
          "allocated_ref"
        ]
      },
      {
        "id": "dispute",
        "name": "dispute",
        "kind": "store",
        "row": 3,
        "col": 1,
        "attrs": [
          "dispute_id  PK",
          "statement_id  FK",
          "raised_by / raised_at",
          "state",
          "resolution  correct|reject"
        ]
      },
      {
        "id": "posting",
        "name": "gl_posting",
        "kind": "store",
        "row": 3,
        "col": 2,
        "attrs": [
          "posting_id  PK",
          "statement_id  FK",
          "cost_centre_id",
          "amount",
          "idempotency_key"
        ]
      }
    ],
    "relations": [
      {
        "from": "period",
        "to": "export",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "export",
        "to": "cost",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "resource",
        "to": "cost",
        "label": "1 : N",
        "from_side": "w",
        "to_side": "e"
      },
      {
        "from": "resource",
        "to": "assign",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "team",
        "to": "assign",
        "label": "1 : N",
        "from_side": "n",
        "to_side": "s"
      },
      {
        "from": "team",
        "to": "driver",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n",
        "kind": "optional"
      },
      {
        "from": "policy",
        "to": "run",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "policy",
        "to": "pool",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "run",
        "to": "allocated",
        "label": "1 : N",
        "from_side": "e",
        "to_side": "w"
      },
      {
        "from": "cost",
        "to": "allocated",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "commit",
        "to": "allocated",
        "label": "1 : N",
        "from_side": "n",
        "to_side": "s",
        "kind": "optional"
      },
      {
        "from": "run",
        "to": "stmt",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n"
      },
      {
        "from": "stmt",
        "to": "line",
        "label": "1 : N",
        "from_side": "s1",
        "to_side": "n"
      },
      {
        "from": "stmt",
        "to": "dispute",
        "label": "1 : N",
        "from_side": "s",
        "to_side": "n",
        "kind": "optional"
      },
      {
        "from": "stmt",
        "to": "posting",
        "label": "1 : 1",
        "from_side": "s3",
        "to_side": "n",
        "kind": "optional"
      }
    ],
    "note": "allocation_run carries all three input versions. Any allocated_cost row is therefore reproducible, and any statement is traceable to the exact inputs that made it.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "12-allocation-run-sequence",
    "title": "Allocation Run — A Pure Function of Three Pinned Inputs",
    "layout": "sequence",
    "canvas": {
      "width": 1680
    },
    "lifelines": [
      {
        "id": "sched",
        "label": "Scheduler",
        "kind": "platform"
      },
      {
        "id": "orch",
        "label": "Run orchestrator",
        "kind": "app"
      },
      {
        "id": "snap",
        "label": "Snapshot service",
        "kind": "app"
      },
      {
        "id": "preg",
        "label": "Policy registry",
        "kind": "security"
      },
      {
        "id": "runner",
        "label": "Allocation runner",
        "kind": "app"
      },
      {
        "id": "facts",
        "label": "Fact store",
        "kind": "store"
      },
      {
        "id": "pub",
        "label": "Statement publisher",
        "kind": "app"
      }
    ],
    "messages": [
      {
        "from": "sched",
        "to": "orch",
        "label": "start run (period, mode)",
        "kind": "call"
      },
      {
        "from": "orch",
        "to": "snap",
        "label": "pin billing snapshot",
        "kind": "call"
      },
      {
        "from": "snap",
        "to": "orch",
        "label": "billing_snapshot_id",
        "kind": "return"
      },
      {
        "from": "orch",
        "to": "snap",
        "label": "pin ownership as-of",
        "kind": "call"
      },
      {
        "from": "snap",
        "to": "orch",
        "label": "ownership_snapshot_id",
        "kind": "return"
      },
      {
        "from": "orch",
        "to": "preg",
        "label": "resolve active policy",
        "kind": "call"
      },
      {
        "from": "preg",
        "to": "orch",
        "label": "policy_version_id",
        "kind": "return"
      },
      {
        "from": "orch",
        "to": "orch",
        "label": "compute run digest",
        "kind": "self"
      },
      {
        "from": "orch",
        "to": "facts",
        "label": "digest already present?",
        "kind": "call"
      },
      {
        "from": "facts",
        "to": "orch",
        "label": "no - proceed",
        "kind": "return"
      },
      {
        "from": "orch",
        "to": "runner",
        "label": "execute (3 pinned ids)",
        "kind": "call"
      },
      {
        "from": "runner",
        "to": "runner",
        "label": "direct attribution",
        "kind": "self"
      },
      {
        "from": "runner",
        "to": "runner",
        "label": "apportion shared pools",
        "kind": "self"
      },
      {
        "from": "runner",
        "to": "runner",
        "label": "amortise commitments",
        "kind": "self"
      },
      {
        "from": "runner",
        "to": "runner",
        "label": "compute remainder",
        "kind": "self"
      },
      {
        "from": "runner",
        "to": "facts",
        "label": "write allocated facts",
        "kind": "call"
      },
      {
        "from": "runner",
        "to": "orch",
        "label": "row count + digest",
        "kind": "return"
      },
      {
        "from": "orch",
        "to": "orch",
        "label": "reconcile to invoice",
        "kind": "self"
      },
      {
        "from": "orch",
        "to": "pub",
        "label": "variance over tolerance",
        "kind": "error"
      },
      {
        "from": "orch",
        "to": "pub",
        "label": "run ready to freeze",
        "kind": "call"
      },
      {
        "from": "pub",
        "to": "sched",
        "label": "statements v1 published",
        "kind": "async"
      }
    ],
    "note": "Steps 8 to 10 make the run idempotent: an identical digest returns the existing result instead of recomputing it. Step 19 blocks publication rather than publishing a number that does not reconcile.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "13-ingestion-and-restatement",
    "title": "Ingestion and Restatement — The Bill Arrives More Than Once",
    "layout": "flow",
    "canvas": {
      "width": 1800
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Arrive",
        "nodes": [
          {
            "id": "poll",
            "label": "Export poller",
            "kind": "integration",
            "sub": "per provider, hourly"
          },
          {
            "id": "late",
            "label": "Late / missing check",
            "kind": "decision",
            "sub": "cutoff T+2"
          }
        ]
      },
      {
        "title": "Land",
        "nodes": [
          {
            "id": "land",
            "label": "Write raw partition",
            "kind": "store",
            "sub": "new version, never overwrite"
          },
          {
            "id": "man",
            "label": "Record manifest",
            "kind": "store",
            "sub": "hash, row count"
          }
        ]
      },
      {
        "title": "Inspect",
        "nodes": [
          {
            "id": "schema",
            "label": "Schema check",
            "kind": "decision",
            "sub": "drift fails loudly"
          },
          {
            "id": "quar",
            "label": "Quarantine partition",
            "kind": "risk",
            "sub": "unknown columns"
          }
        ]
      },
      {
        "title": "Compare",
        "nodes": [
          {
            "id": "diff",
            "label": "Record-grain diff",
            "kind": "app",
            "sub": "vs last ingested version"
          },
          {
            "id": "rev",
            "label": "Emit revision rows",
            "kind": "app",
            "sub": "delta, not overwrite"
          }
        ]
      },
      {
        "title": "Decide",
        "nodes": [
          {
            "id": "open",
            "label": "Period still open",
            "kind": "decision",
            "sub": "absorb silently"
          },
          {
            "id": "closed",
            "label": "Period closed",
            "kind": "decision",
            "sub": "restatement path"
          }
        ]
      },
      {
        "title": "Propagate",
        "nodes": [
          {
            "id": "rerun",
            "label": "Re-run allocation",
            "kind": "app",
            "sub": "same pure function"
          },
          {
            "id": "supers",
            "label": "Supersede statement",
            "kind": "app",
            "sub": "v2, v1 retained"
          },
          {
            "id": "notify",
            "label": "Notify over threshold",
            "kind": "integration",
            "sub": "1% or $1,000"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "late",
        "to": "notify",
        "label": "publish incomplete",
        "kind": "error",
        "route": "gutter"
      }
    ],
    "note": "Restatement is not an error path. It is the normal path executed a second time, which is only affordable because the allocation run is pure and re-runnable. A quarantined partition blocks that provider's period entirely.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "14-shared-cost-apportionment",
    "title": "Shared-Cost Apportionment — Four Pools, Four Different Honest Answers",
    "layout": "swimlane",
    "canvas": {
      "width": 1800
    },
    "laneHeaderWidth": 190,
    "stages": [
      "Identify the pool",
      "Measure consumption",
      "Choose the basis",
      "Compute the share",
      "Handle the idle",
      "Emit"
    ],
    "lanes": [
      {
        "title": "Kubernetes clusters",
        "cells": [
          [
            {
              "label": "Node cost by cluster",
              "kind": "store"
            }
          ],
          [
            {
              "label": "Pod CPU / memory",
              "kind": "app",
              "sub": "60 s samples"
            }
          ],
          [
            {
              "label": "max(request, usage)",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "Share per namespace",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Idle to platform owner",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "Allocated rows",
              "kind": "store"
            }
          ]
        ]
      },
      {
        "title": "Shared data warehouse",
        "cells": [
          [
            {
              "label": "Warehouse SKU cost",
              "kind": "store"
            }
          ],
          [
            {
              "label": "Query slot-seconds",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Measured usage",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "Share per query owner",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Reserved floor split even",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Allocated rows",
              "kind": "store"
            }
          ]
        ]
      },
      {
        "title": "Network egress",
        "cells": [
          [
            {
              "label": "Egress charges",
              "kind": "store"
            }
          ],
          [
            {
              "label": "Flow logs by workload",
              "kind": "app",
              "sub": "sampled"
            }
          ],
          [
            {
              "label": "Measured bytes",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "Share per service",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Unmatched to remainder",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "Allocated rows",
              "kind": "store"
            }
          ]
        ]
      },
      {
        "title": "Support, licences, platform fees",
        "cells": [
          [
            {
              "label": "Fixed period charge",
              "kind": "store"
            }
          ],
          [
            {
              "label": "No usage signal",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "Weighted by direct spend",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "Proportional share",
              "kind": "app"
            }
          ],
          [
            {
              "label": "None - fully spread",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Allocated rows",
              "kind": "store"
            }
          ]
        ]
      },
      {
        "title": "Commitments",
        "cells": [
          [
            {
              "label": "Prepaid / reserved",
              "kind": "store"
            }
          ],
          [
            {
              "label": "Covered usage hours",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Amortise over term",
              "kind": "decision"
            }
          ],
          [
            {
              "label": "Savings to consumer",
              "kind": "app",
              "sub": "policy choice"
            }
          ],
          [
            {
              "label": "Unused to central pool",
              "kind": "risk"
            }
          ],
          [
            {
              "label": "Amortised + cash view",
              "kind": "store"
            }
          ]
        ]
      }
    ],
    "note": "Four pools, four bases, one policy document. The rule per pool is published to its tenants before it is applied, because an apportionment nobody can follow is one nobody accepts.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "15-statement-dispute-and-restatement",
    "title": "Statement, Dispute and Restatement — Supersede, Never Overwrite",
    "layout": "sequence",
    "canvas": {
      "width": 1700
    },
    "lifelines": [
      {
        "id": "pub",
        "label": "Statement publisher",
        "kind": "app"
      },
      {
        "id": "store",
        "label": "Statement store",
        "kind": "store"
      },
      {
        "id": "lead",
        "label": "Engineering lead",
        "kind": "actor"
      },
      {
        "id": "disp",
        "label": "Dispute ledger",
        "kind": "store"
      },
      {
        "id": "fin",
        "label": "FinOps analyst",
        "kind": "actor"
      },
      {
        "id": "rc",
        "label": "Restatement controller",
        "kind": "app"
      },
      {
        "id": "runner",
        "label": "Allocation runner",
        "kind": "app"
      },
      {
        "id": "gl",
        "label": "ERP ledger",
        "kind": "external"
      }
    ],
    "messages": [
      {
        "from": "pub",
        "to": "store",
        "label": "freeze statement v1",
        "kind": "call"
      },
      {
        "from": "store",
        "to": "lead",
        "label": "published (input versions)",
        "kind": "async"
      },
      {
        "from": "pub",
        "to": "gl",
        "label": "posting, idempotency key",
        "kind": "call"
      },
      {
        "from": "lead",
        "to": "disp",
        "label": "dispute line 7",
        "kind": "call"
      },
      {
        "from": "disp",
        "to": "fin",
        "label": "queued, not blocking",
        "kind": "async"
      },
      {
        "from": "fin",
        "to": "store",
        "label": "read v1 + drill-through",
        "kind": "call"
      },
      {
        "from": "fin",
        "to": "rc",
        "label": "accept: ownership was wrong",
        "kind": "call"
      },
      {
        "from": "rc",
        "to": "runner",
        "label": "re-run, new ownership snapshot",
        "kind": "call"
      },
      {
        "from": "runner",
        "to": "rc",
        "label": "allocated facts, new digest",
        "kind": "return"
      },
      {
        "from": "rc",
        "to": "store",
        "label": "write v2, supersedes v1",
        "kind": "call"
      },
      {
        "from": "store",
        "to": "lead",
        "label": "v2 published, delta 4.1%",
        "kind": "async"
      },
      {
        "from": "store",
        "to": "fin",
        "label": "over 1% - notify",
        "kind": "async"
      },
      {
        "from": "rc",
        "to": "gl",
        "label": "adjusting posting, same key + seq",
        "kind": "call"
      },
      {
        "from": "rc",
        "to": "disp",
        "label": "resolve: corrected in v2",
        "kind": "call"
      },
      {
        "from": "fin",
        "to": "disp",
        "label": "reject with reason",
        "kind": "error"
      }
    ],
    "note": "v1 remains retrievable forever. The last message is the other half of the workflow: a dispute may be closed by a reasoned rejection, and that rejection is part of the record.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "16-anomaly-to-owner",
    "title": "Anomaly to Owner — Detect, Attribute, Route, Close",
    "layout": "flow",
    "canvas": {
      "width": 1760
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Observe",
        "nodes": [
          {
            "id": "n1",
            "label": "Daily allocated facts",
            "kind": "store",
            "sub": "T+1 by 10:00"
          },
          {
            "id": "n2",
            "label": "Rolling baseline",
            "kind": "app",
            "sub": "28-day, seasonal"
          }
        ]
      },
      {
        "title": "Detect",
        "nodes": [
          {
            "id": "n3",
            "label": "Threshold + residual test",
            "kind": "app",
            "sub": "30% sustained"
          },
          {
            "id": "n4",
            "label": "Suppression window",
            "kind": "decision",
            "sub": "declared events"
          }
        ]
      },
      {
        "title": "Attribute",
        "nodes": [
          {
            "id": "n5",
            "label": "Drill to changed dimension",
            "kind": "app",
            "sub": "service, SKU, region"
          },
          {
            "id": "n6",
            "label": "Name the resources",
            "kind": "app",
            "sub": "top contributors"
          }
        ]
      },
      {
        "title": "Route",
        "nodes": [
          {
            "id": "n7",
            "label": "Resolve accountable owner",
            "kind": "app"
          },
          {
            "id": "n8",
            "label": "Escalate to parent scope",
            "kind": "risk",
            "sub": "if unattributed"
          }
        ]
      },
      {
        "title": "Close",
        "nodes": [
          {
            "id": "n9",
            "label": "Acknowledged & explained",
            "kind": "app"
          },
          {
            "id": "n10",
            "label": "Feeds baseline",
            "kind": "app",
            "sub": "accepted step change"
          },
          {
            "id": "n11",
            "label": "False positive recorded",
            "kind": "risk",
            "sub": "budget 5/team/quarter"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "n11",
        "to": "n3",
        "label": "retune detector",
        "kind": "error",
        "route": "gutter"
      }
    ],
    "note": "An alert that cannot name a resource is a page to nobody, so attribution happens before routing. A suppressed detection is logged and closed without routing.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "17-deployment-architecture",
    "title": "Deployment — One Region Serves, One Region Holds the Record",
    "layout": "nested",
    "canvas": {
      "width": 1780
    },
    "boxes": [
      {
        "title": "Azure West Europe — primary",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "Zone 1",
            "kind": "boundary",
            "nodes": [
              {
                "id": "aks1",
                "label": "AKS node pool",
                "kind": "app",
                "sub": "serving"
              },
              {
                "id": "sql1",
                "label": "Azure SQL primary",
                "kind": "store",
                "sub": "statements, RPO 0"
              }
            ]
          },
          {
            "title": "Zone 2",
            "kind": "boundary",
            "nodes": [
              {
                "id": "aks2",
                "label": "AKS node pool",
                "kind": "app",
                "sub": "serving"
              },
              {
                "id": "sql2",
                "label": "Sync replica",
                "kind": "store",
                "sub": "zone-redundant"
              }
            ]
          },
          {
            "title": "Zone 3 — batch",
            "kind": "boundary",
            "nodes": [
              {
                "id": "spark",
                "label": "Spark pools",
                "kind": "app",
                "sub": "spot, interruptible"
              },
              {
                "id": "adx1",
                "label": "Fact store cluster",
                "kind": "store",
                "sub": "1.2 bn rows/mo"
              }
            ]
          },
          {
            "title": "Region-wide",
            "kind": "boundary",
            "nodes": [
              {
                "id": "adls1",
                "label": "Raw landing zone",
                "kind": "store",
                "sub": "ZRS, immutable blobs"
              },
              {
                "id": "kv1",
                "label": "Key Vault",
                "kind": "security",
                "sub": "CMK"
              },
              {
                "id": "eh1",
                "label": "Event Hubs",
                "kind": "queue",
                "sub": "usage telemetry"
              }
            ]
          }
        ]
      },
      {
        "title": "Azure North Europe — recovery",
        "kind": "cloud",
        "dir": "row",
        "children": [
          {
            "title": "Record of truth",
            "kind": "trust",
            "nodes": [
              {
                "id": "sqldr",
                "label": "Geo-replica",
                "kind": "store",
                "sub": "statements, audit"
              },
              {
                "id": "adlsdr",
                "label": "Raw zone GRS copy",
                "kind": "store",
                "sub": "rebuild source"
              }
            ]
          },
          {
            "title": "Cold serving",
            "kind": "boundary",
            "nodes": [
              {
                "id": "aksdr",
                "label": "AKS, scaled to zero",
                "kind": "app",
                "sub": "RTO 4 h"
              },
              {
                "id": "adxdr",
                "label": "Fact store, rebuilt",
                "kind": "store",
                "sub": "RTO 24 h"
              }
            ]
          }
        ]
      }
    ],
    "outside": [
      {
        "id": "provx",
        "label": "Provider billing exports",
        "kind": "external",
        "sub": "3 clouds"
      },
      {
        "id": "kmetx",
        "label": "Cluster metrics",
        "kind": "external"
      },
      {
        "id": "erpz",
        "label": "ERP general ledger",
        "kind": "external"
      }
    ],
    "edges": [
      {
        "from": "sql1",
        "to": "sqldr",
        "label": "geo-replication",
        "kind": "async"
      },
      {
        "from": "adls1",
        "to": "adlsdr",
        "label": "GRS",
        "kind": "batch"
      }
    ],
    "note": "The recovery region holds what cannot be recomputed and rebuilds what can - the recovery fact store is rebuilt from the replicated raw zone. That asymmetry is why RTO is 4 hours for serving and 24 for the full fact store.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "18-policy-promotion-pipeline",
    "title": "Policy Promotion — A Rule Change Moves Money, So It Ships Like Code",
    "layout": "flow",
    "canvas": {
      "width": 1800
    },
    "chain": true,
    "align": "top",
    "stages": [
      {
        "title": "Author",
        "nodes": [
          {
            "id": "p1",
            "label": "Rule change in Git",
            "kind": "app",
            "sub": "declarative, reviewable"
          },
          {
            "id": "p2",
            "label": "Schema & lint gate",
            "kind": "decision"
          }
        ]
      },
      {
        "title": "Simulate",
        "nodes": [
          {
            "id": "p3",
            "label": "Re-run closed period",
            "kind": "app",
            "sub": "candidate vs current"
          },
          {
            "id": "p4",
            "label": "Per-team delta report",
            "kind": "store",
            "sub": "who moves, by how much"
          }
        ]
      },
      {
        "title": "Review",
        "nodes": [
          {
            "id": "p5",
            "label": "FinOps + affected owners",
            "kind": "actor",
            "sub": "over 2% delta"
          },
          {
            "id": "p6",
            "label": "Finance sign-off",
            "kind": "decision",
            "sub": "if chargeback on"
          }
        ]
      },
      {
        "title": "Adopt",
        "nodes": [
          {
            "id": "p7",
            "label": "New policy version",
            "kind": "security",
            "sub": "effective-dated"
          },
          {
            "id": "p8",
            "label": "Published to tenants",
            "kind": "integration",
            "sub": "before it applies"
          }
        ]
      },
      {
        "title": "Apply",
        "nodes": [
          {
            "id": "p9",
            "label": "Next allocation run",
            "kind": "app",
            "sub": "pinned to version"
          },
          {
            "id": "p10",
            "label": "Statement notes the version",
            "kind": "store"
          }
        ]
      },
      {
        "title": "Reverse",
        "nodes": [
          {
            "id": "p11",
            "label": "Roll back to prior version",
            "kind": "app",
            "sub": "one command"
          },
          {
            "id": "p12",
            "label": "Re-run affected periods",
            "kind": "app",
            "sub": "45 min p95"
          }
        ]
      }
    ],
    "edges": [],
    "note": "Application code deploys the same way, but policy ships on its own pipeline because its blast radius is every team's number. A delta the reviewers reject never reaches Adopt; a delta that surprises after adoption is reversed at Reverse, and the affected periods are re-run.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "19-observability",
    "title": "Observability — What Is Watched at Each Stage, and What Pages",
    "layout": "grid",
    "canvas": {
      "width": 1800
    },
    "laneHeaderWidth": 190,
    "columns": [
      "Ingest",
      "Conform",
      "Allocate",
      "Publish",
      "Serve"
    ],
    "rows": [
      {
        "title": "Freshness",
        "cells": [
          [
            {
              "label": "Export landed by 06:00",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Conformed by 09:00",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Facts by 10:00 T+1",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Frozen in 5 days",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Mart lag under 1 h",
              "kind": "app"
            }
          ]
        ]
      },
      {
        "title": "Correctness",
        "cells": [
          [
            {
              "label": "Row count vs manifest",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Invoice variance",
              "kind": "risk",
              "sub": "pages"
            }
          ],
          [
            {
              "label": "Digest reproducibility",
              "kind": "risk",
              "sub": "pages"
            }
          ],
          [
            {
              "label": "Sum of lines = total",
              "kind": "risk",
              "sub": "pages"
            }
          ],
          [
            {
              "label": "Drill-through sums back",
              "kind": "app"
            }
          ]
        ]
      },
      {
        "title": "Coverage",
        "cells": [
          [
            {
              "label": "Providers reporting",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Unknown SKUs",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Unallocated %",
              "kind": "risk",
              "sub": "SLO 2%"
            }
          ],
          [
            {
              "label": "Teams with a statement",
              "kind": "app"
            }
          ],
          []
        ]
      },
      {
        "title": "Volume & cost",
        "cells": [
          [
            {
              "label": "Bytes landed / day",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Rows conformed",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Run minutes & spot loss",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Statements per close",
              "kind": "app"
            }
          ],
          [
            {
              "label": "Query cost per team",
              "kind": "app"
            }
          ]
        ]
      },
      {
        "title": "Audit",
        "cells": [
          [
            {
              "label": "Credential use",
              "kind": "security"
            }
          ],
          [
            {
              "label": "Quarantine events",
              "kind": "security"
            }
          ],
          [
            {
              "label": "Policy version applied",
              "kind": "security"
            }
          ],
          [
            {
              "label": "Freeze & restate events",
              "kind": "security"
            }
          ],
          [
            {
              "label": "Cross-team reads",
              "kind": "security"
            }
          ]
        ]
      }
    ],
    "note": "Only five cells page a human, and four of them are correctness rather than availability. A dashboard that is an hour stale is an inconvenience; a number that does not reconcile is the failure this platform exists to avoid.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "20-monthly-close-loop",
    "title": "The Monthly Close Loop — Where the Platform Actually Lives",
    "layout": "cycle",
    "canvas": {
      "width": 1500
    },
    "centre": {
      "label": "Close cycle",
      "sub": "one per period"
    },
    "rx": 430,
    "ry": 215,
    "nodes": [
      {
        "id": "c1",
        "label": "Exports land",
        "kind": "integration",
        "sub": "daily, T+1"
      },
      {
        "id": "c2",
        "label": "Conform & reconcile",
        "kind": "app",
        "sub": "to the invoice"
      },
      {
        "id": "c3",
        "label": "Allocate",
        "kind": "app",
        "sub": "3 pinned inputs"
      },
      {
        "id": "c4",
        "label": "Freeze & publish",
        "kind": "store",
        "sub": "5 business days"
      },
      {
        "id": "c5",
        "label": "Dispute & restate",
        "kind": "app",
        "sub": "90-day window"
      },
      {
        "id": "c6",
        "label": "Review policy & coverage",
        "kind": "security",
        "sub": "what to fix next"
      }
    ],
    "ringLabels": [
      "raw partitions",
      "conformed facts",
      "allocated facts",
      "statements v1",
      "statements v2",
      "next policy version"
    ],
    "note": "The loop is the product. A platform that only runs the first four steps is a report; the last two are what make the next month's number better than this one's.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "21-security-trust-zones",
    "title": "Trust Zones — Cost Data Discloses Architecture, Headcount and Roadmap",
    "layout": "zones",
    "canvas": {
      "width": 1740
    },
    "zones": [
      {
        "title": "Provider billing boundary — outside our control",
        "kind": "trust",
        "nodes": [
          {
            "id": "s1",
            "label": "AWS billing export",
            "kind": "external"
          },
          {
            "id": "s2",
            "label": "Azure Cost Management",
            "kind": "external"
          },
          {
            "id": "s3",
            "label": "Google Cloud billing",
            "kind": "external"
          },
          {
            "id": "s4",
            "label": "Vendor invoice portals",
            "kind": "external"
          }
        ]
      },
      {
        "title": "Corporate access zone — authenticated humans",
        "kind": "trust",
        "nodes": [
          {
            "id": "s5",
            "label": "Engineering lead",
            "kind": "actor",
            "sub": "own team only"
          },
          {
            "id": "s6",
            "label": "Product owner",
            "kind": "actor",
            "sub": "own line"
          },
          {
            "id": "s7",
            "label": "Finance & FinOps",
            "kind": "actor",
            "sub": "estate-wide"
          },
          {
            "id": "s8",
            "label": "Entra ID",
            "kind": "security",
            "sub": "MFA enforced"
          }
        ]
      },
      {
        "title": "Application zone — private endpoints, no public ingress",
        "kind": "trust",
        "nodes": [
          {
            "id": "s9",
            "label": "Query & statement API",
            "kind": "integration",
            "sub": "scope-filtered"
          },
          {
            "id": "s10",
            "label": "Dashboard",
            "kind": "app"
          },
          {
            "id": "s11",
            "label": "Batch runners",
            "kind": "app",
            "sub": "workload identity"
          },
          {
            "id": "s12",
            "label": "Policy & ownership admin",
            "kind": "security",
            "sub": "separate role"
          }
        ]
      },
      {
        "title": "Restricted data zone — no human standing access",
        "kind": "trust",
        "nodes": [
          {
            "id": "s13",
            "label": "Raw landing zone",
            "kind": "store",
            "sub": "immutable blobs"
          },
          {
            "id": "s14",
            "label": "Cost fact store",
            "kind": "store"
          },
          {
            "id": "s15",
            "label": "Statement & audit store",
            "kind": "store",
            "sub": "7 years"
          },
          {
            "id": "s16",
            "label": "Key Vault",
            "kind": "security",
            "sub": "CMK"
          }
        ]
      }
    ],
    "edges": [
      {
        "from": "s1",
        "to": "s13",
        "label": "export role",
        "kind": "batch"
      },
      {
        "from": "s5",
        "to": "s9",
        "label": "team scope"
      },
      {
        "from": "s7",
        "to": "s9",
        "label": "estate scope"
      },
      {
        "from": "s11",
        "to": "s14",
        "label": "workload id"
      },
      {
        "from": "s12",
        "to": "s15",
        "label": "approved, audited"
      }
    ],
    "note": "The credentials that read a provider's bill cannot reach that provider's workloads. That separation is what lets a read-only measurement platform hold estate-wide credentials at all.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  },
  {
    "id": "22-identity-and-access",
    "title": "Identity and Access — Who Is Allowed to See Whose Bill",
    "layout": "sequence",
    "canvas": {
      "width": 1680
    },
    "lifelines": [
      {
        "id": "u",
        "label": "Engineering lead",
        "kind": "actor"
      },
      {
        "id": "idp",
        "label": "Entra ID",
        "kind": "security"
      },
      {
        "id": "api",
        "label": "Query API",
        "kind": "integration"
      },
      {
        "id": "auth",
        "label": "Scope resolver",
        "kind": "security"
      },
      {
        "id": "org",
        "label": "Org tree",
        "kind": "store"
      },
      {
        "id": "facts",
        "label": "Fact store",
        "kind": "store"
      },
      {
        "id": "aud",
        "label": "Audit log",
        "kind": "store"
      }
    ],
    "messages": [
      {
        "from": "u",
        "to": "idp",
        "label": "sign in, MFA",
        "kind": "call"
      },
      {
        "from": "idp",
        "to": "u",
        "label": "token + group claims",
        "kind": "return"
      },
      {
        "from": "u",
        "to": "api",
        "label": "GET /statements?team=X",
        "kind": "call"
      },
      {
        "from": "api",
        "to": "auth",
        "label": "resolve scope for subject",
        "kind": "call"
      },
      {
        "from": "auth",
        "to": "org",
        "label": "teams owned as of date",
        "kind": "call"
      },
      {
        "from": "org",
        "to": "auth",
        "label": "team set (effective-dated)",
        "kind": "return"
      },
      {
        "from": "auth",
        "to": "api",
        "label": "predicate: team in set",
        "kind": "return"
      },
      {
        "from": "api",
        "to": "api",
        "label": "inject predicate, reject override",
        "kind": "self"
      },
      {
        "from": "api",
        "to": "facts",
        "label": "scoped query",
        "kind": "call"
      },
      {
        "from": "facts",
        "to": "api",
        "label": "rows within scope",
        "kind": "return"
      },
      {
        "from": "api",
        "to": "aud",
        "label": "log subject, scope, grain",
        "kind": "async"
      },
      {
        "from": "api",
        "to": "u",
        "label": "statement + drill-through",
        "kind": "return"
      },
      {
        "from": "u",
        "to": "api",
        "label": "GET /statements?team=Y",
        "kind": "call"
      },
      {
        "from": "api",
        "to": "u",
        "label": "aggregate only, no resources",
        "kind": "error"
      },
      {
        "from": "api",
        "to": "aud",
        "label": "log cross-team read",
        "kind": "async"
      }
    ],
    "note": "The scope predicate is injected server-side and cannot be overridden by a query parameter. Out-of-scope reads are answered at aggregate grain rather than refused, because a flat denial teaches nothing and drives people to spreadsheets.",
    "meta": {
      "v": "1.0",
      "owner": "Platform Architecture",
      "date": "2026-09"
    }
  }
]
