{
  "protocol": "OIP",
  "version": "0.6",
  "kind": "tenancy",
  "title": "§TENANCY — multi-tenant, proven on the capability substrate",
  "thesis": "The build runs single-operator by design, but multi-tenancy was never an architecture gap — the object-capability layer IS the tenant auth substrate. A tenant is an isolation boundary bound onto every capability it mints. This page is the architecture and the live proof.",
  "model": {
    "tenant": "A named isolation boundary (t_<slug>) with an allow-list of invokable keys/prefixes, a risk ceiling, and a status (active|suspended). Provisioned by the owner.",
    "binding": "Every minted capability carries a tenant_id. The token format is unchanged (sh.<exp>.<scope>.<nonce>); the tenant lives on the capability record, resolved server-side. A tenant NEVER holds a secret another tenant could forge.",
    "owner_plane": "Capabilities with no tenant_id (or t_root) are the owner plane — unrestricted, exactly as before. Tenancy is additive; nothing about single-operator use changed."
  },
  "isolation_guarantees": [
    "INVOKE: a tenant token can fire only keys in its allow_keys / allow_prefixes. Anything else → 403 tenant_scope_denied, ledgered.",
    "LEDGER: a tenant reads only invocations made by its own capabilities (GET ?tenant_invocations=t_x). Cross-tenant rows are never returned.",
    "RECEIPTS: a tenant token (even read/act) reading ?receipt= for another tenant's invocation → 403 tenant_receipt_isolation.",
    "ADMIN: provisioning, minting tenant tokens, suspending, and listing tenants are owner-only. A tenant cannot mint or revoke for another tenant.",
    "REVOCATION: suspend a tenant and every one of its live tokens fails closed immediately (tenant_suspended), no token expiry needed.",
    "RISK: a tenant's risk_ceiling caps the sensitivity of rows it can reach, independent of the row-level cap already enforced.",
    "AUDIT: every tenant action and denial is appended to the tamper-evident ledger under the capability fingerprint + tenant_id."
  ],
  "endpoints": {
    "doc": "https://miscsubjects.com/api/dispatch?tenancy=1&format=markdown",
    "explain_tenant": "https://miscsubjects.com/api/dispatch?tenant=t_<slug>",
    "list": "https://miscsubjects.com/api/dispatch?tenants=1  (owner)",
    "provision": "https://miscsubjects.com/api/dispatch?tenant_create=<name>&keys=<K1,K2>&prefixes=<P>&risk=low  (owner)",
    "mint_tenant_token": "https://miscsubjects.com/api/dispatch?tenant_mint=t_<slug>&scope=act  (owner) — a token bound to the tenant",
    "suspend": "https://miscsubjects.com/api/dispatch?tenant_suspend=t_<slug>  (owner)",
    "tenant_ledger": "https://miscsubjects.com/api/dispatch?tenant_invocations=t_<slug>  (owner or same-tenant token)"
  },
  "live_proof_recipe": [
    "Provision two tenants with disjoint allow-lists: ?tenant_create=acme&keys=NOW,ARTICLES and ?tenant_create=globex&keys=NOW,GROK_IMAGE.",
    "Mint a token for each: ?tenant_mint=t_acme&scope=act and ?tenant_mint=t_globex&scope=act.",
    "t_acme fires NOW → ok; t_acme fires GROK_IMAGE → 403 tenant_scope_denied (not in its allow-list).",
    "t_globex fires GROK_IMAGE → ok; t_globex fires ARTICLES → 403.",
    "t_acme reads t_globex's receipt → 403 tenant_receipt_isolation; each reads only its own ?tenant_invocations=.",
    "Suspend t_acme → its live token now 403 tenant_suspended on every call.",
    "Cross-tenant delegation: t_acme mints a single-use row token for a key it owns and hands it to t_globex's agent; t_globex fires it — attributed to t_acme's tenant, isolation intact, no shared key vault."
  ],
  "current_tenants": [
    {
      "tenant_id": "t_globex",
      "name": "globex",
      "status": "active",
      "allow_keys": "NOW,DIR_GET",
      "allow_prefixes": "",
      "explain": "https://miscsubjects.com/api/dispatch?tenant=t_globex"
    },
    {
      "tenant_id": "t_acme",
      "name": "acme",
      "status": "active",
      "allow_keys": "NOW,GROK_LEDGER_TAIL",
      "allow_prefixes": "",
      "explain": "https://miscsubjects.com/api/dispatch?tenant=t_acme"
    }
  ],
  "not_built_by_design": "Compute isolation for untrusted CODE (Firecracker/gVisor microVMs) is a separate concern and is deliberately out of scope — this proves the AUTH/data isolation layer, which is what multi-tenant delegation actually needs. See ?why=1 (multi_tenant_isolation).",
  "root": "https://miscsubjects.com/api/dispatch?map=1&format=markdown"
}