Gunnar

nordisk/monetize

docs/integration-v2.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1560 1090" width="1560" height="1090" font-family="'DejaVu Sans', 'Segoe UI', sans-serif">
  <defs>
    <linearGradient id="board" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#0b1c2e"/><stop offset="1" stop-color="#06111d"/></linearGradient>
    <linearGradient id="chip" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#14384f"/><stop offset="1" stop-color="#0e2a3e"/></linearGradient>
    <linearGradient id="rail" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#173d57"/><stop offset="1" stop-color="#0c2438"/></linearGradient>
    <linearGradient id="slot" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#123448"/><stop offset="1" stop-color="#0a2032"/></linearGradient>
    <marker id="head" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#a9c3d4"/></marker>
    <marker id="headw" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#dff1ff"/></marker>
  </defs>
  <rect x="0" y="0" width="1560" height="1090" fill="url(#board)"/>
  <g stroke="#143a52" stroke-width="1"><line x1="0" y1="84" x2="1560" y2="84"/><line x1="0" y1="1054" x2="1560" y2="1054"/></g>
  <g fill="#16415c"><circle cx="40" cy="20" r="2"/><circle cx="1520" cy="20" r="2"/><circle cx="40" cy="1072" r="2"/><circle cx="1520" cy="1072" r="2"/></g>
  <text x="40" y="44" fill="#eaf6ff" font-size="22" font-weight="700">monetize v2.0</text>
  <text x="250" y="44" fill="#9fc9e0" font-size="15">the plugins of the ONE box, and who writes each one</text>
  <rect x="800" y="33" width="24" height="14" rx="3" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <text x="832" y="44" fill="#cfe6f5" font-size="12">you write it (the integrator)</text>
  <rect x="1048.88" y="33" width="24" height="14" rx="3" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <text x="1080.88" y="44" fill="#cfe6f5" font-size="12">premade · open monetize</text>
  <rect x="800" y="59" width="24" height="14" rx="3" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8"/>
  <text x="832" y="70" fill="#cfe6f5" font-size="12">premade · monetize-impl, signed</text>
  <rect x="1062.32" y="59" width="24" height="14" rx="3" fill="url(#chip)" stroke="#9fb4c4" stroke-width="1.8"/>
  <text x="1094.32" y="70" fill="#cfe6f5" font-size="12">outside · the operator</text>
  <rect x="1264.1599999999999" y="59" width="24" height="14" rx="3" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8" stroke-dasharray="4 3"/>
  <text x="1296.1599999999999" y="70" fill="#cfe6f5" font-size="12">stub · lowest priority</text>
  <rect x="30" y="110" width="340" height="50" rx="7" fill="url(#chip)" stroke="#9fb4c4" stroke-width="1.8"/>
  <rect x="31" y="118" width="4" height="34" rx="2" fill="#9fb4c4" fill-opacity="0.85"/>
  <text x="42" y="128" fill="#eaf6ff" font-size="12.5" font-weight="700">The buyer's browser</text>
  <text x="42" y="143" fill="#9fc9e0" font-size="10">sees your pages only, and the vendor's checkout page</text>
  <rect x="30" y="176" width="340" height="696" rx="12" fill="url(#rail)" fill-opacity="0.55" stroke="#7CFFB2" stroke-opacity="0.75" stroke-width="2"/>
  <text x="46" y="200" fill="#7CFFB2" font-size="14.5" font-weight="700">YOU WRITE</text>
  <rect x="400" y="176" width="780" height="696" rx="12" fill="url(#rail)" fill-opacity="0.55" stroke="#6fd3f5" stroke-opacity="0.75" stroke-width="2"/>
  <text x="416" y="200" fill="#6fd3f5" font-size="14.5" font-weight="700">THE ONE BOX</text>
  <text x="536.46" y="200" fill="#86b3cc" font-size="11">monetize-admin (PID 1) runs the open monetize-server</text>
  <rect x="1210" y="176" width="320" height="696" rx="12" fill="url(#rail)" fill-opacity="0.55" stroke="#9fb4c4" stroke-opacity="0.75" stroke-width="2"/>
  <text x="1226" y="200" fill="#9fb4c4" font-size="14.5" font-weight="700">OUTSIDE</text>
  <text x="1307.02" y="200" fill="#86b3cc" font-size="11">the vendors' APIs</text>
  <rect x="44" y="212" width="312" height="108" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="45" y="220" width="4" height="92" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="56" y="230" fill="#eaf6ff" font-size="12.5" font-weight="700">Your site</text>
  <text x="56" y="245" fill="#9fc9e0" font-size="10">gunnar.rs · holger.rs · the Lake's site</text>
  <text x="56" y="260" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">impl BuySite: who · ticket · held_caps</text>
  <text x="56" y="275" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  signup_account · stepped_up</text>
  <text x="56" y="290" fill="#9fc9e0" font-size="10">mounts the relay; your markup and CSS</text>
  <text x="56" y="305" fill="#6fd3f5" font-size="10">links monetize-site-buy (relay, buy_js)</text>
  <rect x="44" y="334" width="312" height="70" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="45" y="342" width="4" height="54" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="56" y="352" fill="#eaf6ff" font-size="12.5" font-weight="700">Your declaration</text>
  <text x="56" y="367" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">[products.&lt;id&gt;] in the feed (solo.toml)</text>
  <text x="56" y="382" fill="#9fc9e0" font-size="10">module + sha256 pin · prices · bundles · plans</text>
  <text x="56" y="395" fill="#7CFFB2" font-size="10" font-weight="700">you + the operator</text>
  <rect x="44" y="418" width="312" height="124" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="45" y="426" width="4" height="108" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="56" y="436" fill="#eaf6ff" font-size="12.5" font-weight="700">Your estate's boxes</text>
  <text x="56" y="451" fill="#9fc9e0" font-size="10">front · main · twin, or the Lake's roles</text>
  <text x="56" y="466" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">impl Estate: report · execute · box_key [P3]</text>
  <text x="56" y="481" fill="#9fc9e0" font-size="10">runs the orders it pulls; an unknown kind</text>
  <text x="56" y="496" fill="#9fc9e0" font-size="10">is refused BY NAME; never called into</text>
  <text x="56" y="511" fill="#6fd3f5" font-size="10">links nordisk-pairing · monetize-estate-side</text>
  <text x="56" y="526" fill="#6fd3f5" font-size="10">  (the Fleet pump)</text>
  <rect x="44" y="556" width="312" height="86" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="45" y="564" width="4" height="70" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="56" y="574" fill="#eaf6ff" font-size="12.5" font-weight="700">Your product operator's source</text>
  <text x="56" y="589" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">crates/&lt;id&gt;-monetize-guest</text>
  <text x="56" y="604" fill="#6fd3f5" font-size="10">links monetize-product-guest (the SDK)</text>
  <text x="56" y="619" fill="#9fc9e0" font-size="10">built + signed by the Build Thing, then</text>
  <text x="56" y="634" fill="#9fc9e0" font-size="10">it sits in the PRODUCT slot →</text>
  <text x="46" y="666" fill="#6fd3f5" font-size="12" font-weight="700">LINKED, NOT PLUGINS</text>
  <text x="211.04000000000002" y="666" fill="#86b3cc" font-size="10.5">premade, open</text>
  <rect x="44" y="676" width="312" height="44" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="45" y="684" width="4" height="28" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="56" y="694" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">monetize-product-guest</text>
  <text x="56" y="709" fill="#9fc9e0" font-size="10">the operator SDK: ops, wire, export_product!</text>
  <rect x="44" y="726" width="312" height="44" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="45" y="734" width="4" height="28" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="56" y="744" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">monetize-site-buy</text>
  <text x="56" y="759" fill="#9fc9e0" font-size="10">BuySite, the relay (26 routes), buy_js</text>
  <rect x="44" y="776" width="312" height="44" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="45" y="784" width="4" height="28" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="56" y="794" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">nordisk-pairing</text>
  <text x="56" y="809" fill="#9fc9e0" font-size="10">pairing + the live door (Skidbladnir)</text>
  <rect x="44" y="826" width="312" height="44" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="45" y="834" width="4" height="28" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="56" y="844" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">monetize-estate-side</text>
  <text x="56" y="859" fill="#9fc9e0" font-size="10">the box pump: Report · Orders · Ask</text>
  <rect x="420" y="212" width="740" height="112" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="421" y="220" width="4" height="96" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="432" y="230" fill="#eaf6ff" font-size="13" font-weight="700">monetize-server · the open core (AGPL)</text>
  <text x="432" y="245" fill="#9fc9e0" font-size="10">ledger · estate state machine · custody · site book · guardian · nonpay · mail · operator console</text>
  <text x="432" y="260" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">instantiate = lay → install → sale check → capture → DNS → ready</text>
  <text x="432" y="275" fill="#9fc9e0" font-size="10">doors: sites (Signup · EstateOrder · Purchase) · boxes (Fleet: Report · Orders · Ask) · /callback/&lt;vendor&gt;</text>
  <text x="432" y="290" fill="#9fc9e0" font-size="10">knows no product name [P3] · vendor keys stay here; a guest reads key NAMES only</text>
  <text x="432" y="305" fill="#9fc9e0" font-size="10">runs every plugin in its guest host: fuel, deadline, memory cap, signature checked</text>
  <text x="420" y="350" fill="#eaf6ff" font-size="13.5" font-weight="700">PLUGINS</text>
  <text x="496.26" y="350" fill="#86b3cc" font-size="10.5">a .wasm guest, signed and pinned by sha256, pulled from the bucket · or linked into the open binary</text>
  <rect x="430" y="362" width="730" height="112" rx="10" fill="url(#rail)" stroke="#5aa6cf" stroke-opacity="0.6" stroke-width="1.4"/>
  <text x="442" y="381" fill="#eaf6ff" font-size="12.5" font-weight="700">PRODUCT</text>
  <text x="519.5" y="381" fill="#86b3cc" font-size="10.5">trait Product · 6 pure ops [P2] (manifest · facts · plan · diagnose · remedy · observe) · 0 grants</text>
  <rect x="442" y="392" width="229" height="72" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="443" y="400" width="4" height="56" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="454" y="410" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">gunnar_monetize_guest.wasm</text>
  <text x="454" y="425" fill="#9fc9e0" font-size="10">Gunnar's: gunnar/crates/…</text>
  <text x="454" y="455" fill="#7CFFB2" font-size="10" font-weight="700">you write · signed</text>
  <rect x="681" y="392" width="229" height="72" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="682" y="400" width="4" height="56" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="693" y="410" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">holger_monetize_guest.wasm</text>
  <text x="693" y="425" fill="#9fc9e0" font-size="10">Holger's: holger/crates/…</text>
  <text x="693" y="455" fill="#7CFFB2" font-size="10" font-weight="700">you write · signed</text>
  <rect x="919" y="392" width="229" height="72" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="920" y="400" width="4" height="56" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="931" y="410" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">the Lake's product operator</text>
  <text x="931" y="425" fill="#9fc9e0" font-size="10">the reference: a thin operator +</text>
  <text x="931" y="440" fill="#9fc9e0" font-size="10">its shape as data (facts)</text>
  <text x="931" y="455" fill="#7CFFB2" font-size="10" font-weight="700">you write · example, open</text>
  <rect x="430" y="486" width="730" height="112" rx="10" fill="url(#rail)" stroke="#5aa6cf" stroke-opacity="0.6" stroke-width="1.4"/>
  <text x="442" y="505" fill="#eaf6ff" font-size="12.5" font-weight="700">PAYMENT</text>
  <text x="519.5" y="505" fill="#86b3cc" font-size="10.5">trait Payment · 10 ops: page · status · capture · release · refund · callback …</text>
  <rect x="442" y="516" width="165" height="72" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8"/>
  <rect x="443" y="524" width="4" height="56" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="454" y="534" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">stripe.wasm</text>
  <text x="454" y="549" fill="#9fc9e0" font-size="10">live · the main one</text>
  <text x="454" y="579" fill="#ffcf6f" font-size="10" font-weight="700">monetize-impl · signed</text>
  <rect x="617" y="516" width="112" height="72" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8" stroke-dasharray="5 4"/>
  <rect x="618" y="524" width="4" height="56" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="629" y="534" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">klarna.wasm</text>
  <text x="629" y="549" fill="#9fc9e0" font-size="10">with holds</text>
  <text x="629" y="579" fill="#ffcf6f" font-size="10" font-weight="700">stub · low</text>
  <rect x="739" y="516" width="112" height="72" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8" stroke-dasharray="5 4"/>
  <rect x="740" y="524" width="4" height="56" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="751" y="534" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">swish.wasm</text>
  <text x="751" y="549" fill="#9fc9e0" font-size="10">no hold</text>
  <text x="751" y="579" fill="#ffcf6f" font-size="10" font-weight="700">stub · low</text>
  <rect x="861" y="516" width="99" height="72" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="862" y="524" width="4" height="56" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="873" y="534" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">invoice</text>
  <text x="873" y="549" fill="#9fc9e0" font-size="10">SE/FI, no card</text>
  <text x="873" y="579" fill="#6fd3f5" font-size="10" font-weight="700">open · linked</text>
  <rect x="970" y="516" width="178" height="72" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="971" y="524" width="4" height="56" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="982" y="534" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">sandbox</text>
  <text x="982" y="549" fill="#9fc9e0" font-size="10">always money, no socket</text>
  <text x="982" y="579" fill="#6fd3f5" font-size="10" font-weight="700">open · money-free default</text>
  <rect x="430" y="610" width="730" height="112" rx="10" fill="url(#rail)" stroke="#5aa6cf" stroke-opacity="0.6" stroke-width="1.4"/>
  <text x="442" y="629" fill="#eaf6ff" font-size="12.5" font-weight="700">CLOUD</text>
  <text x="502.5" y="629" fill="#86b3cc" font-size="10.5">trait Cloud · 9 ops: catalog · price · lay · change · boot · firewall · destroy · inventory</text>
  <rect x="442" y="640" width="165" height="72" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8"/>
  <rect x="443" y="648" width="4" height="56" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="454" y="658" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">upcloud.wasm</text>
  <text x="454" y="673" fill="#9fc9e0" font-size="10">live · the main one</text>
  <text x="454" y="703" fill="#ffcf6f" font-size="10" font-weight="700">monetize-impl · signed</text>
  <rect x="617" y="640" width="165" height="72" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8" stroke-dasharray="5 4"/>
  <rect x="618" y="648" width="4" height="56" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="629" y="658" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">scaleway.wasm</text>
  <text x="629" y="673" fill="#9fc9e0" font-size="10">Cloud, the same 9 ops</text>
  <text x="629" y="703" fill="#ffcf6f" font-size="10" font-weight="700">stub · low</text>
  <rect x="792" y="640" width="165" height="72" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="793" y="648" width="4" height="56" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="804" y="658" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">server</text>
  <text x="804" y="673" fill="#9fc9e0" font-size="10">the box's own iron;</text>
  <text x="804" y="688" fill="#9fc9e0" font-size="10">it never buys anything</text>
  <text x="804" y="703" fill="#6fd3f5" font-size="10" font-weight="700">open · linked</text>
  <rect x="967" y="640" width="181" height="72" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="968" y="648" width="4" height="56" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="979" y="658" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">sandbox</text>
  <text x="979" y="673" fill="#9fc9e0" font-size="10">fake iron at real prices</text>
  <text x="979" y="703" fill="#6fd3f5" font-size="10" font-weight="700">open · money-free default</text>
  <rect x="430" y="734" width="730" height="112" rx="10" fill="url(#rail)" stroke="#5aa6cf" stroke-opacity="0.6" stroke-width="1.4"/>
  <text x="442" y="753" fill="#eaf6ff" font-size="12.5" font-weight="700">DNS</text>
  <text x="485.5" y="753" fill="#86b3cc" font-size="10.5">trait DnsWriter · 6 ops: write · write_taking_over · remove · listed · settled</text>
  <rect x="442" y="764" width="371" height="72" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8"/>
  <rect x="443" y="772" width="4" height="56" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="454" y="782" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">dns_cloudflare.wasm</text>
  <text x="454" y="797" fill="#9fc9e0" font-size="10">live · writes each sold estate's names</text>
  <text x="454" y="827" fill="#ffcf6f" font-size="10" font-weight="700">monetize-impl · signed</text>
  <rect x="823" y="764" width="325" height="72" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="824" y="772" width="4" height="56" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="835" y="782" fill="#eaf6ff" font-size="11" font-weight="700" font-family="'DejaVu Sans Mono', monospace">no DNS guest fed</text>
  <text x="835" y="797" fill="#9fc9e0" font-size="10">the core raises the operator alert</text>
  <text x="835" y="812" fill="#9fc9e0" font-size="10">estate-orders.dns-by-hand</text>
  <text x="835" y="827" fill="#6fd3f5" font-size="10" font-weight="700">open · the default</text>
  <text x="430" y="862" fill="#86b3cc" font-size="10.5">test guests, open, one per slot: toy · toy-vendor · toy-cloud · toy-dns (each proves its ABI end to end)</text>
  <path d="M420 300 L414 300 L414 790.0" stroke="#a9c3d4" stroke-width="3" fill="none"/>
  <circle cx="420" cy="300" r="3.2" fill="#dff1ff"/>
  <path d="M414 418.0 L429 418.0" stroke="#a9c3d4" stroke-width="2.4" fill="none" marker-end="url(#head)"/>
  <path d="M414 542.0 L429 542.0" stroke="#a9c3d4" stroke-width="2.4" fill="none" marker-end="url(#head)"/>
  <path d="M414 666.0 L429 666.0" stroke="#a9c3d4" stroke-width="2.4" fill="none" marker-end="url(#head)"/>
  <path d="M414 790.0 L429 790.0" stroke="#a9c3d4" stroke-width="2.4" fill="none" marker-end="url(#head)"/>
  <circle cx="414" cy="300" r="4" fill="#dff1ff"/>
  <rect x="1224" y="212" width="292" height="92" rx="7" fill="url(#chip)" stroke="#9fb4c4" stroke-width="1.8"/>
  <rect x="1225" y="220" width="4" height="76" rx="2" fill="#9fb4c4" fill-opacity="0.85"/>
  <text x="1236" y="230" fill="#eaf6ff" font-size="12.5" font-weight="700">The vendor's checkout page</text>
  <text x="1236" y="245" fill="#9fc9e0" font-size="10">Stripe's page: the ONE page off your site</text>
  <text x="1236" y="260" fill="#9fc9e0" font-size="10">the buyer pays here; the vendor then calls</text>
  <text x="1236" y="275" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">POST /callback/&lt;vendor&gt;/&lt;inst&gt; (HMAC)</text>
  <text x="1228" y="402" fill="#9fc9e0" font-size="10.5">A product operator dials nothing:</text>
  <text x="1228" y="418" fill="#9fc9e0" font-size="10.5">no door, no key, no endpoint.</text>
  <text x="1228" y="434" fill="#86b3cc" font-size="10.5">Its estate's boxes pull from the</text>
  <text x="1228" y="450" fill="#86b3cc" font-size="10.5">ONE box; the box never calls them.</text>
  <rect x="1224" y="490" width="292" height="46" rx="7" fill="url(#chip)" stroke="#9fb4c4" stroke-width="1.8"/>
  <rect x="1225" y="498" width="4" height="30" rx="2" fill="#9fb4c4" fill-opacity="0.85"/>
  <text x="1236" y="508" fill="#eaf6ff" font-size="11.5" font-weight="700">Stripe · Klarna · Swish APIs</text>
  <text x="1236" y="523" fill="#9fc9e0" font-size="10">HTTPS; the key is presented by the host</text>
  <rect x="1224" y="544" width="292" height="50" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8"/>
  <rect x="1225" y="552" width="4" height="34" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="1236" y="562" fill="#eaf6ff" font-size="10.5" font-weight="700" font-family="'DejaVu Sans Mono', monospace">fake_stripe_serve · klarna · swish</text>
  <text x="1236" y="577" fill="#9fc9e0" font-size="10">test doubles, private (monetize-impl)</text>
  <rect x="1224" y="614" width="292" height="46" rx="7" fill="url(#chip)" stroke="#9fb4c4" stroke-width="1.8"/>
  <rect x="1225" y="622" width="4" height="30" rx="2" fill="#9fb4c4" fill-opacity="0.85"/>
  <text x="1236" y="632" fill="#eaf6ff" font-size="11.5" font-weight="700">UpCloud · Scaleway APIs</text>
  <text x="1236" y="647" fill="#9fc9e0" font-size="10">HTTPS; UPCLOUD_TOKEN read by NAME</text>
  <rect x="1224" y="668" width="292" height="50" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="1225" y="676" width="4" height="34" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="1236" y="686" fill="#eaf6ff" font-size="10.5" font-weight="700" font-family="'DejaVu Sans Mono', monospace">mock-upcloud · mock-scaleway</text>
  <text x="1236" y="701" fill="#9fc9e0" font-size="10">test doubles, open (monetize/crates)</text>
  <rect x="1224" y="738" width="292" height="46" rx="7" fill="url(#chip)" stroke="#9fb4c4" stroke-width="1.8"/>
  <rect x="1225" y="746" width="4" height="30" rx="2" fill="#9fb4c4" fill-opacity="0.85"/>
  <text x="1236" y="756" fill="#eaf6ff" font-size="11.5" font-weight="700">Cloudflare API</text>
  <text x="1236" y="771" fill="#9fc9e0" font-size="10">HTTPS; the zone token by NAME</text>
  <rect x="1224" y="792" width="292" height="50" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="1225" y="800" width="4" height="34" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="1236" y="810" fill="#eaf6ff" font-size="10.5" font-weight="700" font-family="'DejaVu Sans Mono', monospace">toy-dns + a loopback fake</text>
  <text x="1236" y="825" fill="#9fc9e0" font-size="10">test double, open</text>
  <path d="M1160 513 L1223 513" stroke="#a9c3d4" stroke-width="2.2" fill="none" marker-end="url(#head)"/>
  <circle cx="1160" cy="513" r="3.2" fill="#dff1ff"/>
  <path d="M1160 637 L1223 637" stroke="#a9c3d4" stroke-width="2.2" fill="none" marker-end="url(#head)"/>
  <circle cx="1160" cy="637" r="3.2" fill="#dff1ff"/>
  <path d="M1160 761 L1223 761" stroke="#a9c3d4" stroke-width="2.2" fill="none" marker-end="url(#head)"/>
  <circle cx="1160" cy="761" r="3.2" fill="#dff1ff"/>
  <path d="M260 160 L260 210" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="260" cy="160" r="3.2" fill="#dff1ff"/>
  <circle cx="260" cy="186" r="9" fill="#0a2032" stroke="#dff1ff" stroke-width="1.6"/>
  <text x="260" y="190" fill="#dff1ff" font-size="11" font-weight="700" text-anchor="middle">1</text>
  <text x="276" y="190" fill="#dff1ff" font-size="10.5">sign up here</text>
  <path d="M356 240 L418 240" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="356" cy="240" r="3.2" fill="#dff1ff"/>
  <circle cx="385" cy="226" r="9" fill="#0a2032" stroke="#dff1ff" stroke-width="1.6"/>
  <text x="385" y="230" fill="#dff1ff" font-size="11" font-weight="700" text-anchor="middle">2</text>
  <path d="M1160 240 L1222 240" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="1160" cy="240" r="3.2" fill="#dff1ff"/>
  <circle cx="1195" cy="226" r="9" fill="#0a2032" stroke="#dff1ff" stroke-width="1.6"/>
  <text x="1195" y="230" fill="#dff1ff" font-size="11" font-weight="700" text-anchor="middle">3</text>
  <path d="M1224 290 L1162 290" stroke="#a9c3d4" stroke-width="2" fill="none" marker-end="url(#head)"/>
  <circle cx="1224" cy="290" r="3.2" fill="#dff1ff"/>
  <path d="M1490 212 L1490 98 L60 98 L60 108" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="1490" cy="212" r="3.2" fill="#dff1ff"/>
  <circle cx="700" cy="98" r="9" fill="#0a2032" stroke="#dff1ff" stroke-width="1.6"/>
  <text x="700" y="102" fill="#dff1ff" font-size="11" font-weight="700" text-anchor="middle">4</text>
  <text x="716" y="120" fill="#dff1ff" font-size="10.5">back to your paid page; your welcome page polls until the estate is ready</text>
  <text x="410" y="120" fill="#dff1ff" font-size="10.5">only Stripe checkout is off your site</text>
  <text x="410" y="136" fill="#86b3cc" font-size="10.5">(1 → 2 → 3 → 4); the ONE box mints the page once; the buyer never sees monetize</text>
  <path d="M356 480 L388 480 L388 270 L418 270" stroke="#a9c3d4" stroke-width="2.2" fill="none" marker-end="url(#head)"/>
  <circle cx="356" cy="480" r="3.2" fill="#dff1ff"/>
  <text x="388" y="496" fill="#86b3cc" font-size="10" text-anchor="middle">pull</text>
  <rect x="420" y="900" width="330" height="66" rx="7" fill="url(#chip)" stroke="#ffcf6f" stroke-width="1.8"/>
  <rect x="421" y="908" width="4" height="50" rx="2" fill="#ffcf6f" fill-opacity="0.85"/>
  <text x="432" y="918" fill="#eaf6ff" font-size="12" font-weight="700">The Build Thing (monetize-impl)</text>
  <text x="432" y="933" fill="#9fc9e0" font-size="10">signs EVERY guest under the plugin root the box</text>
  <text x="432" y="948" fill="#9fc9e0" font-size="10">trusts: yours (manifest_dir = ../&lt;id&gt;) and the vendors'</text>
  <rect x="780" y="900" width="380" height="66" rx="7" fill="url(#chip)" stroke="#9fb4c4" stroke-width="1.8"/>
  <rect x="781" y="908" width="4" height="50" rx="2" fill="#9fb4c4" fill-opacity="0.85"/>
  <text x="792" y="918" fill="#eaf6ff" font-size="12" font-weight="700">The release bucket + the feed (the operator's)</text>
  <text x="792" y="933" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">release/plugins/&lt;blake3&gt;/&lt;name&gt; + .p7s · signed manifest</text>
  <text x="792" y="948" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">pins · release --publish · feed --apply (key NAMES)</text>
  <path d="M750 933 L778 933" stroke="#a9c3d4" stroke-width="2.2" fill="none" stroke-dasharray="7 5" marker-end="url(#head)"/>
  <circle cx="750" cy="933" r="3.2" fill="#dff1ff"/>
  <path d="M60 642 L36 642 L36 933 L418 933" stroke="#a9c3d4" stroke-width="2.2" fill="none" stroke-dasharray="7 5" marker-end="url(#head)"/>
  <circle cx="60" cy="642" r="3.2" fill="#dff1ff"/>
  <text x="60" y="950" fill="#86b3cc" font-size="10.5">ship: your product operator goes to the Build Thing</text>
  <path d="M1040 872 L1040 898" stroke="#a9c3d4" stroke-width="2.2" fill="none" marker-end="url(#head)"/>
  <circle cx="1040" cy="872" r="3.2" fill="#dff1ff"/>
  <text x="1048" y="890" fill="#86b3cc" font-size="10">pulls by pin, verifies each</text>
  <text x="1178" y="918" fill="#9fc9e0" font-size="10"></text>
  <rect x="30" y="986" width="1500" height="50" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
  <g fill="#0a1c2c" stroke="#7fc8ea" stroke-width="1.5"><circle cx="50" cy="1011.0" r="4"/><circle cx="1510" cy="1011.0" r="4"/></g>
  <text x="66" y="1010" fill="#dff1ff" font-size="14" font-weight="700">rules</text>
  <text x="129.6" y="1010" fill="#bcd9ec" font-size="11">pull only: the ONE box never calls into an estate · runtime code calls Rust libraries, never xtask · vendor keys never leave the ONE box</text>
  <text x="66" y="1027" fill="#bcd9ec" font-size="11">[P1]–[P4] = the phase of MONETIZE-V2.0-PLAN.md it lands in; untagged = on main today · white = the buyer's path · solid = a call or pull, from the caller · dashed = ship</text>
</svg>