[{"data":1,"prerenderedAt":3373},["ShallowReactive",2],{"navigation":3,"\u002Fservices\u002Fuser-envelope":927,"mdc-8bt02u-key":3340,"mdc-ttyery-key":3357},[4,40,114,446,474,498,596,903],{"title":5,"path":6,"stem":7,"children":8},"Architecture","\u002Farchitecture","architecture",[9,14,28,32,36],{"title":10,"path":6,"stem":11,"access":12,"icon":13},"Overview","architecture\u002Findex","public","i-lucide-network",{"title":10,"path":15,"stem":16,"children":17,"access":12,"icon":19},"\u002Farchitecture\u002Fkernel","architecture\u002F1.kernel\u002Findex",[18,20,24],{"title":10,"path":15,"stem":16,"access":12,"icon":19},"i-lucide-box",{"title":21,"path":22,"stem":23,"access":12},"Enclave","\u002Farchitecture\u002Fkernel\u002Fenclave","architecture\u002F1.kernel\u002Fenclave",{"title":25,"path":26,"stem":27,"access":12},"Forking the enclave","\u002Farchitecture\u002Fkernel\u002Fforking-the-enclave","architecture\u002F1.kernel\u002Fforking-the-enclave",{"title":29,"path":30,"stem":31,"access":12},"Ports","\u002Farchitecture\u002Fports","architecture\u002F2.ports",{"title":33,"path":34,"stem":35,"access":12},"Service layers","\u002Farchitecture\u002Fservice-layers","architecture\u002F3.service-layers",{"title":37,"path":38,"stem":39,"access":12},"Families","\u002Farchitecture\u002Ffamilies","architecture\u002F4.families",{"title":41,"path":42,"stem":43,"children":44},"Core","\u002Fcore","core",[45,47,50,53,56,88,97],{"title":10,"path":42,"stem":46,"access":12,"icon":19},"core\u002Findex",{"title":10,"path":48,"stem":49,"access":12},"\u002Fcore\u002F01-overview","core\u002F01-overview",{"title":10,"path":51,"stem":52,"access":12},"\u002Fcore\u002F05-stores","core\u002F05-stores",{"title":10,"path":54,"stem":55,"access":12},"\u002Fcore\u002F06-permissions-and-keyring","core\u002F06-permissions-and-keyring",{"title":10,"path":57,"stem":58,"children":59,"access":12},"\u002Fcore\u002Fnoydb","core\u002F2.noydb\u002Findex",[60,61,65,68,72,76,80,84],{"title":10,"path":57,"stem":58,"access":12},{"title":62,"path":63,"stem":64,"access":12},"Noydb","\u002Fcore\u002Fnoydb\u002Fmethods","core\u002F2.noydb\u002F1.methods",{"title":21,"path":66,"stem":67,"access":12},"\u002Fcore\u002Fnoydb\u002Fenclave","core\u002F2.noydb\u002F2.enclave",{"title":69,"path":70,"stem":71,"access":12},"Secret & keyring","\u002Fcore\u002Fnoydb\u002Fkeyring","core\u002F2.noydb\u002F3.keyring",{"title":73,"path":74,"stem":75,"access":12},"Authentication","\u002Fcore\u002Fnoydb\u002Fauthentication","core\u002F2.noydb\u002F4.authentication",{"title":77,"path":78,"stem":79,"access":12},"Auth recovery","\u002Fcore\u002Fnoydb\u002Frecovery","core\u002F2.noydb\u002F5.recovery",{"title":81,"path":82,"stem":83,"access":12},"Configuration","\u002Fcore\u002Fnoydb\u002Fconfiguration","core\u002F2.noydb\u002F6.configuration",{"title":85,"path":86,"stem":87,"access":12},"Strategies","\u002Fcore\u002Fnoydb\u002Fstrategies","core\u002F2.noydb\u002F7.strategies",{"title":10,"path":89,"stem":90,"children":91,"access":12},"\u002Fcore\u002Fvault","core\u002F3.vault\u002Findex",[92,93],{"title":10,"path":89,"stem":90,"access":12},{"title":94,"path":95,"stem":96,"access":12},"Vault","\u002Fcore\u002Fvault\u002Fmethods","core\u002F3.vault\u002F1.methods",{"title":10,"path":98,"stem":99,"children":100,"access":12},"\u002Fcore\u002Fcollection","core\u002F4.collection\u002Findex",[101,102,106,110],{"title":10,"path":98,"stem":99,"access":12},{"title":103,"path":104,"stem":105,"access":12},"Collection","\u002Fcore\u002Fcollection\u002Fmethods","core\u002F4.collection\u002F1.methods",{"title":107,"path":108,"stem":109,"access":12},"Querying","\u002Fcore\u002Fcollection\u002Fquerying","core\u002F4.collection\u002F2.querying",{"title":111,"path":112,"stem":113,"access":12},"Schema","\u002Fcore\u002Fcollection\u002Fschema","core\u002F4.collection\u002F3.schema",{"title":37,"path":115,"stem":116,"children":117},"\u002Ffamilies","families",[118,121,168,194,208,212,216,294,340],{"title":10,"path":115,"stem":119,"access":12,"icon":120},"families\u002Findex","i-lucide-plug",{"title":122,"path":123,"stem":124,"children":125,"access":12,"icon":127},"as-Exports","\u002Ffamilies\u002Fas","families\u002Fas\u002Findex",[126,128,132,136,140,144,148,152,156,160,164],{"title":122,"path":123,"stem":124,"access":12,"icon":127},"i-lucide-book-open",{"title":129,"path":130,"stem":131,"access":12},"aws-s3","\u002Ffamilies\u002Fas\u002Faws-s3","families\u002Fas\u002Faws-s3",{"title":133,"path":134,"stem":135,"access":12},"blob","\u002Ffamilies\u002Fas\u002Fblob","families\u002Fas\u002Fblob",{"title":137,"path":138,"stem":139,"access":12},"csv","\u002Ffamilies\u002Fas\u002Fcsv","families\u002Fas\u002Fcsv",{"title":141,"path":142,"stem":143,"access":12},"json","\u002Ffamilies\u002Fas\u002Fjson","families\u002Fas\u002Fjson",{"title":145,"path":146,"stem":147,"access":12},"ndjson","\u002Ffamilies\u002Fas\u002Fndjson","families\u002Fas\u002Fndjson",{"title":149,"path":150,"stem":151,"access":12},"noydb","\u002Ffamilies\u002Fas\u002Fnoydb","families\u002Fas\u002Fnoydb",{"title":153,"path":154,"stem":155,"access":12},"sql","\u002Ffamilies\u002Fas\u002Fsql","families\u002Fas\u002Fsql",{"title":157,"path":158,"stem":159,"access":12},"xlsx","\u002Ffamilies\u002Fas\u002Fxlsx","families\u002Fas\u002Fxlsx",{"title":161,"path":162,"stem":163,"access":12},"xml","\u002Ffamilies\u002Fas\u002Fxml","families\u002Fas\u002Fxml",{"title":165,"path":166,"stem":167,"access":12},"zip","\u002Ffamilies\u002Fas\u002Fzip","families\u002Fas\u002Fzip",{"title":169,"path":170,"stem":171,"children":172,"access":12,"icon":127},"at-Seals","\u002Ffamilies\u002Fat","families\u002Fat\u002Findex",[173,174,178,182,186,190],{"title":169,"path":170,"stem":171,"access":12,"icon":127},{"title":175,"path":176,"stem":177,"access":12},"aws-kms","\u002Ffamilies\u002Fat\u002Faws-kms","families\u002Fat\u002Faws-kms",{"title":179,"path":180,"stem":181,"access":12},"azure-keyvault","\u002Ffamilies\u002Fat\u002Fazure-keyvault","families\u002Fat\u002Fazure-keyvault",{"title":183,"path":184,"stem":185,"access":12},"env","\u002Ffamilies\u002Fat\u002Fenv","families\u002Fat\u002Fenv",{"title":187,"path":188,"stem":189,"access":12},"gcp-kms","\u002Ffamilies\u002Fat\u002Fgcp-kms","families\u002Fat\u002Fgcp-kms",{"title":191,"path":192,"stem":193,"access":12},"macos-keychain","\u002Ffamilies\u002Fat\u002Fmacos-keychain","families\u002Fat\u002Fmacos-keychain",{"title":195,"path":196,"stem":197,"children":198,"access":12,"icon":127},"by-Sessions","\u002Ffamilies\u002Fby","families\u002Fby\u002Findex",[199,200,204],{"title":195,"path":196,"stem":197,"access":12,"icon":127},{"title":201,"path":202,"stem":203,"access":12},"peer","\u002Ffamilies\u002Fby\u002Fpeer","families\u002Fby\u002Fpeer",{"title":205,"path":206,"stem":207,"access":12},"tabs","\u002Ffamilies\u002Fby\u002Ftabs","families\u002Fby\u002Ftabs",{"title":209,"path":210,"stem":211,"access":12},"Classifying a package","\u002Ffamilies\u002Fclassification","families\u002Fclassification",{"title":213,"path":214,"stem":215,"access":12},"Command-line tools","\u002Ffamilies\u002Fcli","families\u002Fcli",{"title":217,"path":218,"stem":219,"children":220,"access":12,"icon":127},"in-Frameworks","\u002Ffamilies\u002Fin","families\u002Fin\u002Findex",[221,222,226,230,234,238,242,246,250,254,258,262,266,270,274,278,282,286,290],{"title":217,"path":218,"stem":219,"access":12,"icon":127},{"title":223,"path":224,"stem":225,"access":12},"ai","\u002Ffamilies\u002Fin\u002Fai","families\u002Fin\u002Fai",{"title":227,"path":228,"stem":229,"access":12},"devtools","\u002Ffamilies\u002Fin\u002Fdevtools","families\u002Fin\u002Fdevtools",{"title":231,"path":232,"stem":233,"access":12},"devtools-tui","\u002Ffamilies\u002Fin\u002Fdevtools-tui","families\u002Fin\u002Fdevtools-tui",{"title":235,"path":236,"stem":237,"access":12},"liff","\u002Ffamilies\u002Fin\u002Fliff","families\u002Fin\u002Fliff",{"title":239,"path":240,"stem":241,"access":12},"nextjs","\u002Ffamilies\u002Fin\u002Fnextjs","families\u002Fin\u002Fnextjs",{"title":243,"path":244,"stem":245,"access":12},"nuxt","\u002Ffamilies\u002Fin\u002Fnuxt","families\u002Fin\u002Fnuxt",{"title":247,"path":248,"stem":249,"access":12},"pinia","\u002Ffamilies\u002Fin\u002Fpinia","families\u002Fin\u002Fpinia",{"title":251,"path":252,"stem":253,"access":12},"pwa","\u002Ffamilies\u002Fin\u002Fpwa","families\u002Fin\u002Fpwa",{"title":255,"path":256,"stem":257,"access":12},"react","\u002Ffamilies\u002Fin\u002Freact","families\u002Fin\u002Freact",{"title":259,"path":260,"stem":261,"access":12},"relay","\u002Ffamilies\u002Fin\u002Frelay","families\u002Fin\u002Frelay",{"title":263,"path":264,"stem":265,"access":12},"rest","\u002Ffamilies\u002Fin\u002Frest","families\u002Fin\u002Frest",{"title":267,"path":268,"stem":269,"access":12},"solid","\u002Ffamilies\u002Fin\u002Fsolid","families\u002Fin\u002Fsolid",{"title":271,"path":272,"stem":273,"access":12},"svelte","\u002Ffamilies\u002Fin\u002Fsvelte","families\u002Fin\u002Fsvelte",{"title":275,"path":276,"stem":277,"access":12},"tanstack-query","\u002Ffamilies\u002Fin\u002Ftanstack-query","families\u002Fin\u002Ftanstack-query",{"title":279,"path":280,"stem":281,"access":12},"tanstack-table","\u002Ffamilies\u002Fin\u002Ftanstack-table","families\u002Fin\u002Ftanstack-table",{"title":283,"path":284,"stem":285,"access":12},"vue","\u002Ffamilies\u002Fin\u002Fvue","families\u002Fin\u002Fvue",{"title":287,"path":288,"stem":289,"access":12},"yjs","\u002Ffamilies\u002Fin\u002Fyjs","families\u002Fin\u002Fyjs",{"title":291,"path":292,"stem":293,"access":12},"zustand","\u002Ffamilies\u002Fin\u002Fzustand","families\u002Fin\u002Fzustand",{"title":295,"path":296,"stem":297,"children":298,"access":12,"icon":127},"on-Auth","\u002Ffamilies\u002Fon","families\u002Fon\u002Findex",[299,300,304,308,312,316,320,324,328,332,336],{"title":295,"path":296,"stem":297,"access":12,"icon":127},{"title":301,"path":302,"stem":303,"access":12},"email-otp","\u002Ffamilies\u002Fon\u002Femail-otp","families\u002Fon\u002Femail-otp",{"title":305,"path":306,"stem":307,"access":12},"magic-link","\u002Ffamilies\u002Fon\u002Fmagic-link","families\u002Fon\u002Fmagic-link",{"title":309,"path":310,"stem":311,"access":12},"oidc","\u002Ffamilies\u002Fon\u002Foidc","families\u002Fon\u002Foidc",{"title":313,"path":314,"stem":315,"access":12},"password","\u002Ffamilies\u002Fon\u002Fpassword","families\u002Fon\u002Fpassword",{"title":317,"path":318,"stem":319,"access":12},"pin","\u002Ffamilies\u002Fon\u002Fpin","families\u002Fon\u002Fpin",{"title":321,"path":322,"stem":323,"access":12},"recovery","\u002Ffamilies\u002Fon\u002Frecovery","families\u002Fon\u002Frecovery",{"title":325,"path":326,"stem":327,"access":12},"shamir","\u002Ffamilies\u002Fon\u002Fshamir","families\u002Fon\u002Fshamir",{"title":329,"path":330,"stem":331,"access":12},"threat","\u002Ffamilies\u002Fon\u002Fthreat","families\u002Fon\u002Fthreat",{"title":333,"path":334,"stem":335,"access":12},"totp","\u002Ffamilies\u002Fon\u002Ftotp","families\u002Fon\u002Ftotp",{"title":337,"path":338,"stem":339,"access":12},"webauthn","\u002Ffamilies\u002Fon\u002Fwebauthn","families\u002Fon\u002Fwebauthn",{"title":341,"path":342,"stem":343,"children":344,"access":12,"icon":127},"to-Stores","\u002Ffamilies\u002Fto","families\u002Fto\u002Findex",[345,346,350,353,357,361,365,370,374,378,382,386,390,394,398,402,406,410,414,417,421,425,429,434,438,442],{"title":341,"path":342,"stem":343,"access":12,"icon":127},{"title":347,"path":348,"stem":349,"access":12},"aws-dynamo","\u002Ffamilies\u002Fto\u002Faws-dynamo","families\u002Fto\u002Faws-dynamo",{"title":129,"path":351,"stem":352,"access":12},"\u002Ffamilies\u002Fto\u002Faws-s3","families\u002Fto\u002Faws-s3",{"title":354,"path":355,"stem":356,"access":12},"browser-fs","\u002Ffamilies\u002Fto\u002Fbrowser-fs","families\u002Fto\u002Fbrowser-fs",{"title":358,"path":359,"stem":360,"access":12},"browser-idb","\u002Ffamilies\u002Fto\u002Fbrowser-idb","families\u002Fto\u002Fbrowser-idb",{"title":362,"path":363,"stem":364,"access":12},"browser-local","\u002Ffamilies\u002Fto\u002Fbrowser-local","families\u002Fto\u002Fbrowser-local",{"title":366,"path":367,"stem":368,"access":12,"icon":369},"Choosing a store","\u002Ffamilies\u002Fto\u002Fchoosing-a-store","families\u002Fto\u002Fchoosing-a-store","i-lucide-split",{"title":371,"path":372,"stem":373,"access":12},"cloudflare-d1","\u002Ffamilies\u002Fto\u002Fcloudflare-d1","families\u002Fto\u002Fcloudflare-d1",{"title":375,"path":376,"stem":377,"access":12},"cloudflare-r2","\u002Ffamilies\u002Fto\u002Fcloudflare-r2","families\u002Fto\u002Fcloudflare-r2",{"title":379,"path":380,"stem":381,"access":12},"drive","\u002Ffamilies\u002Fto\u002Fdrive","families\u002Fto\u002Fdrive",{"title":383,"path":384,"stem":385,"access":12},"file","\u002Ffamilies\u002Fto\u002Ffile","families\u002Fto\u002Ffile",{"title":387,"path":388,"stem":389,"access":12},"icloud","\u002Ffamilies\u002Fto\u002Ficloud","families\u002Fto\u002Ficloud",{"title":391,"path":392,"stem":393,"access":12},"memory","\u002Ffamilies\u002Fto\u002Fmemory","families\u002Fto\u002Fmemory",{"title":395,"path":396,"stem":397,"access":12},"meter","\u002Ffamilies\u002Fto\u002Fmeter","families\u002Fto\u002Fmeter",{"title":399,"path":400,"stem":401,"access":12},"mysql","\u002Ffamilies\u002Fto\u002Fmysql","families\u002Fto\u002Fmysql",{"title":403,"path":404,"stem":405,"access":12},"nfs","\u002Ffamilies\u002Fto\u002Fnfs","families\u002Fto\u002Fnfs",{"title":407,"path":408,"stem":409,"access":12},"postgres","\u002Ffamilies\u002Fto\u002Fpostgres","families\u002Fto\u002Fpostgres",{"title":411,"path":412,"stem":413,"access":12},"probe","\u002Ffamilies\u002Fto\u002Fprobe","families\u002Fto\u002Fprobe",{"title":263,"path":415,"stem":416,"access":12},"\u002Ffamilies\u002Fto\u002Frest","families\u002Fto\u002Frest",{"title":418,"path":419,"stem":420,"access":12},"smb","\u002Ffamilies\u002Fto\u002Fsmb","families\u002Fto\u002Fsmb",{"title":422,"path":423,"stem":424,"access":12},"sqlite","\u002Ffamilies\u002Fto\u002Fsqlite","families\u002Fto\u002Fsqlite",{"title":426,"path":427,"stem":428,"access":12},"ssh","\u002Ffamilies\u002Fto\u002Fssh","families\u002Fto\u002Fssh",{"title":430,"path":431,"stem":432,"access":12,"icon":433},"Store-locator descriptors","\u002Ffamilies\u002Fto\u002Fstore-locator","families\u002Fto\u002Fstore-locator","i-lucide-map-pin",{"title":435,"path":436,"stem":437,"access":12},"supabase","\u002Ffamilies\u002Fto\u002Fsupabase","families\u002Fto\u002Fsupabase",{"title":439,"path":440,"stem":441,"access":12},"turso","\u002Ffamilies\u002Fto\u002Fturso","families\u002Fto\u002Fturso",{"title":443,"path":444,"stem":445,"access":12},"webdav","\u002Ffamilies\u002Fto\u002Fwebdav","families\u002Fto\u002Fwebdav",{"title":447,"path":448,"stem":449,"children":450},"Faq","\u002Ffaq","faq",[451,454,458,462,466,470],{"title":10,"path":448,"stem":452,"access":12,"icon":453},"faq\u002Findex","i-lucide-circle-help",{"title":455,"path":456,"stem":457,"access":12},"Where can noy-db run?","\u002Ffaq\u002Fwhere-can-noy-db-run","faq\u002F1.where-can-noy-db-run",{"title":459,"path":460,"stem":461,"access":12},"Native mobile & PWA","\u002Ffaq\u002Fmobile-and-pwa","faq\u002F2.mobile-and-pwa",{"title":463,"path":464,"stem":465,"access":12},"Threat model","\u002Ffaq\u002Fthreat-model","faq\u002F3.threat-model",{"title":467,"path":468,"stem":469,"access":12},"Community & ecosystem","\u002Ffaq\u002Fcommunity-and-ecosystem","faq\u002F4.community-and-ecosystem",{"title":471,"path":472,"stem":473,"access":12},"Licensing","\u002Ffaq\u002Flicensing","faq\u002F5.licensing",{"title":475,"path":476,"stem":477,"children":478},"Glossary","\u002Fglossary","glossary",[479,482,486,490,494],{"title":10,"path":476,"stem":480,"access":12,"icon":481},"glossary\u002Findex","i-lucide-book-a",{"title":483,"path":484,"stem":485,"access":12},"Core vocabulary","\u002Fglossary\u002Fcore-vocabulary","glossary\u002Fcore-vocabulary",{"title":487,"path":488,"stem":489,"access":12},"Deletion vocabulary","\u002Fglossary\u002Fdeletion","glossary\u002Fdeletion",{"title":491,"path":492,"stem":493,"access":12},"Satellite collection vocabulary","\u002Fglossary\u002Fsatellite-collections","glossary\u002Fsatellite-collections",{"title":495,"path":496,"stem":497,"access":12},"Schema migration vocabulary","\u002Fglossary\u002Fschema-migration","glossary\u002Fschema-migration",{"title":499,"path":500,"stem":501,"children":502},"Recipes","\u002Frecipes","recipes",[503,506,510,514,518,522,526,530,534,538,542,546,550,554,558,562,567,571,575,580,584,588,592],{"title":10,"path":500,"stem":504,"access":12,"icon":505},"recipes\u002Findex","i-lucide-play",{"title":507,"path":508,"stem":509,"access":12},"Accounting app","\u002Frecipes\u002Faccounting-app","recipes\u002Faccounting-app",{"title":511,"path":512,"stem":513,"access":12},"Analytics app","\u002Frecipes\u002Fanalytics-app","recipes\u002Fanalytics-app",{"title":515,"path":516,"stem":517,"access":12},"Attestation verifier","\u002Frecipes\u002Fattestation-verifier","recipes\u002Fattestation-verifier",{"title":519,"path":520,"stem":521,"access":12},"AWS-KMS attestation","\u002Frecipes\u002Faws-kms-pdf-attestation","recipes\u002Faws-kms-pdf-attestation",{"title":523,"path":524,"stem":525,"access":12},"Browser durability","\u002Frecipes\u002Fbrowser-durability","recipes\u002Fbrowser-durability",{"title":527,"path":528,"stem":529,"access":12},"Production cloud store","\u002Frecipes\u002Fcloud-store","recipes\u002Fcloud-store",{"title":531,"path":532,"stem":533,"access":12},"Compose your own setup","\u002Frecipes\u002Fcompose-your-own","recipes\u002Fcompose-your-own",{"title":535,"path":536,"stem":537,"access":12},"Confidential HR records","\u002Frecipes\u002Fconfidential-hr","recipes\u002Fconfidential-hr",{"title":539,"path":540,"stem":541,"access":12},"Composing an echo secret","\u002Frecipes\u002Fecho-secret-enrollment","recipes\u002Fecho-secret-enrollment",{"title":543,"path":544,"stem":545,"access":12},"Email archive","\u002Frecipes\u002Femail-archive","recipes\u002Femail-archive",{"title":547,"path":548,"stem":549,"access":12},"Email archive — threads & revisions","\u002Frecipes\u002Femail-archive-threads-revisions","recipes\u002Femail-archive-threads-revisions",{"title":551,"path":552,"stem":553,"access":12},"Export & portability","\u002Frecipes\u002Fexport-portability","recipes\u002Fexport-portability",{"title":555,"path":556,"stem":557,"access":12},"Passwordless OIDC (AWS Cognito)","\u002Frecipes\u002Fpasswordless-oidc","recipes\u002Fpasswordless-oidc",{"title":559,"path":560,"stem":561,"access":12},"Personal notebook","\u002Frecipes\u002Fpersonal-notebook","recipes\u002Fpersonal-notebook",{"title":563,"path":564,"stem":565,"access":12,"icon":566},"Playgrounds","\u002Frecipes\u002Fplaygrounds","recipes\u002Fplaygrounds","i-lucide-gamepad-2",{"title":568,"path":569,"stem":570,"access":12},"React invoice app","\u002Frecipes\u002Freact-invoices","recipes\u002Freact-invoices",{"title":572,"path":573,"stem":574,"access":12},"Collaborative app","\u002Frecipes\u002Frealtime-crdt-app","recipes\u002Frealtime-crdt-app",{"title":576,"path":577,"stem":578,"access":12,"icon":579},"Run the showcases","\u002Frecipes\u002Frun-the-showcases","recipes\u002Frun-the-showcases","i-lucide-flask-conical",{"title":581,"path":582,"stem":583,"access":12},"Search & RAG","\u002Frecipes\u002Fsearch-rag","recipes\u002Fsearch-rag",{"title":585,"path":586,"stem":587,"access":12},"Team vault topology","\u002Frecipes\u002Fteam-vault-topology","recipes\u002Fteam-vault-topology",{"title":589,"path":590,"stem":591,"access":12},"Unlock ceremonies","\u002Frecipes\u002Funlock-ceremonies","recipes\u002Funlock-ceremonies",{"title":593,"path":594,"stem":595,"access":12},"User preferences","\u002Frecipes\u002Fuser-preferences","recipes\u002Fuser-preferences",{"title":597,"path":598,"stem":599,"children":600},"Services","\u002Fservices","services",[601,604,608,612,616,620,624,628,632,636,640,644,648,652,656,660,664,668,672,676,680,684,688,692,696,700,704,710,714,718,722,726,730,734,738,742,746,750,755,759,763,767,771,775,779,783,787,791,795,799,803,807,811,815,819,823,827,831,835,839,843,847,851,855,859,863,867,871,875,879,883,887,891,895,899],{"title":10,"path":598,"stem":602,"access":12,"icon":603},"services\u002Findex","i-lucide-layers",{"title":605,"path":606,"stem":607,"access":12},"archive","\u002Fservices\u002Farchive","services\u002Farchive",{"title":609,"path":610,"stem":611,"access":12},"attestation","\u002Fservices\u002Fattestation","services\u002Fattestation",{"title":613,"path":614,"stem":615,"access":12},"auth-introspection","\u002Fservices\u002Fauth-introspection","services\u002Fauth-introspection",{"title":617,"path":618,"stem":619,"access":12},"auth-landscape","\u002Fservices\u002Fauth-landscape","services\u002Fauth-landscape",{"title":621,"path":622,"stem":623,"access":12},"blobs","\u002Fservices\u002Fblobs","services\u002Fblobs",{"title":625,"path":626,"stem":627,"access":12},"broker","\u002Fservices\u002Fbroker","services\u002Fbroker",{"title":629,"path":630,"stem":631,"access":12},"bundle","\u002Fservices\u002Fbundle","services\u002Fbundle",{"title":633,"path":634,"stem":635,"access":12},"classified","\u002Fservices\u002Fclassified","services\u002Fclassified",{"title":637,"path":638,"stem":639,"access":12},"computed","\u002Fservices\u002Fcomputed","services\u002Fcomputed",{"title":641,"path":642,"stem":643,"access":12},"consent","\u002Fservices\u002Fconsent","services\u002Fconsent",{"title":645,"path":646,"stem":647,"access":12},"cover","\u002Fservices\u002Fcover","services\u002Fcover",{"title":649,"path":650,"stem":651,"access":12},"coverage","\u002Fservices\u002Fcoverage","services\u002Fcoverage",{"title":653,"path":654,"stem":655,"access":12},"crdt","\u002Fservices\u002Fcrdt","services\u002Fcrdt",{"title":657,"path":658,"stem":659,"access":12},"cross-join","\u002Fservices\u002Fcross-join","services\u002Fcross-join",{"title":661,"path":662,"stem":663,"access":12},"custody","\u002Fservices\u002Fcustody","services\u002Fcustody",{"title":665,"path":666,"stem":667,"access":12},"derivations","\u002Fservices\u002Fderivations","services\u002Fderivations",{"title":669,"path":670,"stem":671,"access":12},"directory","\u002Fservices\u002Fdirectory","services\u002Fdirectory",{"title":673,"path":674,"stem":675,"access":12},"search — AI","\u002Fservices\u002Fembeddings","services\u002Fembeddings",{"title":677,"path":678,"stem":679,"access":12},"Field metadata","\u002Fservices\u002Ffield-metadata","services\u002Ffield-metadata",{"title":681,"path":682,"stem":683,"access":12},"Foreign refs","\u002Fservices\u002Fforeign-refs","services\u002Fforeign-refs",{"title":685,"path":686,"stem":687,"access":12},"forget","\u002Fservices\u002Fforget","services\u002Fforget",{"title":689,"path":690,"stem":691,"access":12},"governance","\u002Fservices\u002Fgovernance","services\u002Fgovernance",{"title":693,"path":694,"stem":695,"access":12},"guards","\u002Fservices\u002Fguards","services\u002Fguards",{"title":697,"path":698,"stem":699,"access":12},"history","\u002Fservices\u002Fhistory","services\u002Fhistory",{"title":701,"path":702,"stem":703,"access":12},"i18n","\u002Fservices\u002Fi18n","services\u002Fi18n",{"title":705,"path":706,"stem":707,"children":708,"access":12},"indexing","\u002Fservices\u002Findexing","services\u002Findexing",[709],{"title":705,"path":706,"stem":707,"access":12},{"title":711,"path":712,"stem":713,"access":12},"introspection","\u002Fservices\u002Fintrospection","services\u002Fintrospection",{"title":715,"path":716,"stem":717,"access":12},"joins","\u002Fservices\u002Fjoins","services\u002Fjoins",{"title":719,"path":720,"stem":721,"access":12},"lazy","\u002Fservices\u002Flazy","services\u002Flazy",{"title":723,"path":724,"stem":725,"access":12},"links","\u002Fservices\u002Flinks","services\u002Flinks",{"title":727,"path":728,"stem":729,"access":12},"live","\u002Fservices\u002Flive","services\u002Flive",{"title":731,"path":732,"stem":733,"access":12},"lookup","\u002Fservices\u002Flookup","services\u002Flookup",{"title":735,"path":736,"stem":737,"access":12},"manifest","\u002Fservices\u002Fmanifest","services\u002Fmanifest",{"title":739,"path":740,"stem":741,"access":12},"materialized-views","\u002Fservices\u002Fmaterialized-views","services\u002Fmaterialized-views",{"title":743,"path":744,"stem":745,"access":12},"Metadata ladder","\u002Fservices\u002Fmetadata-ladder","services\u002Fmetadata-ladder",{"title":747,"path":748,"stem":749,"access":12},"Metadata riders","\u002Fservices\u002Fmetadata-riders","services\u002Fmetadata-riders",{"title":751,"path":752,"stem":753,"access":12,"badge":754},"metrics","\u002Fservices\u002Fmetrics","services\u002Fmetrics","Planned",{"title":756,"path":757,"stem":758,"access":12,"badge":754},"migrations","\u002Fservices\u002Fmigrations","services\u002Fmigrations",{"title":760,"path":761,"stem":762,"access":12},"money","\u002Fservices\u002Fmoney","services\u002Fmoney",{"title":764,"path":765,"stem":766,"access":12},"numbering","\u002Fservices\u002Fnumbering","services\u002Fnumbering",{"title":768,"path":769,"stem":770,"access":12},"overlay-views","\u002Fservices\u002Foverlay-views","services\u002Foverlay-views",{"title":772,"path":773,"stem":774,"access":12,"badge":754},"partitioning","\u002Fservices\u002Fpartitioning","services\u002Fpartitioning",{"title":776,"path":777,"stem":778,"access":12},"periods","\u002Fservices\u002Fperiods","services\u002Fperiods",{"title":780,"path":781,"stem":782,"access":12},"persisted-schemas","\u002Fservices\u002Fpersisted-schemas","services\u002Fpersisted-schemas",{"title":784,"path":785,"stem":786,"access":12},"plaintext-bypass","\u002Fservices\u002Fplaintext-bypass","services\u002Fplaintext-bypass",{"title":788,"path":789,"stem":790,"access":12},"pod-redirect","\u002Fservices\u002Fpod-redirect","services\u002Fpod-redirect",{"title":792,"path":793,"stem":794,"access":12},"pod-signature","\u002Fservices\u002Fpod-signature","services\u002Fpod-signature",{"title":796,"path":797,"stem":798,"access":12},"policy","\u002Fservices\u002Fpolicy","services\u002Fpolicy",{"title":800,"path":801,"stem":802,"access":12},"portability","\u002Fservices\u002Fportability","services\u002Fportability",{"title":804,"path":805,"stem":806,"access":12},"reduce","\u002Fservices\u002Freduce","services\u002Freduce",{"title":808,"path":809,"stem":810,"access":12},"routing","\u002Fservices\u002Frouting","services\u002Frouting",{"title":812,"path":813,"stem":814,"access":12},"satellites","\u002Fservices\u002Fsatellites","services\u002Fsatellites",{"title":816,"path":817,"stem":818,"access":12},"schema-identifiers","\u002Fservices\u002Fschema-identifiers","services\u002Fschema-identifiers",{"title":820,"path":821,"stem":822,"access":12},"schema-update","\u002Fservices\u002Fschema-update","services\u002Fschema-update",{"title":824,"path":825,"stem":826,"access":12},"sealed-record","\u002Fservices\u002Fsealed-record","services\u002Fsealed-record",{"title":828,"path":829,"stem":830,"access":12},"sealing provider id","\u002Fservices\u002Fsealing-pid-stability","services\u002Fsealing-pid-stability",{"title":832,"path":833,"stem":834,"access":12},"search — full-text","\u002Fservices\u002Fsearch","services\u002Fsearch",{"title":836,"path":837,"stem":838,"access":12},"sequence","\u002Fservices\u002Fsequence","services\u002Fsequence",{"title":840,"path":841,"stem":842,"access":12},"session","\u002Fservices\u002Fsession","services\u002Fsession",{"title":844,"path":845,"stem":846,"access":12},"session-tiers","\u002Fservices\u002Fsession-tiers","services\u002Fsession-tiers",{"title":848,"path":849,"stem":850,"access":12},"shadow","\u002Fservices\u002Fshadow","services\u002Fshadow",{"title":852,"path":853,"stem":854,"access":12},"share-link","\u002Fservices\u002Fshare-link","services\u002Fshare-link",{"title":856,"path":857,"stem":858,"access":12},"snapshots","\u002Fservices\u002Fsnapshots","services\u002Fsnapshots",{"title":860,"path":861,"stem":862,"access":12},"store capabilities","\u002Fservices\u002Fstorage-capability-matrix","services\u002Fstorage-capability-matrix",{"title":864,"path":865,"stem":866,"access":12},"sync","\u002Fservices\u002Fsync","services\u002Fsync",{"title":868,"path":869,"stem":870,"access":12},"team","\u002Fservices\u002Fteam","services\u002Fteam",{"title":872,"path":873,"stem":874,"access":12},"tiers","\u002Fservices\u002Ftiers","services\u002Ftiers",{"title":876,"path":877,"stem":878,"access":12},"transactions","\u002Fservices\u002Ftransactions","services\u002Ftransactions",{"title":880,"path":881,"stem":882,"access":12},"partitions","\u002Fservices\u002Ftransferable-partitions","services\u002Ftransferable-partitions",{"title":884,"path":885,"stem":886,"access":12},"user-envelope","\u002Fservices\u002Fuser-envelope","services\u002Fuser-envelope",{"title":888,"path":889,"stem":890,"access":12,"badge":754},"validation","\u002Fservices\u002Fvalidation","services\u002Fvalidation",{"title":892,"path":893,"stem":894,"access":12},"vault-head","\u002Fservices\u002Fvault-head","services\u002Fvault-head",{"title":896,"path":897,"stem":898,"access":12},"via","\u002Fservices\u002Fvia","services\u002Fvia",{"title":900,"path":901,"stem":902,"access":12},"withdrawal","\u002Fservices\u002Fwithdrawal","services\u002Fwithdrawal",{"title":904,"path":905,"stem":906,"children":907},"Start","\u002Fstart","start",[908,911,915,919,923],{"title":10,"path":905,"stem":909,"access":12,"icon":910},"start\u002Findex","i-lucide-flag",{"title":912,"path":913,"stem":914,"access":12},"Install","\u002Fstart\u002Finstall","start\u002F1.install",{"title":916,"path":917,"stem":918,"access":12},"Your first vault","\u002Fstart\u002Ffirst-vault","start\u002F2.first-vault",{"title":920,"path":921,"stem":922,"access":12},"Your first service","\u002Fstart\u002Ffirst-service","start\u002F3.first-service",{"title":924,"path":925,"stem":926,"access":12},"See the ciphertext","\u002Fstart\u002Fsee-the-ciphertext","start\u002F4.see-the-ciphertext",{"id":928,"title":884,"access":12,"apiToc":929,"body":930,"category":3331,"description":3332,"extension":3333,"meta":3334,"navigation":3331,"nest":3335,"path":885,"seo":3336,"sinceVersion":3331,"status":3337,"stem":886,"subtitle":3331,"tier":3338,"tocExternal":3331,"__hash__":3339},"docs\u002Fservices\u002Fuser-envelope.md",false,{"type":931,"value":932,"toc":3306},"minimark",[933,936,940,945,974,1014,1018,1032,1036,1046,1315,1319,1324,1334,1388,1392,1403,1451,1455,1461,1611,1615,1619,1766,1785,1788,1886,1902,1942,1948,1996,2001,2071,2087,2090,2177,2196,2200,2237,2244,2419,2425,2523,2545,2549,2563,2567,2574,2670,2686,2710,2714,2717,2774,2780,2803,2808,2832,2837,2845,2849,2917,2921,2965,2969,3041,3045,3050,3209,3233,3246,3253,3257,3302],[934,935,884],"h1",{"id":884},[937,938],"service-meta",{":rows":939},"[{\"label\":\"Subpath\",\"value\":\"`@noy-db\u002Fhub` (root export)\"},{\"label\":\"Type\",\"value\":\"Core feature — exposed as `vault.user.*`, always available.\"}]",[941,942,944],"h2",{"id":943},"what-it-does","What it does",[946,947,948,949,956,957,960,961,965,966,969,970,973],"p",{},"Every noy-db vault can hold more than one user. Each user unlocks the vault with their own\n",[950,951,952],"a",{"href":54},[953,954,955],"strong",{},"keyring"," — the per-principal set of wrapped keys that\ngrants them access — and this service gives every keyring a small JSON object to store its own\nprofile and preferences (display name, theme, locale, whatever the app needs), living alongside\nit in the vault. That object is called a ",[953,958,959],{},"user envelope",": it's stored at ",[962,963,964],"code",{},"_users\u002F\u003CkeyringId>",",\nencrypted under a DEK (data-encryption key) shared by every keyring in the vault, and only ever\nwritten by the user it belongs to — hub commits only to ",[962,967,968],{},"userId === keyringId"," and where the\nenvelope lives; the shape of the data inside is entirely up to the app. Three method families on\n",[962,971,972],{},"vault.user.*",":",[975,976,977,988,1005],"ul",{},[978,979,980,983,984,987],"li",{},[953,981,982],{},"Write-self"," — ",[962,985,986],{},"me() \u002F updateMe(patch) \u002F setMe(payload)",". Always target the writer's own keyringId; there is no API method to write someone else's envelope.",[978,989,990,983,993,996,997,1000,1001,1004],{},[953,991,992],{},"Read-anyone",[962,994,995],{},"get(keyringId) \u002F list()",". Gated by ",[962,998,999],{},"view-team-profiles"," (default ",[962,1002,1003],{},"minTier: 2",").",[978,1006,1007,983,1010,1013],{},[953,1008,1009],{},"Reactive",[962,1011,1012],{},"subscribe(id, cb) \u002F live(id)",". In-process event emission on local writes.",[941,1015,1017],{"id":1016},"when-you-need-it","When you need it",[975,1019,1020,1023,1026,1029],{},[978,1021,1022],{},"A multi-user vault where each user wants their own UI preferences (theme, locale) that follow them across devices via the team\u002Fsync engine.",[978,1024,1025],{},"A team-aware app rendering \"who's online\" or \"who edited this record\" with display names + avatars sourced consistently from one place.",[978,1027,1028],{},"An accounting-style app where each user has a profile (signature, default currency map, per-client overrides) that travels with the vault.",[978,1030,1031],{},"Admin onboarding flows that pre-fill a teammate's display name and locale at invite time.",[941,1033,1035],{"id":1034},"setup","Setup",[946,1037,1038,1039,1042,1043,1045],{},"None — ",[962,1040,1041],{},"vault.user"," is always available on every ",[962,1044,94],{},". The first write lazily provisions any state the underlying primitive needs:",[1047,1048,1053],"pre",{"className":1049,"code":1050,"language":1051,"meta":1052,"style":1052},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createNoydb } from '@noy-db\u002Fhub'\n\n\u002F\u002F No store → the kernel's built-in in-memory default (0.3).\nconst db = await createNoydb({ user: 'alice', secret: 'pass-2026' })\nconst vault = await db.openVault('demo')\n\nawait vault.user.updateMe({\n  profile: { displayName: 'Alice' },\n  preferences: { theme: 'dark' },\n})\n\u002F\u002F → {\n\u002F\u002F     keyringId: 'alice',\n\u002F\u002F     data: { profile: { displayName: 'Alice' }, preferences: { theme: 'dark' } },\n\u002F\u002F     _v: 1,\n\u002F\u002F     _ts: '2026-05-05T10:00:00.000Z',\n\u002F\u002F   }\n","ts","",[962,1054,1055,1088,1095,1102,1161,1193,1198,1222,1247,1271,1279,1285,1291,1297,1303,1309],{"__ignoreMap":1052},[1056,1057,1060,1064,1068,1072,1075,1078,1081,1085],"span",{"class":1058,"line":1059},"line",1,[1056,1061,1063],{"class":1062},"s7zQu","import",[1056,1065,1067],{"class":1066},"sMK4o"," {",[1056,1069,1071],{"class":1070},"sTEyZ"," createNoydb",[1056,1073,1074],{"class":1066}," }",[1056,1076,1077],{"class":1062}," from",[1056,1079,1080],{"class":1066}," '",[1056,1082,1084],{"class":1083},"sfazB","@noy-db\u002Fhub",[1056,1086,1087],{"class":1066},"'\n",[1056,1089,1091],{"class":1058,"line":1090},2,[1056,1092,1094],{"emptyLinePlaceholder":1093},true,"\n",[1056,1096,1098],{"class":1058,"line":1097},3,[1056,1099,1101],{"class":1100},"sHwdD","\u002F\u002F No store → the kernel's built-in in-memory default (0.3).\n",[1056,1103,1105,1109,1112,1115,1118,1121,1124,1127,1131,1133,1135,1138,1141,1144,1147,1149,1151,1154,1156,1158],{"class":1058,"line":1104},4,[1056,1106,1108],{"class":1107},"spNyl","const",[1056,1110,1111],{"class":1070}," db ",[1056,1113,1114],{"class":1066},"=",[1056,1116,1117],{"class":1062}," await",[1056,1119,1071],{"class":1120},"s2Zo4",[1056,1122,1123],{"class":1070},"(",[1056,1125,1126],{"class":1066},"{",[1056,1128,1130],{"class":1129},"swJcz"," user",[1056,1132,973],{"class":1066},[1056,1134,1080],{"class":1066},[1056,1136,1137],{"class":1083},"alice",[1056,1139,1140],{"class":1066},"'",[1056,1142,1143],{"class":1066},",",[1056,1145,1146],{"class":1129}," secret",[1056,1148,973],{"class":1066},[1056,1150,1080],{"class":1066},[1056,1152,1153],{"class":1083},"pass-2026",[1056,1155,1140],{"class":1066},[1056,1157,1074],{"class":1066},[1056,1159,1160],{"class":1070},")\n",[1056,1162,1164,1166,1169,1171,1173,1176,1179,1182,1184,1186,1189,1191],{"class":1058,"line":1163},5,[1056,1165,1108],{"class":1107},[1056,1167,1168],{"class":1070}," vault ",[1056,1170,1114],{"class":1066},[1056,1172,1117],{"class":1062},[1056,1174,1175],{"class":1070}," db",[1056,1177,1178],{"class":1066},".",[1056,1180,1181],{"class":1120},"openVault",[1056,1183,1123],{"class":1070},[1056,1185,1140],{"class":1066},[1056,1187,1188],{"class":1083},"demo",[1056,1190,1140],{"class":1066},[1056,1192,1160],{"class":1070},[1056,1194,1196],{"class":1058,"line":1195},6,[1056,1197,1094],{"emptyLinePlaceholder":1093},[1056,1199,1201,1204,1207,1209,1212,1214,1217,1219],{"class":1058,"line":1200},7,[1056,1202,1203],{"class":1062},"await",[1056,1205,1206],{"class":1070}," vault",[1056,1208,1178],{"class":1066},[1056,1210,1211],{"class":1070},"user",[1056,1213,1178],{"class":1066},[1056,1215,1216],{"class":1120},"updateMe",[1056,1218,1123],{"class":1070},[1056,1220,1221],{"class":1066},"{\n",[1056,1223,1225,1228,1230,1232,1235,1237,1239,1242,1244],{"class":1058,"line":1224},8,[1056,1226,1227],{"class":1129},"  profile",[1056,1229,973],{"class":1066},[1056,1231,1067],{"class":1066},[1056,1233,1234],{"class":1129}," displayName",[1056,1236,973],{"class":1066},[1056,1238,1080],{"class":1066},[1056,1240,1241],{"class":1083},"Alice",[1056,1243,1140],{"class":1066},[1056,1245,1246],{"class":1066}," },\n",[1056,1248,1250,1253,1255,1257,1260,1262,1264,1267,1269],{"class":1058,"line":1249},9,[1056,1251,1252],{"class":1129},"  preferences",[1056,1254,973],{"class":1066},[1056,1256,1067],{"class":1066},[1056,1258,1259],{"class":1129}," theme",[1056,1261,973],{"class":1066},[1056,1263,1080],{"class":1066},[1056,1265,1266],{"class":1083},"dark",[1056,1268,1140],{"class":1066},[1056,1270,1246],{"class":1066},[1056,1272,1274,1277],{"class":1058,"line":1273},10,[1056,1275,1276],{"class":1066},"}",[1056,1278,1160],{"class":1070},[1056,1280,1282],{"class":1058,"line":1281},11,[1056,1283,1284],{"class":1100},"\u002F\u002F → {\n",[1056,1286,1288],{"class":1058,"line":1287},12,[1056,1289,1290],{"class":1100},"\u002F\u002F     keyringId: 'alice',\n",[1056,1292,1294],{"class":1058,"line":1293},13,[1056,1295,1296],{"class":1100},"\u002F\u002F     data: { profile: { displayName: 'Alice' }, preferences: { theme: 'dark' } },\n",[1056,1298,1300],{"class":1058,"line":1299},14,[1056,1301,1302],{"class":1100},"\u002F\u002F     _v: 1,\n",[1056,1304,1306],{"class":1058,"line":1305},15,[1056,1307,1308],{"class":1100},"\u002F\u002F     _ts: '2026-05-05T10:00:00.000Z',\n",[1056,1310,1312],{"class":1058,"line":1311},16,[1056,1313,1314],{"class":1100},"\u002F\u002F   }\n",[941,1316,1318],{"id":1317},"usage","Usage",[1320,1321,1323],"h3",{"id":1322},"read-your-own-envelope","Read your own envelope",[946,1325,1326,1329,1330,1333],{},[962,1327,1328],{},"me()"," returns the writer's own envelope, or ",[962,1331,1332],{},"null"," if they've never written one — it's never\ngated, since reading your own data needs no permission check:",[1047,1335,1337],{"className":1049,"code":1336,"language":1051,"meta":1052,"style":1052},"const mine = await vault.user.me()\n\u002F\u002F → {\n\u002F\u002F     keyringId: 'alice',\n\u002F\u002F     data: { profile: { displayName: 'Alice' }, preferences: { theme: 'dark' } },\n\u002F\u002F     _v: 1,\n\u002F\u002F     _ts: '2026-05-05T10:00:00.000Z',\n\u002F\u002F   }\n",[962,1338,1339,1364,1368,1372,1376,1380,1384],{"__ignoreMap":1052},[1056,1340,1341,1343,1346,1348,1350,1352,1354,1356,1358,1361],{"class":1058,"line":1059},[1056,1342,1108],{"class":1107},[1056,1344,1345],{"class":1070}," mine ",[1056,1347,1114],{"class":1066},[1056,1349,1117],{"class":1062},[1056,1351,1206],{"class":1070},[1056,1353,1178],{"class":1066},[1056,1355,1211],{"class":1070},[1056,1357,1178],{"class":1066},[1056,1359,1360],{"class":1120},"me",[1056,1362,1363],{"class":1070},"()\n",[1056,1365,1366],{"class":1058,"line":1090},[1056,1367,1284],{"class":1100},[1056,1369,1370],{"class":1058,"line":1097},[1056,1371,1290],{"class":1100},[1056,1373,1374],{"class":1058,"line":1104},[1056,1375,1296],{"class":1100},[1056,1377,1378],{"class":1058,"line":1163},[1056,1379,1302],{"class":1100},[1056,1381,1382],{"class":1058,"line":1195},[1056,1383,1308],{"class":1100},[1056,1385,1386],{"class":1058,"line":1200},[1056,1387,1314],{"class":1100},[1320,1389,1391],{"id":1390},"read-a-teammates-envelope","Read a teammate's envelope",[946,1393,1394,1397,1398,1000,1400,1402],{},[962,1395,1396],{},"get(keyringId)"," reads any principal's envelope by id. Reading someone else's envelope is\ngated by ",[962,1399,999],{},[962,1401,1003],{},") — reading your own is not:",[1047,1404,1406],{"className":1049,"code":1405,"language":1051,"meta":1052,"style":1052},"const bobs = await vault.user.get('bob')\n\u002F\u002F → { keyringId: 'bob', data: { profile: { displayName: 'Bob' } }, _v: 1, _ts: '2026-05-05T10:05:00.000Z' }\n\u002F\u002F throws PolicyDeniedError if the caller's session tier is below view-team-profiles' minTier\n",[962,1407,1408,1441,1446],{"__ignoreMap":1052},[1056,1409,1410,1412,1415,1417,1419,1421,1423,1425,1427,1430,1432,1434,1437,1439],{"class":1058,"line":1059},[1056,1411,1108],{"class":1107},[1056,1413,1414],{"class":1070}," bobs ",[1056,1416,1114],{"class":1066},[1056,1418,1117],{"class":1062},[1056,1420,1206],{"class":1070},[1056,1422,1178],{"class":1066},[1056,1424,1211],{"class":1070},[1056,1426,1178],{"class":1066},[1056,1428,1429],{"class":1120},"get",[1056,1431,1123],{"class":1070},[1056,1433,1140],{"class":1066},[1056,1435,1436],{"class":1083},"bob",[1056,1438,1140],{"class":1066},[1056,1440,1160],{"class":1070},[1056,1442,1443],{"class":1058,"line":1090},[1056,1444,1445],{"class":1100},"\u002F\u002F → { keyringId: 'bob', data: { profile: { displayName: 'Bob' } }, _v: 1, _ts: '2026-05-05T10:05:00.000Z' }\n",[1056,1447,1448],{"class":1058,"line":1097},[1056,1449,1450],{"class":1100},"\u002F\u002F throws PolicyDeniedError if the caller's session tier is below view-team-profiles' minTier\n",[1320,1452,1454],{"id":1453},"react-to-local-writes","React to local writes",[946,1456,1457,1460],{},[962,1458,1459],{},"subscribe(keyringId, cb)"," fires synchronously whenever that principal writes their own\nenvelope from this process:",[1047,1462,1464],{"className":1049,"code":1463,"language":1051,"meta":1052,"style":1052},"const unsubscribe = vault.user.subscribe('alice', (env) => {\n  console.log(env?.data.preferences?.theme)\n})\n\nawait vault.user.updateMe({ preferences: { theme: 'light' } })\n\u002F\u002F → the subscriber above fires synchronously: logs 'light'\n\nunsubscribe()\n",[962,1465,1466,1511,1543,1549,1553,1595,1600,1604],{"__ignoreMap":1052},[1056,1467,1468,1470,1473,1475,1477,1479,1481,1483,1486,1488,1490,1492,1494,1496,1499,1502,1505,1508],{"class":1058,"line":1059},[1056,1469,1108],{"class":1107},[1056,1471,1472],{"class":1070}," unsubscribe ",[1056,1474,1114],{"class":1066},[1056,1476,1206],{"class":1070},[1056,1478,1178],{"class":1066},[1056,1480,1211],{"class":1070},[1056,1482,1178],{"class":1066},[1056,1484,1485],{"class":1120},"subscribe",[1056,1487,1123],{"class":1070},[1056,1489,1140],{"class":1066},[1056,1491,1137],{"class":1083},[1056,1493,1140],{"class":1066},[1056,1495,1143],{"class":1066},[1056,1497,1498],{"class":1066}," (",[1056,1500,183],{"class":1501},"sHdIc",[1056,1503,1504],{"class":1066},")",[1056,1506,1507],{"class":1107}," =>",[1056,1509,1510],{"class":1066}," {\n",[1056,1512,1513,1516,1518,1521,1523,1525,1528,1531,1533,1536,1538,1541],{"class":1058,"line":1090},[1056,1514,1515],{"class":1070},"  console",[1056,1517,1178],{"class":1066},[1056,1519,1520],{"class":1120},"log",[1056,1522,1123],{"class":1129},[1056,1524,183],{"class":1070},[1056,1526,1527],{"class":1066},"?.",[1056,1529,1530],{"class":1070},"data",[1056,1532,1178],{"class":1066},[1056,1534,1535],{"class":1070},"preferences",[1056,1537,1527],{"class":1066},[1056,1539,1540],{"class":1070},"theme",[1056,1542,1160],{"class":1129},[1056,1544,1545,1547],{"class":1058,"line":1097},[1056,1546,1276],{"class":1066},[1056,1548,1160],{"class":1070},[1056,1550,1551],{"class":1058,"line":1104},[1056,1552,1094],{"emptyLinePlaceholder":1093},[1056,1554,1555,1557,1559,1561,1563,1565,1567,1569,1571,1574,1576,1578,1580,1582,1584,1587,1589,1591,1593],{"class":1058,"line":1163},[1056,1556,1203],{"class":1062},[1056,1558,1206],{"class":1070},[1056,1560,1178],{"class":1066},[1056,1562,1211],{"class":1070},[1056,1564,1178],{"class":1066},[1056,1566,1216],{"class":1120},[1056,1568,1123],{"class":1070},[1056,1570,1126],{"class":1066},[1056,1572,1573],{"class":1129}," preferences",[1056,1575,973],{"class":1066},[1056,1577,1067],{"class":1066},[1056,1579,1259],{"class":1129},[1056,1581,973],{"class":1066},[1056,1583,1080],{"class":1066},[1056,1585,1586],{"class":1083},"light",[1056,1588,1140],{"class":1066},[1056,1590,1074],{"class":1066},[1056,1592,1074],{"class":1066},[1056,1594,1160],{"class":1070},[1056,1596,1597],{"class":1058,"line":1195},[1056,1598,1599],{"class":1100},"\u002F\u002F → the subscriber above fires synchronously: logs 'light'\n",[1056,1601,1602],{"class":1058,"line":1200},[1056,1603,1094],{"emptyLinePlaceholder":1093},[1056,1605,1606,1609],{"class":1058,"line":1224},[1056,1607,1608],{"class":1120},"unsubscribe",[1056,1610,1363],{"class":1070},[941,1612,1614],{"id":1613},"api","API",[1320,1616,1618],{"id":1617},"write-self-own-envelope-only","Write-self (own envelope only)",[1047,1620,1622],{"className":1049,"code":1621,"language":1051,"meta":1052,"style":1052},"vault.user.me\u003CT>(): Promise\u003CUserEnvelope\u003CT> | null>\nvault.user.updateMe\u003CT>(patch: DeepPartial\u003CT>, presented?): Promise\u003CUserEnvelope\u003CT>>\nvault.user.setMe\u003CT>(payload: T, presented?): Promise\u003CUserEnvelope\u003CT>>\n",[962,1623,1624,1670,1722],{"__ignoreMap":1052},[1056,1625,1626,1629,1631,1633,1635,1637,1640,1644,1647,1650,1653,1655,1658,1660,1662,1664,1667],{"class":1058,"line":1059},[1056,1627,1628],{"class":1070},"vault",[1056,1630,1178],{"class":1066},[1056,1632,1211],{"class":1070},[1056,1634,1178],{"class":1066},[1056,1636,1360],{"class":1120},[1056,1638,1639],{"class":1066},"\u003C",[1056,1641,1643],{"class":1642},"sBMFI","T",[1056,1645,1646],{"class":1066},">",[1056,1648,1649],{"class":1070},"(): ",[1056,1651,1652],{"class":1642},"Promise",[1056,1654,1639],{"class":1066},[1056,1656,1657],{"class":1070},"UserEnvelope",[1056,1659,1639],{"class":1066},[1056,1661,1643],{"class":1070},[1056,1663,1646],{"class":1066},[1056,1665,1666],{"class":1066}," |",[1056,1668,1669],{"class":1066}," null>\n",[1056,1671,1672,1674,1676,1678,1680,1682,1684,1686,1688,1691,1693,1695,1698,1701,1704,1706,1708,1711,1713,1715,1717,1719],{"class":1058,"line":1090},[1056,1673,1628],{"class":1070},[1056,1675,1178],{"class":1066},[1056,1677,1211],{"class":1070},[1056,1679,1178],{"class":1066},[1056,1681,1216],{"class":1120},[1056,1683,1639],{"class":1066},[1056,1685,1643],{"class":1642},[1056,1687,1646],{"class":1066},[1056,1689,1690],{"class":1070},"(patch: DeepPartial",[1056,1692,1639],{"class":1066},[1056,1694,1643],{"class":1070},[1056,1696,1697],{"class":1066},">,",[1056,1699,1700],{"class":1070}," presented",[1056,1702,1703],{"class":1066},"?",[1056,1705,1504],{"class":1070},[1056,1707,973],{"class":1066},[1056,1709,1710],{"class":1642}," Promise",[1056,1712,1639],{"class":1066},[1056,1714,1657],{"class":1070},[1056,1716,1639],{"class":1066},[1056,1718,1643],{"class":1070},[1056,1720,1721],{"class":1066},">>\n",[1056,1723,1724,1726,1728,1730,1732,1735,1737,1739,1741,1744,1746,1748,1750,1752,1754,1756,1758,1760,1762,1764],{"class":1058,"line":1097},[1056,1725,1628],{"class":1070},[1056,1727,1178],{"class":1066},[1056,1729,1211],{"class":1070},[1056,1731,1178],{"class":1066},[1056,1733,1734],{"class":1120},"setMe",[1056,1736,1639],{"class":1066},[1056,1738,1643],{"class":1642},[1056,1740,1646],{"class":1066},[1056,1742,1743],{"class":1070},"(payload: T",[1056,1745,1143],{"class":1066},[1056,1747,1700],{"class":1070},[1056,1749,1703],{"class":1066},[1056,1751,1504],{"class":1070},[1056,1753,973],{"class":1066},[1056,1755,1710],{"class":1642},[1056,1757,1639],{"class":1066},[1056,1759,1657],{"class":1070},[1056,1761,1639],{"class":1066},[1056,1763,1643],{"class":1070},[1056,1765,1721],{"class":1066},[946,1767,1768,1769,1772,1773,1776,1777,1780,1781,1784],{},"Each call goes through the ",[962,1770,1771],{},"edit-own-profile"," policy gate (default ",[962,1774,1775],{},"minTier: 3","). Pass ",[962,1778,1779],{},"presented: { factors, sharedDevice }"," to satisfy tightened policies (e.g. ",[962,1782,1783],{},"STRICT_POLICY"," requires a TOTP or email-OTP proof for profile edits).",[1320,1786,992],{"id":1787},"read-anyone",[1047,1789,1791],{"className":1049,"code":1790,"language":1051,"meta":1052,"style":1052},"vault.user.get\u003CT>(keyringId: string, presented?): Promise\u003CUserEnvelope\u003CT> | null>\nvault.user.list\u003CT>(presented?): Promise\u003CUserEnvelope\u003CT>[]>\n",[962,1792,1793,1840],{"__ignoreMap":1052},[1056,1794,1795,1797,1799,1801,1803,1805,1807,1809,1811,1814,1816,1818,1820,1822,1824,1826,1828,1830,1832,1834,1836,1838],{"class":1058,"line":1059},[1056,1796,1628],{"class":1070},[1056,1798,1178],{"class":1066},[1056,1800,1211],{"class":1070},[1056,1802,1178],{"class":1066},[1056,1804,1429],{"class":1120},[1056,1806,1639],{"class":1066},[1056,1808,1643],{"class":1642},[1056,1810,1646],{"class":1066},[1056,1812,1813],{"class":1070},"(keyringId: string",[1056,1815,1143],{"class":1066},[1056,1817,1700],{"class":1070},[1056,1819,1703],{"class":1066},[1056,1821,1504],{"class":1070},[1056,1823,973],{"class":1066},[1056,1825,1710],{"class":1642},[1056,1827,1639],{"class":1066},[1056,1829,1657],{"class":1070},[1056,1831,1639],{"class":1066},[1056,1833,1643],{"class":1070},[1056,1835,1646],{"class":1066},[1056,1837,1666],{"class":1066},[1056,1839,1669],{"class":1066},[1056,1841,1842,1844,1846,1848,1850,1853,1855,1857,1859,1862,1864,1866,1868,1870,1872,1874,1876,1878,1880,1883],{"class":1058,"line":1090},[1056,1843,1628],{"class":1070},[1056,1845,1178],{"class":1066},[1056,1847,1211],{"class":1070},[1056,1849,1178],{"class":1066},[1056,1851,1852],{"class":1120},"list",[1056,1854,1639],{"class":1066},[1056,1856,1643],{"class":1642},[1056,1858,1646],{"class":1066},[1056,1860,1861],{"class":1070},"(presented",[1056,1863,1703],{"class":1066},[1056,1865,1504],{"class":1070},[1056,1867,973],{"class":1066},[1056,1869,1710],{"class":1642},[1056,1871,1639],{"class":1066},[1056,1873,1657],{"class":1070},[1056,1875,1639],{"class":1066},[1056,1877,1643],{"class":1070},[1056,1879,1646],{"class":1066},[1056,1881,1882],{"class":1070},"[]",[1056,1884,1885],{"class":1066},">\n",[946,1887,1888,1890,1891,1893,1894,1901],{},[962,1889,1396],{}," is gated by ",[962,1892,999],{}," ",[1895,1896,1897,1898],"em",{},"only when ",[962,1899,1900],{},"keyringId !== self"," — reading your own envelope is never gated.",[1047,1903,1905],{"className":1049,"code":1904,"language":1051,"meta":1052,"style":1052},"const bob = await vault.user.get('bob')\n\u002F\u002F → { keyringId: 'bob', data: { profile: { displayName: 'Bob' } }, _v: 1, _ts: '2026-05-05T10:05:00.000Z' }\n",[962,1906,1907,1938],{"__ignoreMap":1052},[1056,1908,1909,1911,1914,1916,1918,1920,1922,1924,1926,1928,1930,1932,1934,1936],{"class":1058,"line":1059},[1056,1910,1108],{"class":1107},[1056,1912,1913],{"class":1070}," bob ",[1056,1915,1114],{"class":1066},[1056,1917,1117],{"class":1062},[1056,1919,1206],{"class":1070},[1056,1921,1178],{"class":1066},[1056,1923,1211],{"class":1070},[1056,1925,1178],{"class":1066},[1056,1927,1429],{"class":1120},[1056,1929,1123],{"class":1070},[1056,1931,1140],{"class":1066},[1056,1933,1436],{"class":1083},[1056,1935,1140],{"class":1066},[1056,1937,1160],{"class":1070},[1056,1939,1940],{"class":1058,"line":1090},[1056,1941,1445],{"class":1100},[946,1943,1944,1947],{},[962,1945,1946],{},"list()"," reads every persisted envelope in the vault (store-defined order):",[1047,1949,1951],{"className":1049,"code":1950,"language":1051,"meta":1052,"style":1052},"const all = await vault.user.list()\n\u002F\u002F → [\n\u002F\u002F     { keyringId: 'alice', data: { profile: { displayName: 'Alice' } }, _v: 1, _ts: '2026-05-05T10:00:00.000Z' },\n\u002F\u002F     { keyringId: 'bob',   data: { profile: { displayName: 'Bob' } },   _v: 1, _ts: '2026-05-05T10:05:00.000Z' },\n\u002F\u002F   ]\n",[962,1952,1953,1976,1981,1986,1991],{"__ignoreMap":1052},[1056,1954,1955,1957,1960,1962,1964,1966,1968,1970,1972,1974],{"class":1058,"line":1059},[1056,1956,1108],{"class":1107},[1056,1958,1959],{"class":1070}," all ",[1056,1961,1114],{"class":1066},[1056,1963,1117],{"class":1062},[1056,1965,1206],{"class":1070},[1056,1967,1178],{"class":1066},[1056,1969,1211],{"class":1070},[1056,1971,1178],{"class":1066},[1056,1973,1852],{"class":1120},[1056,1975,1363],{"class":1070},[1056,1977,1978],{"class":1058,"line":1090},[1056,1979,1980],{"class":1100},"\u002F\u002F → [\n",[1056,1982,1983],{"class":1058,"line":1097},[1056,1984,1985],{"class":1100},"\u002F\u002F     { keyringId: 'alice', data: { profile: { displayName: 'Alice' } }, _v: 1, _ts: '2026-05-05T10:00:00.000Z' },\n",[1056,1987,1988],{"class":1058,"line":1104},[1056,1989,1990],{"class":1100},"\u002F\u002F     { keyringId: 'bob',   data: { profile: { displayName: 'Bob' } },   _v: 1, _ts: '2026-05-05T10:05:00.000Z' },\n",[1056,1992,1993],{"class":1058,"line":1163},[1056,1994,1995],{"class":1100},"\u002F\u002F   ]\n",[946,1997,1998,2000],{},[962,1999,1946],{}," has a deliberate asymmetry on denial:",[2002,2003,2004,2017],"table",{},[2005,2006,2007],"thead",{},[2008,2009,2010,2014],"tr",{},[2011,2012,2013],"th",{},"Denial reason",[2011,2015,2016],{},"Behavior",[2018,2019,2020,2035,2049,2060],"tbody",{},[2008,2021,2022,2028],{},[2023,2024,2025],"td",{},[962,2026,2027],{},"disabled",[2023,2029,2030,2031,2034],{},"Silent self-fallback — returns ",[962,2032,2033],{},"[me]"," only.",[2008,2036,2037,2042],{},[2023,2038,2039],{},[962,2040,2041],{},"insufficient-tier",[2023,2043,2044,2045,2048],{},"Throws ",[962,2046,2047],{},"PolicyDeniedError"," (caller is expected to elevate)",[2008,2050,2051,2056],{},[2023,2052,2053],{},[962,2054,2055],{},"missing-factor",[2023,2057,2044,2058],{},[962,2059,2047],{},[2008,2061,2062,2067],{},[2023,2063,2064],{},[962,2065,2066],{},"stale-proof",[2023,2068,2044,2069],{},[962,2070,2047],{},[946,2072,2073,2074,2077,2078,2080,2081,2084,2085,1178],{},"The ",[962,2075,2076],{},"enabled: false"," path is the privacy-strict opt-out (\"nobody sees teammate profiles in this app\"); the others are authentication concerns. An ",[962,2079,2041],{}," denial here asks you to authenticate further up the ",[950,2082,2083],{"href":845},"session ladder"," — it is not the per-record elevation documented on ",[950,2086,872],{"href":873},[1320,2088,1009],{"id":2089},"reactive",[1047,2091,2093],{"className":1049,"code":2092,"language":1051,"meta":1052,"style":1052},"vault.user.subscribe\u003CT>(keyringId: string, cb: (env: UserEnvelope\u003CT> | null) => void): Unsubscribe\nvault.user.live\u003CT>(keyringId: string): LiveUserEnvelope\u003CT>\n",[962,2094,2095,2150],{"__ignoreMap":1052},[1056,2096,2097,2099,2101,2103,2105,2107,2109,2111,2113,2115,2117,2120,2122,2124,2126,2129,2131,2133,2135,2137,2140,2142,2144,2147],{"class":1058,"line":1059},[1056,2098,1628],{"class":1070},[1056,2100,1178],{"class":1066},[1056,2102,1211],{"class":1070},[1056,2104,1178],{"class":1066},[1056,2106,1485],{"class":1120},[1056,2108,1639],{"class":1066},[1056,2110,1643],{"class":1642},[1056,2112,1646],{"class":1066},[1056,2114,1813],{"class":1070},[1056,2116,1143],{"class":1066},[1056,2118,2119],{"class":1070}," cb: ",[1056,2121,1123],{"class":1066},[1056,2123,183],{"class":1501},[1056,2125,973],{"class":1066},[1056,2127,2128],{"class":1642}," UserEnvelope",[1056,2130,1639],{"class":1066},[1056,2132,1643],{"class":1642},[1056,2134,1646],{"class":1066},[1056,2136,1666],{"class":1066},[1056,2138,2139],{"class":1642}," null",[1056,2141,1504],{"class":1066},[1056,2143,1507],{"class":1107},[1056,2145,2146],{"class":1066}," void",[1056,2148,2149],{"class":1070},"): Unsubscribe\n",[1056,2151,2152,2154,2156,2158,2160,2162,2164,2166,2168,2171,2173,2175],{"class":1058,"line":1090},[1056,2153,1628],{"class":1070},[1056,2155,1178],{"class":1066},[1056,2157,1211],{"class":1070},[1056,2159,1178],{"class":1066},[1056,2161,727],{"class":1120},[1056,2163,1639],{"class":1066},[1056,2165,1643],{"class":1642},[1056,2167,1646],{"class":1066},[1056,2169,2170],{"class":1070},"(keyringId: string): LiveUserEnvelope",[1056,2172,1639],{"class":1066},[1056,2174,1643],{"class":1070},[1056,2176,1885],{"class":1066},[946,2178,2179,2180,2182,2183,2185,2186,2189,2190,2182,2193,2195],{},"Subscribers fire synchronously after every successful local ",[962,2181,1216],{},"\u002F",[962,2184,1734],{}," on the matching keyringId. Pass ",[962,2187,2188],{},"'*'"," to fire on every change. Cross-instance changes (a teammate edits their profile on their device, the sync engine pulls onto this device) flow through the team\u002Fsync engine and will fire subscribers when sync replays the write through the API. In v1, raw store-level changes do not fire subscribers — wire your sync layer to call back through ",[962,2191,2192],{},"vault.user.setMe",[962,2194,1216],{}," if you need that behavior.",[1320,2197,2199],{"id":2198},"lifecycle-hooks","Lifecycle hooks",[1047,2201,2203],{"className":1049,"code":2202,"language":1051,"meta":1052,"style":1052},"db.grant(vault, { ..., initialProfile?: T })\n",[962,2204,2205],{"__ignoreMap":1052},[1056,2206,2207,2210,2212,2215,2218,2220,2222,2225,2228,2230,2233,2235],{"class":1058,"line":1059},[1056,2208,2209],{"class":1070},"db",[1056,2211,1178],{"class":1066},[1056,2213,2214],{"class":1120},"grant",[1056,2216,2217],{"class":1070},"(vault",[1056,2219,1143],{"class":1066},[1056,2221,1067],{"class":1066},[1056,2223,2224],{"class":1066}," ...,",[1056,2226,2227],{"class":1070}," initialProfile?",[1056,2229,973],{"class":1066},[1056,2231,2232],{"class":1070}," T ",[1056,2234,1276],{"class":1066},[1056,2236,1160],{"class":1070},[946,2238,2239,2240,2243],{},"Admin pre-fill at grant time. Hub seeds the new principal's first envelope under the caller's ",[962,2241,2242],{},"_users"," DEK so the new user can decrypt it on first open. Once the user activates and writes their own envelope, the own-only write rule prevents further admin edits — bootstrap-only by construction.",[1047,2245,2247],{"className":1049,"code":2246,"language":1051,"meta":1052,"style":1052},"await db.grant('acme', {\n  userId: 'bob',\n  displayName: 'Bob',\n  role: 'operator',\n  secret: 'glasses cabinet bicycle umbrella thunder velvet',\n  permissions: { invoices: 'rw' },\n  initialProfile: { profile: { displayName: 'Bob' }, preferences: { theme: 'light' } },\n})\n\u002F\u002F → bob's `_users\u002Fbob` envelope exists, pre-filled, before bob ever opens the vault\n",[962,2248,2249,2272,2288,2304,2320,2336,2359,2408,2414],{"__ignoreMap":1052},[1056,2250,2251,2253,2255,2257,2259,2261,2263,2266,2268,2270],{"class":1058,"line":1059},[1056,2252,1203],{"class":1062},[1056,2254,1175],{"class":1070},[1056,2256,1178],{"class":1066},[1056,2258,2214],{"class":1120},[1056,2260,1123],{"class":1070},[1056,2262,1140],{"class":1066},[1056,2264,2265],{"class":1083},"acme",[1056,2267,1140],{"class":1066},[1056,2269,1143],{"class":1066},[1056,2271,1510],{"class":1066},[1056,2273,2274,2277,2279,2281,2283,2285],{"class":1058,"line":1090},[1056,2275,2276],{"class":1129},"  userId",[1056,2278,973],{"class":1066},[1056,2280,1080],{"class":1066},[1056,2282,1436],{"class":1083},[1056,2284,1140],{"class":1066},[1056,2286,2287],{"class":1066},",\n",[1056,2289,2290,2293,2295,2297,2300,2302],{"class":1058,"line":1097},[1056,2291,2292],{"class":1129},"  displayName",[1056,2294,973],{"class":1066},[1056,2296,1080],{"class":1066},[1056,2298,2299],{"class":1083},"Bob",[1056,2301,1140],{"class":1066},[1056,2303,2287],{"class":1066},[1056,2305,2306,2309,2311,2313,2316,2318],{"class":1058,"line":1104},[1056,2307,2308],{"class":1129},"  role",[1056,2310,973],{"class":1066},[1056,2312,1080],{"class":1066},[1056,2314,2315],{"class":1083},"operator",[1056,2317,1140],{"class":1066},[1056,2319,2287],{"class":1066},[1056,2321,2322,2325,2327,2329,2332,2334],{"class":1058,"line":1163},[1056,2323,2324],{"class":1129},"  secret",[1056,2326,973],{"class":1066},[1056,2328,1080],{"class":1066},[1056,2330,2331],{"class":1083},"glasses cabinet bicycle umbrella thunder velvet",[1056,2333,1140],{"class":1066},[1056,2335,2287],{"class":1066},[1056,2337,2338,2341,2343,2345,2348,2350,2352,2355,2357],{"class":1058,"line":1195},[1056,2339,2340],{"class":1129},"  permissions",[1056,2342,973],{"class":1066},[1056,2344,1067],{"class":1066},[1056,2346,2347],{"class":1129}," invoices",[1056,2349,973],{"class":1066},[1056,2351,1080],{"class":1066},[1056,2353,2354],{"class":1083},"rw",[1056,2356,1140],{"class":1066},[1056,2358,1246],{"class":1066},[1056,2360,2361,2364,2366,2368,2371,2373,2375,2377,2379,2381,2383,2385,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406],{"class":1058,"line":1200},[1056,2362,2363],{"class":1129},"  initialProfile",[1056,2365,973],{"class":1066},[1056,2367,1067],{"class":1066},[1056,2369,2370],{"class":1129}," profile",[1056,2372,973],{"class":1066},[1056,2374,1067],{"class":1066},[1056,2376,1234],{"class":1129},[1056,2378,973],{"class":1066},[1056,2380,1080],{"class":1066},[1056,2382,2299],{"class":1083},[1056,2384,1140],{"class":1066},[1056,2386,2387],{"class":1066}," },",[1056,2389,1573],{"class":1129},[1056,2391,973],{"class":1066},[1056,2393,1067],{"class":1066},[1056,2395,1259],{"class":1129},[1056,2397,973],{"class":1066},[1056,2399,1080],{"class":1066},[1056,2401,1586],{"class":1083},[1056,2403,1140],{"class":1066},[1056,2405,1074],{"class":1066},[1056,2407,1246],{"class":1066},[1056,2409,2410,2412],{"class":1058,"line":1224},[1056,2411,1276],{"class":1066},[1056,2413,1160],{"class":1070},[1056,2415,2416],{"class":1058,"line":1249},[1056,2417,2418],{"class":1100},"\u002F\u002F → bob's `_users\u002Fbob` envelope exists, pre-filled, before bob ever opens the vault\n",[1320,2420,2422],{"id":2421},"listuserswithenvelopesstore-vault-dek-callerrole",[962,2423,2424],{},"listUsersWithEnvelopes(store, vault, dek, callerRole)",[1047,2426,2428],{"className":1049,"code":2427,"language":1051,"meta":1052,"style":1052},"import { listUsersWithEnvelopes } from '@noy-db\u002Fhub'\n\nconst rows = await listUsersWithEnvelopes\u003CUserShape>(store, vault, dek, callerRole)\n\u002F\u002F rows: Array\u003C{ user: UserInfo; envelope: UserEnvelope\u003CUserShape> | null }>\n\u002F\u002F → [\n\u002F\u002F     { user: { userId: 'alice', displayName: 'Alice', role: 'owner', ... },\n\u002F\u002F       envelope: { keyringId: 'alice', data: { profile: { displayName: 'Alice' } }, _v: 1, _ts: '...' } },\n\u002F\u002F     { user: { userId: 'bob', displayName: 'Bob', role: 'operator', ... },\n\u002F\u002F       envelope: null },\n\u002F\u002F   ]\n",[962,2429,2430,2449,2453,2490,2495,2499,2504,2509,2514,2519],{"__ignoreMap":1052},[1056,2431,2432,2434,2436,2439,2441,2443,2445,2447],{"class":1058,"line":1059},[1056,2433,1063],{"class":1062},[1056,2435,1067],{"class":1066},[1056,2437,2438],{"class":1070}," listUsersWithEnvelopes",[1056,2440,1074],{"class":1066},[1056,2442,1077],{"class":1062},[1056,2444,1080],{"class":1066},[1056,2446,1084],{"class":1083},[1056,2448,1087],{"class":1066},[1056,2450,2451],{"class":1058,"line":1090},[1056,2452,1094],{"emptyLinePlaceholder":1093},[1056,2454,2455,2457,2460,2462,2464,2466,2468,2471,2473,2476,2478,2480,2482,2485,2487],{"class":1058,"line":1097},[1056,2456,1108],{"class":1107},[1056,2458,2459],{"class":1070}," rows ",[1056,2461,1114],{"class":1066},[1056,2463,1117],{"class":1062},[1056,2465,2438],{"class":1120},[1056,2467,1639],{"class":1066},[1056,2469,2470],{"class":1642},"UserShape",[1056,2472,1646],{"class":1066},[1056,2474,2475],{"class":1070},"(store",[1056,2477,1143],{"class":1066},[1056,2479,1206],{"class":1070},[1056,2481,1143],{"class":1066},[1056,2483,2484],{"class":1070}," dek",[1056,2486,1143],{"class":1066},[1056,2488,2489],{"class":1070}," callerRole)\n",[1056,2491,2492],{"class":1058,"line":1104},[1056,2493,2494],{"class":1100},"\u002F\u002F rows: Array\u003C{ user: UserInfo; envelope: UserEnvelope\u003CUserShape> | null }>\n",[1056,2496,2497],{"class":1058,"line":1163},[1056,2498,1980],{"class":1100},[1056,2500,2501],{"class":1058,"line":1195},[1056,2502,2503],{"class":1100},"\u002F\u002F     { user: { userId: 'alice', displayName: 'Alice', role: 'owner', ... },\n",[1056,2505,2506],{"class":1058,"line":1200},[1056,2507,2508],{"class":1100},"\u002F\u002F       envelope: { keyringId: 'alice', data: { profile: { displayName: 'Alice' } }, _v: 1, _ts: '...' } },\n",[1056,2510,2511],{"class":1058,"line":1224},[1056,2512,2513],{"class":1100},"\u002F\u002F     { user: { userId: 'bob', displayName: 'Bob', role: 'operator', ... },\n",[1056,2515,2516],{"class":1058,"line":1249},[1056,2517,2518],{"class":1100},"\u002F\u002F       envelope: null },\n",[1056,2520,2521],{"class":1058,"line":1273},[1056,2522,1995],{"class":1100},[946,2524,2525,2526,2182,2529,2531,2532,2182,2535,2537,2538,2541,2542,1178],{},"Convenience for admin UIs that want to render team-member lists with profile data in a single pass — ",[962,2527,2528],{},"store",[962,2530,1628],{}," are the same values passed to ",[962,2533,2534],{},"createNoydb",[962,2536,1181],{},", ",[962,2539,2540],{},"callerRole"," is the caller's own role, and it drives the directory-visibility rules below. Principals without a persisted envelope (legacy keyrings predating this feature) come back with ",[962,2543,2544],{},"envelope: null",[941,2546,2548],{"id":2547},"availability","Availability",[946,2550,2551,2553,2554,2556,2557,2559,2560,1178],{},[962,2552,1041],{}," is always present — there is no opt-in to skip. Vaults that never call ",[962,2555,972],{}," work identically to today; the ",[962,2558,2242],{}," collection is reserved on grant but envelopes are empty until first ",[962,2561,2562],{},"updateMe()",[941,2564,2566],{"id":2565},"storage-shape","Storage shape",[946,2568,2569,2570,2573],{},"Each principal has one envelope at the store key ",[962,2571,2572],{},"(_users, \u003CkeyringId>)",". The envelope uses the standard noy-db form:",[1047,2575,2578],{"className":2576,"code":2577,"language":141,"meta":1052,"style":1052},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{ \"_noydb\": 1, \"_v\": 7, \"_ts\": \"2026-05-05T10:00:00.000Z\", \"_iv\": \"\u003Cbase64>\", \"_data\": \"\u003Cbase64 ciphertext>\" }\n",[962,2579,2580],{"__ignoreMap":1052},[1056,2581,2582,2584,2587,2590,2593,2595,2599,2601,2603,2606,2608,2610,2613,2615,2617,2620,2622,2624,2626,2629,2631,2633,2635,2638,2640,2642,2644,2647,2649,2651,2653,2656,2658,2660,2662,2665,2667],{"class":1058,"line":1059},[1056,2583,1126],{"class":1066},[1056,2585,2586],{"class":1066}," \"",[1056,2588,2589],{"class":1107},"_noydb",[1056,2591,2592],{"class":1066},"\"",[1056,2594,973],{"class":1066},[1056,2596,2598],{"class":2597},"sbssI"," 1",[1056,2600,1143],{"class":1066},[1056,2602,2586],{"class":1066},[1056,2604,2605],{"class":1107},"_v",[1056,2607,2592],{"class":1066},[1056,2609,973],{"class":1066},[1056,2611,2612],{"class":2597}," 7",[1056,2614,1143],{"class":1066},[1056,2616,2586],{"class":1066},[1056,2618,2619],{"class":1107},"_ts",[1056,2621,2592],{"class":1066},[1056,2623,973],{"class":1066},[1056,2625,2586],{"class":1066},[1056,2627,2628],{"class":1083},"2026-05-05T10:00:00.000Z",[1056,2630,2592],{"class":1066},[1056,2632,1143],{"class":1066},[1056,2634,2586],{"class":1066},[1056,2636,2637],{"class":1107},"_iv",[1056,2639,2592],{"class":1066},[1056,2641,973],{"class":1066},[1056,2643,2586],{"class":1066},[1056,2645,2646],{"class":1083},"\u003Cbase64>",[1056,2648,2592],{"class":1066},[1056,2650,1143],{"class":1066},[1056,2652,2586],{"class":1066},[1056,2654,2655],{"class":1107},"_data",[1056,2657,2592],{"class":1066},[1056,2659,973],{"class":1066},[1056,2661,2586],{"class":1066},[1056,2663,2664],{"class":1083},"\u003Cbase64 ciphertext>",[1056,2666,2592],{"class":1066},[1056,2668,2669],{"class":1066}," }\n",[946,2671,2672,2674,2675,2677,2678,2681,2682,2685],{},[962,2673,2655],{}," decrypts (under the ",[962,2676,2242],{}," DEK) to an opaque JSON object. Hub does not reserve any keys inside the payload. The reference shape ",[962,2679,2680],{},"{ profile, preferences, app }"," lives in the ",[962,2683,2684],{},"recipe-user-preferences"," recipe as copy-paste material — apps adopt, modify, or replace it.",[946,2687,2073,2688,2690,2691,2694,2695,2698,2699,2702,2703,2706,2707,2709],{},[962,2689,2242],{}," DEK is ",[953,2692,2693],{},"eager-provisioned"," in ",[962,2696,2697],{},"createOwnerKeyring()"," for new vaults, and propagated to every granted keyring via the existing system-collection branch (",[962,2700,2701],{},"collName.startsWith('_')",") in ",[962,2704,2705],{},"team\u002Fkeyring.ts",". Pre-existing vaults (provisioned before this feature) get the DEK lazily on first ",[962,2708,972],{}," access — see \"Edge cases & limits\" below.",[941,2711,2713],{"id":2712},"permission-model","Permission model",[946,2715,2716],{},"Two new built-in policy gates, registered alongside the existing tier-2\u002Ftier-3 gates:",[2002,2718,2719,2735],{},[2005,2720,2721],{},[2008,2722,2723,2726,2729,2732],{},[2011,2724,2725],{},"Gate",[2011,2727,2728],{},"Default (PERSONAL)",[2011,2730,2731],{},"Default (STRICT)",[2011,2733,2734],{},"Purpose",[2018,2736,2737,2756],{},[2008,2738,2739,2743,2748,2753],{},[2023,2740,2741],{},[962,2742,1771],{},[2023,2744,2745],{},[962,2746,2747],{},"{ minTier: 3 }",[2023,2749,2750],{},[962,2751,2752],{},"{ minTier: 2, factors: [{ anyOf: ['totp', 'email-otp'] }] }",[2023,2754,2755],{},"Authorize a write to one's own envelope.",[2008,2757,2758,2762,2767,2771],{},[2023,2759,2760],{},[962,2761,999],{},[2023,2763,2764],{},[962,2765,2766],{},"{ minTier: 2 }",[2023,2768,2769],{},[962,2770,2766],{},[2023,2772,2773],{},"Authorize reading other principals' envelopes.",[946,2775,2776,2779],{},[953,2777,2778],{},"Structural rules"," (cannot be relaxed by policy):",[2781,2782,2783,2800],"ol",{},[978,2784,2785,2788,2789,2791,2792,2795,2796,2799],{},[962,2786,2787],{},"vault.user.updateMe"," \u002F ",[962,2790,1734],{}," always target ",[962,2793,2794],{},"writerKeyringId",". Runtime check throws ",[962,2797,2798],{},"PermissionDeniedError"," if the resolved target keyringId does not equal the writer's.",[978,2801,2802],{},"The API exposes no method that accepts a target keyringId for writes. There is no path by which an admin or owner can write a teammate's envelope.",[946,2804,2805],{},[953,2806,2807],{},"Tightening (allowed):",[975,2809,2810,2816],{},[978,2811,2812,2813,2815],{},"A strict app sets ",[962,2814,1771],{}," to require a fresh TOTP for any profile change.",[978,2817,2818,2819,2822,2823,2825,2826,2829,2830,1178],{},"A privacy-strict app sets ",[962,2820,2821],{},"view-team-profiles.enabled: false"," → ",[962,2824,1946],{}," returns only self; ",[962,2827,2828],{},"get(other)"," throws ",[962,2831,2047],{},[946,2833,2834],{},[953,2835,2836],{},"Relaxing (disallowed):",[975,2838,2839],{},[978,2840,2841,2842,2844],{},"Setting ",[962,2843,1771],{}," to permit cross-principal writes is impossible. Policy controls authentication, not authorization. The own-only rule is structural.",[941,2846,2848],{"id":2847},"lifecycle","Lifecycle",[975,2850,2851,2871,2892,2898,2911],{},[978,2852,2853,2856,2857,2860,2861,2863,2864,2867,2868,1004],{},[953,2854,2855],{},"Created on grant."," When ",[962,2858,2859],{},"team\u002Fgrant.ts"," provisions a new keyring, it also creates a ",[962,2862,964],{}," envelope, seeded with ",[962,2865,2866],{},"initialProfile?: T"," if present, else empty (",[962,2869,2870],{},"{}",[978,2872,2873,2876,2877,2880,2881,2884,2885,2888,2889,2034],{},[953,2874,2875],{},"Magic-link grants."," The existing ",[962,2878,2879],{},"team\u002Fmagic-link-grant.ts"," is for ",[953,2882,2883],{},"tier delegation"," (auditor gets 48h access to a collection), not user creation; it does not produce a persistent keyring. Bootstrap ",[962,2886,2887],{},"initialProfile"," flows through ",[962,2890,2891],{},"db.grant()",[978,2893,2894,2897],{},[953,2895,2896],{},"Deleted on revoke."," Cascade-revoke removes the envelope alongside the keyring file. Idempotent: no error if the envelope is already absent.",[978,2899,2900,2903,2904,2907,2908,2910],{},[953,2901,2902],{},"Rotated on tier-1 rotation."," The DEK rotation path re-encrypts every ",[962,2905,2906],{},"_users\u002F*"," envelope under the fresh DEK — the user-envelope feature inherits this for free since ",[962,2909,2242],{}," is in the affected collections set.",[978,2912,2913,2916],{},[953,2914,2915],{},"Untouched on tier-2 add\u002Fremove."," Authenticator slot changes do not touch the envelope.",[941,2918,2920],{"id":2919},"pairs-well-with","Pairs well with",[975,2922,2923,2932,2943,2952],{},[978,2924,2925,2927,2928,2931],{},[962,2926,868],{}," — joined ",[962,2929,2930],{},"listUsersWithEnvelopes()"," for admin UIs; cascade-revoke deletes envelopes alongside keyrings.",[978,2933,2934,2936,2937,2939,2940,2942],{},[962,2935,872],{}," — the ",[962,2938,1771],{}," and ",[962,2941,999],{}," gates plug into the same policy-gate DSL as every other built-in gate.",[978,2944,2945,2947,2948,2951],{},[962,2946,864],{}," — own-write changes propagate to teammates' clients on the next sync round-trip; ",[962,2949,2950],{},"subscribe()"," fires when the sync layer replays the write through the API.",[978,2953,2954,2956,2957,2960,2961,2964],{},[962,2955,701],{}," — apps storing ",[962,2958,2959],{},"profile.locale"," use it to drive ",[962,2962,2963],{},"vault.t()"," resolution.",[941,2966,2968],{"id":2967},"edge-cases-limits","Edge cases & limits",[975,2970,2971,2984,3009,3015,3025],{},[978,2972,2973,2976,2977,2980,2981,1004],{},[953,2974,2975],{},"Soft size cap: 64 KiB per envelope."," Larger payloads throw ",[962,2978,2979],{},"UserEnvelopeOversizedError",". UTF-8 byte-aware (multi-byte characters are counted via TextEncoder, not ",[962,2982,2983],{},"String.length",[978,2985,2986,2989,2990,2992,2993,2995,2996,2999,3000,3003,3004,3006,3007,1178],{},[953,2987,2988],{},"Pre-existing vaults — single-principal lazy DEK."," Vaults provisioned before this feature do not have a ",[962,2991,2242],{}," DEK in any keyring. The first call to ",[962,2994,972],{}," lazily creates the DEK in ",[1895,2997,2998],{},"that user's"," keyring only. Other principals on a different machine that open the vault later will then create their own (different) DEK — and cross-principal reads will fail until the vault rotates the keys. Workaround: call ",[962,3001,3002],{},"db.rotate(vault, ['_users'])"," after the first user calls ",[962,3005,972],{}," to propagate the DEK to all keyrings. New vaults (post-feature) avoid this entirely via eager provisioning in ",[962,3008,2697],{},[978,3010,3011,3014],{},[953,3012,3013],{},"Subscribe \u002F live in v1 fire only on local writes."," Cross-instance changes flow via team\u002Fsync; subscribers there see the change when sync replays through the API. Wiring raw store-level changes into subscribers is a follow-up.",[978,3016,3017,3020,3021,3024],{},[953,3018,3019],{},"No managed-mode identity-provider integration yet."," A future ",[962,3022,3023],{},"UserProfileProvider"," interface for syncing profile data from an external IdP is planned but not implemented — there is no such export, constructor option, or runtime hook in the current API.",[978,3026,3027,3036,3037,3040],{},[953,3028,3029,3032,3033,3035],{},[962,3030,3031],{},"listUsersWithEnvelopes"," requires the ",[962,3034,2242],{}," DEK, which has no public accessor yet."," The function's ",[962,3038,3039],{},"dek"," parameter must currently be sourced from vault internals; there is no supported public method that returns it. Until one ships, the joined enumeration is reachable from code with direct access to those internals (e.g. within the hub itself), not from ordinary app code.",[941,3042,3044],{"id":3043},"directory-visibility","Directory visibility",[946,3046,3047,3048,973],{},"Two complementary opt-outs on top of ",[962,3049,3031],{},[975,3051,3052,3150],{},[978,3053,3054,3059,3060,3063,3064,2182,3067,3070,3071,3074,3075,3080,3081,3084,3085],{},[953,3055,3056],{},[962,3057,3058],{},"vault.user.setMyVisibility({ hidden: true })"," — per-user opt-out.\nPersisted as a plaintext sidecar at ",[962,3061,3062],{},"_meta\u002Fvisibility\u002F\u003CkeyringId>",".\nHidden users are filtered out of the default listing; ",[962,3065,3066],{},"owner",[962,3068,3069],{},"admin","\ncallers can pass ",[962,3072,3073],{},"{ includeHidden: true }"," to see them. Own-only by\nconstruction (no method to hide another principal). Read it back with\n",[953,3076,3077],{},[962,3078,3079],{},"vault.user.getMyVisibility()",", which returns ",[962,3082,3083],{},"{ hidden: false }","\nwhen nothing has been persisted yet.",[1047,3086,3088],{"className":1049,"code":3087,"language":1051,"meta":1052,"style":1052},"await vault.user.setMyVisibility({ hidden: true })\nconst mine = await vault.user.getMyVisibility()\n\u002F\u002F → { hidden: true }\n",[962,3089,3090,3122,3145],{"__ignoreMap":1052},[1056,3091,3092,3094,3096,3098,3100,3102,3105,3107,3109,3112,3114,3118,3120],{"class":1058,"line":1059},[1056,3093,1203],{"class":1062},[1056,3095,1206],{"class":1070},[1056,3097,1178],{"class":1066},[1056,3099,1211],{"class":1070},[1056,3101,1178],{"class":1066},[1056,3103,3104],{"class":1120},"setMyVisibility",[1056,3106,1123],{"class":1070},[1056,3108,1126],{"class":1066},[1056,3110,3111],{"class":1129}," hidden",[1056,3113,973],{"class":1066},[1056,3115,3117],{"class":3116},"sfNiH"," true",[1056,3119,1074],{"class":1066},[1056,3121,1160],{"class":1070},[1056,3123,3124,3126,3128,3130,3132,3134,3136,3138,3140,3143],{"class":1058,"line":1090},[1056,3125,1108],{"class":1107},[1056,3127,1345],{"class":1070},[1056,3129,1114],{"class":1066},[1056,3131,1117],{"class":1062},[1056,3133,1206],{"class":1070},[1056,3135,1178],{"class":1066},[1056,3137,1211],{"class":1070},[1056,3139,1178],{"class":1066},[1056,3141,3142],{"class":1120},"getMyVisibility",[1056,3144,1363],{"class":1070},[1056,3146,3147],{"class":1058,"line":1097},[1056,3148,3149],{"class":1100},"\u002F\u002F → { hidden: true }\n",[978,3151,3152,3157,3158,3161,3162,2829,3164,3167,3168,3170,3171,1178,3173],{},[953,3153,3154],{},[962,3155,3156],{},"db.setDirectoryEnabled(vault, false)"," — vault-level toggle.\nOwner-only. Persisted at ",[962,3159,3160],{},"_meta\u002Fdirectory",". When disabled,\n",[962,3163,3031],{},[962,3165,3166],{},"DirectoryDisabledError"," for any\ncaller whose role is neither ",[962,3169,3066],{}," nor ",[962,3172,3069],{},[1047,3174,3176],{"className":1049,"code":3175,"language":1051,"meta":1052,"style":1052},"await db.setDirectoryEnabled('acme', false)\n\u002F\u002F → any admin\u002Fnon-owner call to listUsersWithEnvelopes now throws DirectoryDisabledError\n",[962,3177,3178,3204],{"__ignoreMap":1052},[1056,3179,3180,3182,3184,3186,3189,3191,3193,3195,3197,3199,3202],{"class":1058,"line":1059},[1056,3181,1203],{"class":1062},[1056,3183,1175],{"class":1070},[1056,3185,1178],{"class":1066},[1056,3187,3188],{"class":1120},"setDirectoryEnabled",[1056,3190,1123],{"class":1070},[1056,3192,1140],{"class":1066},[1056,3194,2265],{"class":1083},[1056,3196,1140],{"class":1066},[1056,3198,1143],{"class":1066},[1056,3200,3201],{"class":3116}," false",[1056,3203,1160],{"class":1070},[1056,3205,3206],{"class":1058,"line":1090},[1056,3207,3208],{"class":1100},"\u002F\u002F → any admin\u002Fnon-owner call to listUsersWithEnvelopes now throws DirectoryDisabledError\n",[946,3210,3211,3212,3215,3216,3219,3220,3222,3223,3226,3227,1178],{},"Both flags live in ",[962,3213,3214],{},"_meta"," rather than inside the encrypted\n",[962,3217,3218],{},"UserEnvelope\u003CT>.data"," payload — ",[962,3221,1530],{}," is opaque-to-hub by contract,\nand the directory filter must work even when an envelope decryption\nfails (legacy keyrings predating the envelope feature, or a corrupted\nenvelope). Storing them as plaintext sidecars matches the\n",[962,3224,3225],{},"_meta\u002Fpolicy"," pattern documented in\n",[950,3228,3230],{"href":3229},".\u002Fplaintext-bypass",[962,3231,3232],{},"plaintext-bypass.md",[946,3234,3235,3238,3239,3242,3243,3245],{},[953,3236,3237],{},"Honest caveat — this is a UX flag, not a privacy guarantee."," The\nkeyring file at ",[962,3240,3241],{},"_keyring\u002F\u003CuserId>"," is still listed (an attacker with\ndirect store read access can count keyrings and read role +\npermissions metadata). The envelope ciphertext at\n",[962,3244,964],{}," is still present in the store. The visibility +\ndirectory flags only gate the hub-level enumeration helper — they\nprevent admin-UIs from accidentally rendering a hidden user, not a\ndetermined adversary from learning who has access. Apps that need\nreal principal anonymity should use a dedicated identity store\nexternal to the vault.",[946,3247,3248,3249,3252],{},"Peer-recovery preserves both flags: ",[962,3250,3251],{},"db.recoverUser"," only rewrites the\nkeyring file, so the user's visibility doc and the vault's directory\ndoc both survive the rotation.",[941,3254,3256],{"id":3255},"see-also","See also",[975,3258,3259,3270,3280,3286,3292],{},[978,3260,3261,3269],{},[950,3262,3266],{"href":3263,"rel":3264},"https:\u002F\u002Fgithub.com\u002Fnoy-db\u002Fdocs\u002Fblob\u002Fmain\u002Fshowcases\u002Fsrc\u002F70-user-envelope.showcase.test.ts",[3265],"nofollow",[962,3267,3268],{},"70-user-envelope.showcase.test.ts"," — Hub API end-to-end",[978,3271,3272,3279],{},[950,3273,3276],{"href":3274,"rel":3275},"https:\u002F\u002Fgithub.com\u002Fnoy-db\u002Fdocs\u002Fblob\u002Fmain\u002Fshowcases\u002Fsrc\u002Frecipe-user-preferences.recipe.test.ts",[3265],[962,3277,3278],{},"recipe-user-preferences.recipe.test.ts"," — reference shape pattern + device-local pattern",[978,3281,3282,3285],{},[962,3283,3284],{},"docs\u002Fservices\u002Fsession-tiers.md"," — policy gate DSL the new gates plug into",[978,3287,3288,3291],{},[962,3289,3290],{},"docs\u002Fservices\u002Fteam.md"," — multi-user grant\u002Frevoke flows the lifecycle binds to",[978,3293,3294,983,3297,2939,3299,3301],{},[962,3295,3296],{},"docs\u002Fservices\u002Fplaintext-bypass.md",[962,3298,3160],{},[962,3300,3062],{}," are documented bypasses",[3303,3304,3305],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":1052,"searchDepth":1097,"depth":1097,"links":3307},[3308,3309,3310,3311,3316,3323,3324,3325,3326,3327,3328,3329,3330],{"id":943,"depth":1090,"text":944},{"id":1016,"depth":1090,"text":1017},{"id":1034,"depth":1090,"text":1035},{"id":1317,"depth":1090,"text":1318,"children":3312},[3313,3314,3315],{"id":1322,"depth":1097,"text":1323},{"id":1390,"depth":1097,"text":1391},{"id":1453,"depth":1097,"text":1454},{"id":1613,"depth":1090,"text":1614,"children":3317},[3318,3319,3320,3321,3322],{"id":1617,"depth":1097,"text":1618},{"id":1787,"depth":1097,"text":992},{"id":2089,"depth":1097,"text":1009},{"id":2198,"depth":1097,"text":2199},{"id":2421,"depth":1097,"text":2424},{"id":2547,"depth":1090,"text":2548},{"id":2565,"depth":1090,"text":2566},{"id":2712,"depth":1090,"text":2713},{"id":2847,"depth":1090,"text":2848},{"id":2919,"depth":1090,"text":2920},{"id":2967,"depth":1090,"text":2968},{"id":3043,"depth":1090,"text":3044},{"id":3255,"depth":1090,"text":3256},null,"Per-principal profile storage: every keyring gets a small encrypted JSON object at `_users\u002F\u003CkeyringId>` for its own display name, theme, and preferences.","md",{},"service",{"title":884,"description":3332},"stable","important","XD28HhnTtYzpbHA12mdsE9KBuINChoFlzHmpiomBh8E",{"data":3341,"body":3342},{},{"type":3343,"children":3344},"root",[3345],{"type":3346,"tag":946,"props":3347,"children":3348},"element",{},[3349,3355],{"type":3346,"tag":962,"props":3350,"children":3352},{"className":3351},[],[3353],{"type":3354,"value":1084},"text",{"type":3354,"value":3356}," (root export)",{"data":3358,"body":3359},{},{"type":3343,"children":3360},[3361],{"type":3346,"tag":946,"props":3362,"children":3363},{},[3364,3366,3371],{"type":3354,"value":3365},"Core feature — exposed as ",{"type":3346,"tag":962,"props":3367,"children":3369},{"className":3368},[],[3370],{"type":3354,"value":972},{"type":3354,"value":3372},", always available.",1791896582091]