[{"data":1,"prerenderedAt":170},["ShallowReactive",2],{"i-lucide:layers":3,"i-lucide:git-commit-horizontal":8,"i-lucide:refresh-cw":10,"i-lucide:book-open":12,"i-lucide:image":14,"i-lucide:webhook":16,"i-lucide:home":18,"i-lucide:layout-grid":20,"i-lucide:tag":22,"i-lucide:newspaper":24,"i-lucide:map":26,"i-lucide:flask-conical":28,"i-lucide:arrow-right":30,"i-lucide:chevron-right":32,"i-lucide:search":34,"i-lucide:monitor":36,"content:\u002Finternal\u002Farchitecture\u002Ftenancy":38,"i-lucide:info":168,"i-lucide:layers-2":165,"i-lucide:key-round":165,"i-lucide:shield-check":165,"i-lucide:share-2":165,"i-lucide:box":165,"i-lucide:clock":165,"i-lucide:dices":165,"i-lucide:building-2":165,"i-lucide:bell":165,"i-lucide:sprout":165,"i-lucide:puzzle":165,"i-lucide:shield-alert":165,"i-lucide:activity":165,"i-lucide:blocks":165},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z\"\u002F>\u003Cpath d=\"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12\"\u002F>\u003Cpath d=\"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"3\"\u002F>\u003Cpath d=\"M3 12h6m6 0h6\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":11},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M3 12a9 9 0 0 1 9-9a9.75 9.75 0 0 1 6.74 2.74L21 8\"\u002F>\u003Cpath d=\"M21 3v5h-5m5 4a9 9 0 0 1-9 9a9.75 9.75 0 0 1-6.74-2.74L3 16\"\u002F>\u003Cpath d=\"M8 16H3v5\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":13},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 5v16m8.001-2A2 2 0 0 0 22 17V5a2 2 0 0 0-1.999-2L16 3.002A5 5 0 0 0 12 5a5 5 0 0 0-4-2H4a2 2 0 0 0-2 2v12a2 2 0 0 0 1.999 2H8a5 5 0 0 1 4 2a5 5 0 0 1 4-2z\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":15},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\"\u002F>\u003Ccircle cx=\"9\" cy=\"9\" r=\"2\"\u002F>\u003Cpath d=\"m21 15l-3.086-3.086a2 2 0 0 0-2.828 0L6 21\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":17},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M18 16.98h-5.99c-1.1 0-1.95.94-2.48 1.9A4 4 0 0 1 2 17c.01-.7.2-1.4.57-2\"\u002F>\u003Cpath d=\"m6 17l3.13-5.78c.53-.97.1-2.18-.5-3.1a4 4 0 1 1 6.89-4.06\"\u002F>\u003Cpath d=\"m12 6l3.13 5.73C15.66 12.7 16.9 13 18 13a4 4 0 0 1 0 8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":19},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8\"\u002F>\u003Cpath d=\"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":21},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"7\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"14\" y=\"3\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"14\" y=\"14\" rx=\"1\"\u002F>\u003Crect width=\"7\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":23},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z\"\u002F>\u003Ccircle cx=\"7.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":25},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M15 18h-5m8-4h-8m-6 8h16a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H8a2 2 0 0 0-2 2v16a2 2 0 0 1-4 0v-9a2 2 0 0 1 2-2h2\"\u002F>\u003Crect width=\"8\" height=\"4\" x=\"10\" y=\"6\" rx=\"1\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":27},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0zm.894.211v15M9 3.236v15\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":29},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2M6.453 15h11.094M8.5 2h7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":31},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":33},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m9 18l6-6l-6-6\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":35},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"m21 21l-4.34-4.34\"\u002F>\u003Ccircle cx=\"11\" cy=\"11\" r=\"8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":37},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"20\" height=\"14\" x=\"2\" y=\"3\" rx=\"2\"\u002F>\u003Cpath d=\"M8 21h8m-4-4v4\"\u002F>\u003C\u002Fg>",{"id":39,"title":40,"body":41,"description":158,"extension":159,"eyebrow":160,"hostedOnly":6,"meta":161,"navigation":162,"path":163,"seo":164,"short":165,"stem":166,"__hash__":167},"docs\u002Finternal\u002Farchitecture\u002Ftenancy.md","Workspaces, Plans & Billing",{"type":42,"value":43,"toc":148},"minimark",[44,48,53,61,65,68,86,89,93,96,99,103,110,114,117,121,135],[45,46,47],"p",{},"Chronicler is free to run yourself and paid to have hosted. That single fact shapes the whole commercial layer, because every limit and every payment has to be optional. Turn billing off and the product still has to make complete sense. This area also went through a few naming passes before it settled, so it is worth reading for the words as much as the mechanics.",[49,50,52],"h2",{"id":51},"a-workspace-owns-the-worlds","A workspace owns the worlds",[45,54,55,56,60],{},"A ",[57,58,59],"strong",{},"workspace"," is the single owner of a set of chronicles and the home for quota and cross-world roles. Every user gets a permanent personal workspace on signup, and shared workspaces are created deliberately and can invite members. A chronicle points at its owning workspace through one edge, so usage is attributed through that edge and re-attributes cleanly when a world is handed to a different workspace. A workspace is a management and attribution layer, not a hard wall between tenants, but the single owner edge is exactly what would let it harden into one later.",[49,62,64],{"id":63},"four-words-kept-distinct","Four words, kept distinct",[45,66,67],{},"The money model turns on four words that early drafts kept blurring, so they are now pinned down.",[45,69,55,70,73,74,77,78,81,82,85],{},[57,71,72],{},"plan"," is a template of entitlements. An ",[57,75,76],{},"allocation"," is the live instance of a plan, owned by one user, holding that plan's entitlements and its credit ledgers; workspaces attach to an allocation to take its plan. A ",[57,79,80],{},"billing subscription"," is the real-world payment that grants a plan, and it exists only inside the hosted billing module. A ",[57,83,84],{},"grant"," is a permission row in access control, and nothing else. Keeping these separate is what lets the free self-host edition talk about plans and entitlements without ever mentioning a payment.",[45,87,88],{},"Assigning a plan snapshots its caps onto the allocation, so editing a plan later never silently moves a live tenant. Pushing that change out is an explicit migration a person decides to run.",[49,90,92],{"id":91},"a-downgrade-freezes-growth-it-never-deletes","A downgrade freezes growth, it never deletes",[45,94,95],{},"This is the decision most worth understanding. When a tenant moves to a smaller plan, or lets a payment lapse, or archives a world, Chronicler does not reach in and delete anything. It freezes growth at the write boundary. Reads, edits, and deletes all keep working, and only a write that adds to a metered quantity is refused. A person who stops paying still owns their data and can still get it out.",[45,97,98],{},"An archived chronicle goes dormant and stops counting against the resource cap, though its bytes keep counting against storage, because a disk costs money whether or not anyone is reading it. Bringing it back runs one capacity check, which removes any need for an artificial cool-off period.",[49,100,102],{"id":101},"usage-is-counted-never-stored","Usage is counted, never stored",[45,104,105,106,109],{},"A metered number is counted at the moment of the write, never kept in a column that could quietly drift out of step with reality. Storage, seats, and resources are metered per workspace. A pooled measure like AI credits is a single number on the allocation that attached workspaces draw from, optionally under a per-workspace draw cap. A user's class in a workspace, their ",[57,107,108],{},"standing",", is declared on their role rather than guessed from the permissions the role happens to hold, so editing a role can never silently reclassify someone and blow a cap. And a table always includes one free place, because someone has to run the game and that person is the customer, not an extra seat to charge for.",[49,111,113],{"id":112},"money-enters-only-the-hosted-edition","Money enters only the hosted edition",[45,115,116],{},"Billing is hosted-only, full stop. A self-host install has no payment provider and never asks for one. In the hosted edition a plan change becomes a first-class request with a clear yes-or-no outcome, and a fulfilment port decides how to satisfy it: the self-host adapter routes to admin approval, the hosted adapter opens a Stripe checkout and lets a webhook drive the request to done, with a reconcile chore as a backstop. A plan itself carries no price. The price is a sidecar the billing module fills in, so the core code never names a payment provider at all.",[49,118,120],{"id":119},"where-this-connects","Where this connects",[45,122,123,124,129,130,134],{},"Standing and roles lean on ",[125,126,128],"a",{"href":127},"\u002Finternal\u002Farchitecture\u002Fauthorization","Authorization",", and the hosted billing module is one instance of the pattern in ",[125,131,133],{"href":132},"\u002Finternal\u002Farchitecture\u002Fmodules","Modules and editions",".",[136,137,140],"callout",{"title":138,"tone":139},"Read the record for the detail","note",[45,141,142,143,147],{},"This page is the guide. The full records under ",[144,145,146],"code",{},"docs\u002Fadrs"," carry the exact caps, the transition mechanics, and the alternatives that were weighed and rejected.",{"title":149,"searchDepth":150,"depth":150,"links":151},"",2,[152,153,154,155,156,157],{"id":51,"depth":150,"text":52},{"id":63,"depth":150,"text":64},{"id":91,"depth":150,"text":92},{"id":101,"depth":150,"text":102},{"id":112,"depth":150,"text":113},{"id":119,"depth":150,"text":120},"The commercial layer - who owns a world, what a plan really grants, why a downgrade never deletes, and where money enters only the hosted edition.","md","Architecture",{},{"title":40},"\u002Finternal\u002Farchitecture\u002Ftenancy",{"title":40,"description":158},null,"internal\u002Farchitecture\u002Ftenancy","cNY2oLfoAiPJUlLYHTGVc1WMbnDsADKrK_Uzt_yQl2E",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":169},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Ccircle cx=\"12\" cy=\"12\" r=\"10\"\u002F>\u003Cpath d=\"M12 16v-4m0-4h.01\"\u002F>\u003C\u002Fg>",1788784066569]