<svg width="100%" viewBox="0 0 760 700" role="img" xmlns="http://www.w3.org/2000/svg">
  <title>WhatsApp turn — Twilio webhook to phone-routed family agent</title>
  <desc>Twilio webhook hits sudo-api; signature is verified; sender phone is looked up in family_members; payload forwarded to the owning account's hermes plugin; reply goes back via Twilio REST.</desc>
  <style>
    text{font-family:"Anthropic Sans",-apple-system,system-ui,"Segoe UI",sans-serif}
    .t{font-size:14px;font-weight:500;text-anchor:middle;dominant-baseline:central}
    .s{font-size:12px;text-anchor:middle;dominant-baseline:central}
    .stp{font-size:12px;fill:#c2c0b6}
    rect{stroke-width:.5}
    .neutral{fill:#444441;stroke:#b4b2a9} .nt{fill:#d3d1c7} .ns{fill:#b4b2a9}
    .blue{fill:#1f3b7a;stroke:#8aaef0}    .bt{fill:#cfdcf4} .bs{fill:#8aaef0}
    .orange{fill:#712b13;stroke:#f0997b}  .ot{fill:#f5c4b3} .os{fill:#f0997b}
    .purple{fill:#3c3489;stroke:#afa9ec}  .pt{fill:#ceccf6} .ps{fill:#afa9ec}
    .arrow{fill:none;stroke:#9c9a92;stroke-width:1.5}
    .arrow-ok{fill:none;stroke:#1d9e75;stroke-width:1.5}
  </style>
  <defs>
    <marker id="a" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
      <path d="M2 1L8 5L2 9" fill="none" stroke="context-stroke" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
    </marker>
  </defs>

  <text class="stp" x="40" y="64">1</text>
  <text class="stp" x="40" y="164">2</text>
  <text class="stp" x="40" y="264">3</text>
  <text class="stp" x="40" y="364">4</text>
  <text class="stp" x="40" y="464">5</text>
  <text class="stp" x="40" y="564">6</text>
  <text class="stp" x="40" y="664">7</text>

  <rect class="neutral" x="120" y="40" width="560" height="60" rx="8"/>
  <text class="t nt" x="400" y="64">User sends a WhatsApp message to the shared sender number</text>
  <text class="s ns" x="400" y="84">phone (WhatsApp app)</text>

  <rect class="purple" x="120" y="140" width="560" height="60" rx="8"/>
  <text class="t pt" x="400" y="164">Twilio delivers the inbound</text>
  <text class="s ps" x="400" y="184">POST /v1/twilio/whatsapp/inbound  ·  X-Twilio-Signature</text>

  <rect class="blue" x="120" y="240" width="560" height="60" rx="8"/>
  <text class="t bt" x="400" y="264">sudo-api verifies the signature</text>
  <text class="s bs" x="400" y="284">defense-in-depth: Caddy also rejects /v1/internal/*</text>

  <rect class="blue" x="120" y="340" width="560" height="60" rx="8"/>
  <text class="t bt" x="400" y="364">sudo-api looks up sender phone → owning account</text>
  <text class="s bs" x="400" y="384">SELECT … FROM public.family_members WHERE phone = …</text>

  <rect class="orange" x="120" y="440" width="560" height="60" rx="8"/>
  <text class="t ot" x="400" y="464">sudo-api forwards to that account's hermes plugin</text>
  <text class="s os" x="400" y="484">POST :8651/inbound  ·  internal bearer  ·  agent runs</text>

  <rect class="orange" x="120" y="540" width="560" height="60" rx="8"/>
  <text class="t ot" x="400" y="564">hermes adapter sends the reply</text>
  <text class="s os" x="400" y="584">Twilio REST  ·  Messages.json</text>

  <rect class="neutral" x="120" y="640" width="560" height="44" rx="8"/>
  <text class="t nt" x="400" y="662">User receives the reply in WhatsApp</text>

  <path class="arrow"    d="M 400 100 L 400 138" marker-end="url(#a)"/>
  <path class="arrow"    d="M 400 200 L 400 238" marker-end="url(#a)"/>
  <path class="arrow"    d="M 400 300 L 400 338" marker-end="url(#a)"/>
  <path class="arrow"    d="M 400 400 L 400 438" marker-end="url(#a)"/>
  <path class="arrow"    d="M 400 500 L 400 538" marker-end="url(#a)"/>
  <path class="arrow-ok" d="M 400 600 L 400 638" marker-end="url(#a)"/>
</svg>
