Gunnar

nordisk/monetize

docs/datamodel-v2.svg

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1240 1100" width="1240" height="1100" 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="1240" height="1100" fill="url(#board)"/>
  <g stroke="#143a52" stroke-width="1"><line x1="0" y1="84" x2="1240" y2="84"/><line x1="0" y1="1064" x2="1240" y2="1064"/></g>
  <g fill="#16415c"><circle cx="40" cy="20" r="2"/><circle cx="1200" cy="20" r="2"/><circle cx="40" cy="1082" r="2"/><circle cx="1200" cy="1082" r="2"/></g>
  <text x="40" y="44" fill="#eaf6ff" font-size="22" font-weight="700">The data model</text>
  <text x="265" y="44" fill="#9fc9e0" font-size="15">behind a sale (monetize v2.0): who stores what</text>
  <rect x="700" y="33" width="24" height="14" rx="3" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <text x="732" y="44" fill="#cfe6f5" font-size="12">the product writes it (its own store)</text>
  <rect x="700" y="59" width="24" height="14" rx="3" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <text x="732" y="70" fill="#cfe6f5" font-size="12">monetize writes it (the ONE box)</text>
  <line x1="1000" y1="40" x2="1036" y2="40" stroke="#dff1ff" stroke-width="2.6"/>
  <text x="1044" y="44" fill="#cfe6f5" font-size="12">crosses a band</text>
  <line x1="1000" y1="66" x2="1036" y2="66" stroke="#a9c3d4" stroke-width="2.2" stroke-dasharray="7 5"/>
  <text x="1044" y="70" fill="#cfe6f5" font-size="12">pull (Fleet)</text>
  <rect x="16" y="104" width="1208" height="262" rx="12" fill="url(#rail)" fill-opacity="0.55" stroke="#7CFFB2" stroke-opacity="0.75" stroke-width="2"/>
  <text x="32" y="128" fill="#7CFFB2" font-size="14.5" font-weight="700">ON THE SELLING SITE</text>
  <text x="231.34" y="128" fill="#86b3cc" font-size="11">gunnar.rs · holger.rs: the product writes it, in its own store</text>
  <rect x="30" y="140" width="230" height="103" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="31" y="148" width="4" height="87" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="42" y="158" fill="#eaf6ff" font-size="12" font-weight="700">Principal (a person)</text>
  <text x="42" y="173" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">id · name · created</text>
  <text x="42" y="188" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">kind: User | Machine |</text>
  <text x="42" y="203" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  Deploy | Group</text>
  <text x="42" y="218" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">+ ssh keys · tokens (1:n)</text>
  <text x="42" y="233" fill="#86b3cc" font-size="10">control.redb AuthDoc.principals</text>
  <rect x="30" y="264" width="230" height="88" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="31" y="272" width="4" height="72" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="42" y="282" fill="#eaf6ff" font-size="12" font-weight="700">Passkey (WebCredential)</text>
  <text x="42" y="297" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">id · principal_id</text>
  <text x="42" y="312" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">public_key_hex · sign_count</text>
  <text x="42" y="327" fill="#86b3cc" font-size="10">signup_account(): NoPasskey |</text>
  <text x="42" y="342" fill="#86b3cc" font-size="10">  HasPasskey</text>
  <rect x="290" y="140" width="250" height="103" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="291" y="148" width="4" height="87" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="302" y="158" fill="#eaf6ff" font-size="12" font-weight="700">Account = namespace</text>
  <text x="302" y="173" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">id == name · explode_budget_bytes</text>
  <text x="302" y="188" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">public · repos (1:n)</text>
  <text x="302" y="203" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">Entitlement: plan · state · caps</text>
  <text x="302" y="218" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  paid_until · signature</text>
  <text x="302" y="233" fill="#86b3cc" font-size="10">catalog doc · refs/gunnar/entitlements</text>
  <rect x="287" y="137" width="256" height="109" rx="9" fill="none" stroke="#7CFFB2" stroke-width="1" stroke-opacity="0.7"/>
  <rect x="290" y="264" width="250" height="73" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="291" y="272" width="4" height="57" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="302" y="282" fill="#eaf6ff" font-size="12" font-weight="700">Grant</text>
  <text x="302" y="297" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">principal · scope: Server |</text>
  <text x="302" y="312" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  Namespace | Repo · level R/W/A</text>
  <text x="302" y="327" fill="#86b3cc" font-size="10">+ members, seats; a member buys nothing</text>
  <rect x="570" y="140" width="230" height="103" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="571" y="148" width="4" height="87" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="582" y="158" fill="#eaf6ff" font-size="12" font-weight="700">Invite</text>
  <text x="582" y="173" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">id · principal_id</text>
  <text x="582" y="188" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">secret_hash (never the token)</text>
  <text x="582" y="203" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">created_by · expires</text>
  <text x="582" y="218" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">server_level · single use</text>
  <text x="582" y="233" fill="#86b3cc" font-size="10">the link registers the first passkey</text>
  <rect x="570" y="264" width="230" height="88" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="571" y="272" width="4" height="72" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="582" y="282" fill="#eaf6ff" font-size="12" font-weight="700">Actor ticket (not stored)</text>
  <text x="582" y="297" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">account · purpose · caps</text>
  <text x="582" y="312" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">signed by the main's ticket key</text>
  <text x="582" y="327" fill="#86b3cc" font-size="10">single use; proves "account</text>
  <text x="582" y="342" fill="#86b3cc" font-size="10">is the buyer"</text>
  <rect x="830" y="140" width="380" height="163" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="831" y="148" width="4" height="147" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="842" y="158" fill="#eaf6ff" font-size="12" font-weight="700">What the site keeps of monetize: a link</text>
  <text x="842" y="173" fill="#86b3cc" font-size="10">ShopLink: the ONE box's URL, the site's bearer, product, vendor</text>
  <text x="842" y="188" fill="#86b3cc" font-size="10">no order, no price, no card, no estate row lives on the site</text>
  <text x="842" y="203" fill="#86b3cc" font-size="10">the relay (monetize-site-buy) passes the buyer's form through</text>
  <text x="842" y="218" fill="#86b3cc" font-size="10">and renders the words the ONE box answers</text>
  <text x="842" y="233" fill="#86b3cc" font-size="10">Gunnar: tenant = the account's namespace</text>
  <text x="842" y="248" fill="#86b3cc" font-size="10">Holger: tenant = the account's repository</text>
  <text x="842" y="263" fill="#86b3cc" font-size="10">the site's main runs add_principal and entitlement orders;</text>
  <text x="842" y="278" fill="#86b3cc" font-size="10">it PULLS them from the ONE box (Fleet), as any sold estate does</text>
  <text x="842" y="293" fill="#dff1ff" font-size="10">[P2] the entitlement push dies: it is only a pulled order</text>
  <path d="M145 243 L145 264" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="145" cy="243" r="2.6" fill="#a9c3d4"/>
  <circle cx="145" cy="264" r="2.6" fill="#a9c3d4"/>
  <text x="150" y="258" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M260 190 L290 190" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="260" cy="190" r="2.6" fill="#a9c3d4"/>
  <circle cx="290" cy="190" r="2.6" fill="#a9c3d4"/>
  <text x="264" y="184" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M260 232 L268 232 L268 300 L290 300" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="260" cy="232" r="2.6" fill="#a9c3d4"/>
  <circle cx="290" cy="300" r="2.6" fill="#a9c3d4"/>
  <text x="271" y="294" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M415 243 L415 264" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="415" cy="243" r="2.6" fill="#a9c3d4"/>
  <circle cx="415" cy="264" r="2.6" fill="#a9c3d4"/>
  <text x="420" y="258" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M540 190 L570 190" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="540" cy="190" r="2.6" fill="#a9c3d4"/>
  <circle cx="570" cy="190" r="2.6" fill="#a9c3d4"/>
  <text x="544" y="184" fill="#86b3cc" font-size="10">1:n</text>
  <rect x="16" y="382" width="1208" height="432" rx="12" fill="url(#rail)" fill-opacity="0.55" stroke="#6fd3f5" stroke-opacity="0.75" stroke-width="2"/>
  <text x="32" y="406" fill="#6fd3f5" font-size="14.5" font-weight="700">IN MONETIZE</text>
  <text x="798" y="406" fill="#86b3cc" font-size="10.5">the ONE box: monetize-admin's server writes it (redb, run files)</text>
  <rect x="30" y="418" width="230" height="118" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="31" y="426" width="4" height="102" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="42" y="436" fill="#eaf6ff" font-size="12" font-weight="700">Site [estates.&lt;label&gt;]</text>
  <text x="42" y="451" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">label (test2-gunnar-rs)</text>
  <text x="42" y="466" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">product · vendor · owner</text>
  <text x="42" y="481" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">domain · first_admin</text>
  <text x="42" y="496" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">orders: term, grace, margin</text>
  <text x="42" y="511" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">terminable · operator_site</text>
  <text x="42" y="526" fill="#86b3cc" font-size="10">EstateConfig · SiteBook.SiteRecord</text>
  <rect x="27" y="415" width="236" height="124" rx="9" fill="none" stroke="#6fd3f5" stroke-width="1" stroke-opacity="0.7"/>
  <rect x="290" y="418" width="230" height="118" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="291" y="426" width="4" height="102" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="302" y="436" fill="#eaf6ff" font-size="12" font-weight="700">Account (product, tenant)</text>
  <text x="302" y="451" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">EntitlementFact: plan · state</text>
  <text x="302" y="466" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  caps · paid_until · signature</text>
  <text x="302" y="481" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">usage (latest + history)</text>
  <text x="302" y="496" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">rows: subscription | purchase</text>
  <text x="302" y="511" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">      | instance</text>
  <text x="302" y="526" fill="#86b3cc" font-size="10">ledger.redb · usage.redb</text>
  <rect x="287" y="415" width="236" height="124" rx="9" fill="none" stroke="#6fd3f5" stroke-width="1" stroke-opacity="0.7"/>
  <rect x="550" y="418" width="220" height="133" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="551" y="426" width="4" height="117" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="562" y="436" fill="#eaf6ff" font-size="12" font-weight="700">Signup (vendor, session)</text>
  <text x="562" y="451" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">username · email · product</text>
  <text x="562" y="466" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">plan · amount · state</text>
  <text x="562" y="481" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">estate (the site) · card</text>
  <text x="562" y="496" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  (fingerprint, never the no.)</text>
  <text x="562" y="511" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">name_holds · card_checks</text>
  <text x="562" y="526" fill="#86b3cc" font-size="10">signups.redb</text>
  <text x="562" y="541" fill="#dff1ff" font-size="10">[P2] the signup guests are deleted</text>
  <rect x="800" y="418" width="200" height="118" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="801" y="426" width="4" height="102" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="812" y="436" fill="#eaf6ff" font-size="12" font-weight="700">Purchase (ledger rows)</text>
  <text x="812" y="451" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">reference</text>
  <text x="812" y="466" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace"> &lt;product&gt;/&lt;tenant&gt;/&lt;period&gt;</text>
  <text x="812" y="481" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">steps: Reserved · Ensured</text>
  <text x="812" y="496" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace"> Captured · Settled · Released</text>
  <text x="812" y="511" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">append-only, never deleted</text>
  <text x="812" y="526" fill="#86b3cc" font-size="10">ledger.redb steps · open · recent</text>
  <rect x="1030" y="418" width="180" height="118" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="1031" y="426" width="4" height="102" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="1042" y="436" fill="#eaf6ff" font-size="12" font-weight="700">Plan / offer (feed)</text>
  <text x="1042" y="451" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">signup plans:</text>
  <text x="1042" y="466" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  amount_minor · currency</text>
  <text x="1042" y="481" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  cap_bytes · period_days</text>
  <text x="1042" y="496" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">bundles: cap_delta</text>
  <text x="1042" y="511" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">prices · purge_after_days</text>
  <text x="1042" y="526" fill="#dff1ff" font-size="10">[P3] facts().form + offers</text>
  <rect x="30" y="584" width="230" height="133" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="31" y="592" width="4" height="117" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="42" y="602" fill="#eaf6ff" font-size="12" font-weight="700">Custody (SEALED)</text>
  <text x="42" y="617" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">per estate:</text>
  <text x="42" y="632" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">first_login invite (32 B)</text>
  <text x="42" y="647" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">signing · pairing seeds</text>
  <text x="42" y="662" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">break_glass · estate_client</text>
  <text x="42" y="677" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">pairing material</text>
  <text x="42" y="692" fill="#86b3cc" font-size="10">sealed; never in the clear</text>
  <text x="42" y="707" fill="#dff1ff" font-size="10">[P3] + the main's ticket_pubkey</text>
  <rect x="27" y="581" width="236" height="139" rx="9" fill="none" stroke="#6fd3f5" stroke-width="1" stroke-opacity="0.7"/>
  <rect x="30" y="732" width="230" height="73" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="31" y="740" width="4" height="57" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="42" y="750" fill="#eaf6ff" font-size="12" font-weight="700">Fleet (fleet.redb)</text>
  <text x="42" y="765" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">boxes: key · newest report</text>
  <text x="42" y="780" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">orders(instance, seq) to ack</text>
  <text x="42" y="795" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">cases · auto_fix</text>
  <rect x="290" y="584" width="300" height="208" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="291" y="592" width="4" height="192" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="302" y="602" fill="#eaf6ff" font-size="12" font-weight="700">Sold estate (EstateRun)</text>
  <text x="302" y="617" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">estate/&lt;company&gt;</text>
  <text x="302" y="632" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">company · reference · estate (site)</text>
  <text x="302" y="647" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">account (whose it is) · email</text>
  <text x="302" y="662" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">phase: ordered → held → laying →</text>
  <text x="302" y="677" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  installing → paired → captured</text>
  <text x="302" y="692" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  … grace · suspended · terminated</text>
  <text x="302" y="707" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">quote · amount · paid_until · handle</text>
  <text x="302" y="722" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">laid · dns · peers · client_key</text>
  <text x="302" y="737" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">renewals · changes · history</text>
  <text x="302" y="752" fill="#86b3cc" font-size="10">estate-orders/&lt;company&gt;/run.json (no secret)</text>
  <text x="302" y="767" fill="#dff1ff" font-size="10">[P3] quote.sizes → the product's Order JSON</text>
  <text x="302" y="782" fill="#dff1ff" font-size="10">[P3] SoldEstate folds into Fleet</text>
  <rect x="287" y="581" width="306" height="214" rx="9" fill="none" stroke="#6fd3f5" stroke-width="1" stroke-opacity="0.7"/>
  <rect x="620" y="584" width="210" height="88" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="621" y="592" width="4" height="72" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="632" y="602" fill="#eaf6ff" font-size="12" font-weight="700">Vendor instance</text>
  <text x="632" y="617" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">stripe/&lt;instance&gt;</text>
  <text x="632" y="632" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">guest · digest · country</text>
  <text x="632" y="647" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">key NAMES (values in custody)</text>
  <text x="632" y="662" fill="#86b3cc" font-size="10">callback_events · paid_at_vendor</text>
  <rect x="620" y="700" width="210" height="88" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="621" y="708" width="4" height="72" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="632" y="718" fill="#eaf6ff" font-size="12" font-weight="700">Cloud resources</text>
  <text x="632" y="733" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">LaidEstate: machines, disks</text>
  <text x="632" y="748" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">label reference=estate/&lt;co&gt;</text>
  <text x="632" y="763" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">journal · spend cap</text>
  <text x="632" y="778" fill="#dff1ff" font-size="10">[P1] the backups are destroyed too</text>
  <rect x="860" y="584" width="350" height="178" rx="7" fill="url(#chip)" stroke="#6fd3f5" stroke-width="1.8"/>
  <rect x="861" y="592" width="4" height="162" rx="2" fill="#6fd3f5" fill-opacity="0.85"/>
  <text x="872" y="602" fill="#eaf6ff" font-size="12" font-weight="700">Release and feed (what the box runs)</text>
  <text x="872" y="617" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">solo.toml: [products.&lt;id&gt;] · [vendors.*]</text>
  <text x="872" y="632" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">  [estates.&lt;site&gt;] · [signups.&lt;id&gt;]</text>
  <text x="872" y="647" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">release-manifest.toml (signed)</text>
  <text x="872" y="662" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">plugins/&lt;blake3&gt;/&lt;name&gt; + .p7s</text>
  <text x="872" y="677" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">media-&lt;kind&gt;.toml · templates</text>
  <text x="872" y="692" fill="#bfe6ff" font-size="10" font-family="'DejaVu Sans Mono', monospace">site orders: live_apps · release_notes</text>
  <text x="872" y="707" fill="#86b3cc" font-size="10">the product operator's facts() and plan() are read here,</text>
  <text x="872" y="722" fill="#86b3cc" font-size="10">never stored: the shape of an estate is the operator's</text>
  <text x="872" y="737" fill="#dff1ff" font-size="10">[P2] grants, shape and shop-pairing CONTRACTS leave</text>
  <text x="872" y="752" fill="#dff1ff" font-size="10">     the feed; [P3] the core knows no product name</text>
  <path d="M260 478 L290 478" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="260" cy="478" r="2.6" fill="#a9c3d4"/>
  <circle cx="290" cy="478" r="2.6" fill="#a9c3d4"/>
  <text x="264" y="472" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M520 478 L550 478" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="520" cy="478" r="2.6" fill="#a9c3d4"/>
  <circle cx="550" cy="478" r="2.6" fill="#a9c3d4"/>
  <text x="524" y="472" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M770 478 L800 478" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="770" cy="478" r="2.6" fill="#a9c3d4"/>
  <circle cx="800" cy="478" r="2.6" fill="#a9c3d4"/>
  <text x="774" y="472" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M1000 478 L1030 478" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="1000" cy="478" r="2.6" fill="#a9c3d4"/>
  <circle cx="1030" cy="478" r="2.6" fill="#a9c3d4"/>
  <text x="1004" y="472" fill="#86b3cc" font-size="10">n:1</text>
  <path d="M405 536 L405 584" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="405" cy="536" r="2.6" fill="#a9c3d4"/>
  <circle cx="405" cy="584" r="2.6" fill="#a9c3d4"/>
  <text x="410" y="576" fill="#86b3cc" font-size="10">1:n instances</text>
  <path d="M260 634 L290 634" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="260" cy="634" r="2.6" fill="#a9c3d4"/>
  <circle cx="290" cy="634" r="2.6" fill="#a9c3d4"/>
  <text x="264" y="628" fill="#86b3cc" font-size="10">1:1</text>
  <path d="M260 774 L290 774" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="260" cy="774" r="2.6" fill="#a9c3d4"/>
  <circle cx="290" cy="774" r="2.6" fill="#a9c3d4"/>
  <text x="264" y="768" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M590 634 L620 634" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="590" cy="634" r="2.6" fill="#a9c3d4"/>
  <circle cx="620" cy="634" r="2.6" fill="#a9c3d4"/>
  <text x="594" y="628" fill="#86b3cc" font-size="10">n:1</text>
  <path d="M590 744 L620 744" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="590" cy="744" r="2.6" fill="#a9c3d4"/>
  <circle cx="620" cy="744" r="2.6" fill="#a9c3d4"/>
  <text x="594" y="738" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M145 536 L145 568 L282 568 L282 704 L290 704" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="145" cy="536" r="2.6" fill="#a9c3d4"/>
  <circle cx="290" cy="704" r="2.6" fill="#a9c3d4"/>
  <text x="150" y="564" fill="#86b3cc" font-size="10">1:n estates sold here</text>
  <rect x="16" y="830" width="1208" height="128" rx="12" fill="url(#rail)" fill-opacity="0.55" stroke="#7CFFB2" stroke-opacity="0.75" stroke-width="2"/>
  <text x="32" y="854" fill="#7CFFB2" font-size="14.5" font-weight="700">ON THE SOLD INSTANCE</text>
  <text x="420" y="854" fill="#86b3cc" font-size="11">acme.gunnar.rs: its own store; monetize holds no row of its people</text>
  <rect x="30" y="866" width="330" height="73" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="31" y="874" width="4" height="57" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="42" y="884" fill="#eaf6ff" font-size="12" font-weight="700">Its first admin</text>
  <text x="42" y="899" fill="#86b3cc" font-size="10">principal named EstateRun.account, made by the</text>
  <text x="42" y="914" fill="#86b3cc" font-size="10">first-login invite (its hash fed at the install)</text>
  <text x="42" y="929" fill="#86b3cc" font-size="10">+ its first passkey, registered from the "ready" mail</text>
  <rect x="27" y="863" width="336" height="79" rx="9" fill="none" stroke="#7CFFB2" stroke-width="1" stroke-opacity="0.7"/>
  <rect x="390" y="866" width="330" height="73" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="391" y="874" width="4" height="57" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="402" y="884" fill="#eaf6ff" font-size="12" font-weight="700">Its users, namespaces, grants</text>
  <text x="402" y="899" fill="#86b3cc" font-size="10">the same model as the selling site, in its own store;</text>
  <text x="402" y="914" fill="#86b3cc" font-size="10">the first admin invites them; the selling site and</text>
  <text x="402" y="929" fill="#86b3cc" font-size="10">monetize never see them</text>
  <rect x="750" y="866" width="460" height="73" rx="7" fill="url(#chip)" stroke="#7CFFB2" stroke-width="1.8"/>
  <rect x="751" y="874" width="4" height="57" rx="2" fill="#7CFFB2" fill-opacity="0.85"/>
  <text x="762" y="884" fill="#eaf6ff" font-size="12" font-weight="700">Its boxes (front · main · twin, or the Lake's roles)</text>
  <text x="762" y="899" fill="#86b3cc" font-size="10">each box: fleet_pubkey, pinned at pairing; reports (build, health, usage)</text>
  <text x="762" y="914" fill="#86b3cc" font-size="10">and pulls its orders; the main holds the ticket key and the data</text>
  <text x="762" y="929" fill="#86b3cc" font-size="10">no backup at terminate: machines, disks, DNS and custody go</text>
  <path d="M360 906 L390 906" stroke="#a9c3d4" stroke-width="1.6" fill="none"/>
  <circle cx="360" cy="906" r="2.6" fill="#a9c3d4"/>
  <circle cx="390" cy="906" r="2.6" fill="#a9c3d4"/>
  <text x="364" y="900" fill="#86b3cc" font-size="10">1:n</text>
  <path d="M470 243 L470 252 L552 252 L552 374 L405 374 L405 415" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="470" cy="243" r="3.2" fill="#dff1ff"/>
  <text x="412" y="369" fill="#dff1ff" font-size="10" font-weight="700">tenant = namespace</text>
  <path d="M660 418 L660 362 L562 362 L562 220 L542 220" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="660" cy="418" r="3.2" fill="#dff1ff"/>
  <text x="792" y="358" fill="#dff1ff" font-size="10" font-weight="700">new_account: paid → add_principal</text>
  <path d="M785 352 L785 572 L540 572 L540 581" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="785" cy="352" r="3.2" fill="#dff1ff"/>
  <text x="800" y="576" fill="#dff1ff" font-size="10" font-weight="700">actor ticket → EstateOrder.Start(company, account, ticket)</text>
  <path d="M30 644 L22 644 L22 906 L28 906" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="30" cy="644" r="3.2" fill="#dff1ff"/>
  <text x="12" y="765.0" fill="#dff1ff" font-size="10" font-weight="700" text-anchor="middle" transform="rotate(-90 12 765.0)">first-login invite</text>
  <path d="M440 792 L440 822 L980 822 L980 863" stroke="#dff1ff" stroke-width="2.6" fill="none" marker-end="url(#headw)"/>
  <circle cx="440" cy="792" r="3.2" fill="#dff1ff"/>
  <text x="990" y="817" fill="#dff1ff" font-size="10" font-weight="700">lay → pair → sale check → capture</text>
  <path d="M800 939 L800 956 L386 956 L386 820 L145 820 L145 807" stroke="#a9c3d4" stroke-width="2" fill="none" stroke-dasharray="7 5" marker-end="url(#head)"/>
  <circle cx="800" cy="939" r="3.2" fill="#dff1ff"/>
  <text x="286" y="974" fill="#86b3cc" font-size="10">every box reports and pulls its orders (Fleet); the ONE box never calls into an estate</text>
  <rect x="30" y="988" width="1180" height="72" rx="10" fill="url(#rail)" stroke="#7fc8ea" stroke-width="2"/>
  <g fill="#0a1c2c" stroke="#7fc8ea" stroke-width="1.5"><circle cx="50" cy="1024.0" r="4"/><circle cx="1190" cy="1024.0" r="4"/></g>
  <text x="66" y="1012" fill="#dff1ff" font-size="14" font-weight="700">how to read it</text>
  <text x="215.28" y="1012" fill="#bcd9ec" font-size="11">a thin grey line is a relation inside one store; "1:n" reads from the left or top box · a white line crosses a band: the only links between the three stores</text>
  <text x="66" y="1029" fill="#bcd9ec" font-size="11">a double outline marks the key entity of a store · untagged = on main today; [P1]–[P3] = MONETIZE-V2.0-PLAN.md §6 · sources: INTEGRATION-v2.md §7</text>
  <text x="66" y="1046" fill="#bcd9ec" font-size="11">monetize keeps one run file per sold estate (estate-orders/&lt;company&gt;/run.json); the operator console keeps its own passkeys and sessions in state.redb</text>
</svg>