[{"data":1,"prerenderedAt":5488},["ShallowReactive",2],{"navigation":3,"\u002Fservices\u002Fguards":927,"mdc-rvbvp8-key":5430,"mdc--bzyyyo-key":5444,"mdc--u5mbys-key":5457,"mdc--r89yej-key":5470,"mdc-m99vsy-key":5479},[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":693,"access":12,"apiToc":929,"body":930,"category":5421,"description":5422,"extension":5423,"meta":5424,"navigation":5421,"nest":5425,"path":694,"seo":5426,"sinceVersion":5421,"status":5427,"stem":695,"subtitle":5421,"tier":5428,"tocExternal":5421,"__hash__":5429},"docs\u002Fservices\u002Fguards.md",false,{"type":931,"value":932,"toc":5389},"minimark",[933,936,940,945,974,988,992,1016,1020,1057,1061,1789,1793,1798,1816,1925,1929,1949,2264,2268,2297,2510,2522,2526,2529,2626,2648,2654,2660,2704,2708,2720,3163,3180,3189,3219,3563,3569,3575,3591,3993,4065,4069,4077,4081,4096,4102,4106,4115,4153,4157,4201,4205,4231,4235,4329,4333,4347,4353,4453,4500,4980,4990,4994,5278,5285,5289,5342,5346,5385],[934,935,693],"h1",{"id":693},[937,938],"service-meta",{":rows":939},"[{\"label\":\"Subpath\",\"value\":\"`@noy-db\u002Fhub\u002Fguards`\"},{\"label\":\"Factory\",\"value\":\"`withGuard()`\"},{\"label\":\"Layer\",\"value\":\"`with-audit`\"},{\"label\":\"Cluster\",\"value\":\"E — Time & Audit\"},{\"label\":\"LOC cost\",\"value\":\"~700 (off-bundle when not opted in)\"}]",[941,942,944],"h2",{"id":943},"what-it-does","What it does",[946,947,948,951,952,956,957,960,961,964,965,969,970,973],"p",{},[949,950,693],"code",{}," lets you say \"this record can't be written (or deleted) unless a\nbusiness rule allows it\" — a per-record ",[953,954,955],"strong",{},"lock",", a per-field ",[953,958,959],{},"freeze",", and\na controlled ",[953,962,963],{},"amendment"," path for the rare case where a locked record must\nlegitimately change. It's the layer above a single permission bit: permissions\nsay ",[966,967,968],"em",{},"who"," can write a collection, guards say ",[966,971,972],{},"whether this specific write is\nallowed right now",".",[946,975,976,977,982,983,987],{},"A guard's callbacks run on the decrypted record — after the\n",[978,979,981],"a",{"href":980},"..\u002Fcore\u002Fnoydb\u002Fenclave","per-collection encryption key"," is unwrapped, before\nthe plaintext is re-encrypted for storage, and before any\n",[978,984,986],{"href":985},".\u002Fperiods","period close"," is checked — the storage backend never sees\nplaintext either way.",[941,989,991],{"id":990},"when-you-need-it","When you need it",[993,994,995,999,1010,1013],"ul",{},[996,997,998],"li",{},"Accounting \u002F financial books where issued invoices must not change",[996,1000,1001,1002,1005,1006,1009],{},"Workflows that freeze specific fields after a status transition (e.g.\n",[949,1003,1004],{},"amount"," immutable once ",[949,1007,1008],{},"status === 'paid'",")",[996,1011,1012],{},"Audit-tracked corrections that must preserve an invariant (totals,\nbalanced double-entry pairs)",[996,1014,1015],{},"Any domain where a single permission bit (\"can write\") is too coarse",[941,1017,1019],{"id":1018},"prerequisites","Prerequisites",[993,1021,1022,1032],{},[996,1023,1024,1027,1028,1031],{},[953,1025,1026],{},"Guard declarations per collection"," (",[949,1029,1030],{},"guardStrategies",") — the factory enables enforcement; each collection declares its own rules.",[996,1033,1034,1037,1038,1041,1042,1045,1046,1049,1050,1037,1053,1056],{},[966,1035,1036],{},"For amendment mode:"," ",[949,1039,1040],{},"transactionsStrategy: withTransactions()"," is required, plus ",[949,1043,1044],{},"admin",", ",[949,1047,1048],{},"owner",", or ",[949,1051,1052],{},"custodian",[978,1054,1055],{"href":54},"role"," on every vault the amendment touches.",[941,1058,1060],{"id":1059},"opt-in","Opt in",[1062,1063,1068],"pre",{"className":1064,"code":1065,"language":1066,"meta":1067,"style":1067},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createNoydb } from '@noy-db\u002Fhub'\nimport { toMemory } from '@noy-db\u002Fto-memory'\nimport { withGuard, RecordLockedError, InvariantError } from '@noy-db\u002Fhub\u002Fguards'\nimport { withTransactions } from '@noy-db\u002Fhub\u002Ftransactions'\n\nconst disbursementGuard = withGuard\u003CDisbursement>({\n  collection: 'disbursements',\n  check: async (incoming, { vault }) => {\n    const inv = await vault.collection\u003CInvoice>('invoices').get(incoming.invoiceId)\n    if (inv?.status === 'issued') {\n      throw new RecordLockedError('disbursements', incoming.id, 'invoice is issued')\n    }\n  },\n  amendment: {\n    roles: ['admin', 'owner'],\n    invariant: (changes) => {\n      const sum = (s: 'before' | 'after') =>\n        changes.reduce((t, c) => t + ((c[s])?.amount ?? 0), 0)\n      if (sum('before') !== sum('after')) {\n        throw new InvariantError('total must be preserved')\n      }\n    },\n  },\n})\n\nconst db = await createNoydb({\n  store: toMemory(),\n  user: 'alice',\n  guardStrategies: [disbursementGuard],\n  transactionsStrategy: withTransactions(), \u002F\u002F required for amendment mode\n})\n\nconst vault = await db.openVault('books')\n","ts","",[949,1069,1070,1103,1124,1156,1177,1184,1216,1237,1270,1327,1359,1399,1405,1411,1421,1451,1470,1510,1575,1614,1635,1641,1647,1652,1660,1665,1683,1698,1715,1728,1746,1753,1758],{"__ignoreMap":1067},[1071,1072,1075,1079,1083,1087,1090,1093,1096,1100],"span",{"class":1073,"line":1074},"line",1,[1071,1076,1078],{"class":1077},"s7zQu","import",[1071,1080,1082],{"class":1081},"sMK4o"," {",[1071,1084,1086],{"class":1085},"sTEyZ"," createNoydb",[1071,1088,1089],{"class":1081}," }",[1071,1091,1092],{"class":1077}," from",[1071,1094,1095],{"class":1081}," '",[1071,1097,1099],{"class":1098},"sfazB","@noy-db\u002Fhub",[1071,1101,1102],{"class":1081},"'\n",[1071,1104,1106,1108,1110,1113,1115,1117,1119,1122],{"class":1073,"line":1105},2,[1071,1107,1078],{"class":1077},[1071,1109,1082],{"class":1081},[1071,1111,1112],{"class":1085}," toMemory",[1071,1114,1089],{"class":1081},[1071,1116,1092],{"class":1077},[1071,1118,1095],{"class":1081},[1071,1120,1121],{"class":1098},"@noy-db\u002Fto-memory",[1071,1123,1102],{"class":1081},[1071,1125,1127,1129,1131,1134,1137,1140,1142,1145,1147,1149,1151,1154],{"class":1073,"line":1126},3,[1071,1128,1078],{"class":1077},[1071,1130,1082],{"class":1081},[1071,1132,1133],{"class":1085}," withGuard",[1071,1135,1136],{"class":1081},",",[1071,1138,1139],{"class":1085}," RecordLockedError",[1071,1141,1136],{"class":1081},[1071,1143,1144],{"class":1085}," InvariantError",[1071,1146,1089],{"class":1081},[1071,1148,1092],{"class":1077},[1071,1150,1095],{"class":1081},[1071,1152,1153],{"class":1098},"@noy-db\u002Fhub\u002Fguards",[1071,1155,1102],{"class":1081},[1071,1157,1159,1161,1163,1166,1168,1170,1172,1175],{"class":1073,"line":1158},4,[1071,1160,1078],{"class":1077},[1071,1162,1082],{"class":1081},[1071,1164,1165],{"class":1085}," withTransactions",[1071,1167,1089],{"class":1081},[1071,1169,1092],{"class":1077},[1071,1171,1095],{"class":1081},[1071,1173,1174],{"class":1098},"@noy-db\u002Fhub\u002Ftransactions",[1071,1176,1102],{"class":1081},[1071,1178,1180],{"class":1073,"line":1179},5,[1071,1181,1183],{"emptyLinePlaceholder":1182},true,"\n",[1071,1185,1187,1191,1194,1197,1200,1203,1207,1210,1213],{"class":1073,"line":1186},6,[1071,1188,1190],{"class":1189},"spNyl","const",[1071,1192,1193],{"class":1085}," disbursementGuard ",[1071,1195,1196],{"class":1081},"=",[1071,1198,1133],{"class":1199},"s2Zo4",[1071,1201,1202],{"class":1081},"\u003C",[1071,1204,1206],{"class":1205},"sBMFI","Disbursement",[1071,1208,1209],{"class":1081},">",[1071,1211,1212],{"class":1085},"(",[1071,1214,1215],{"class":1081},"{\n",[1071,1217,1219,1223,1226,1228,1231,1234],{"class":1073,"line":1218},7,[1071,1220,1222],{"class":1221},"swJcz","  collection",[1071,1224,1225],{"class":1081},":",[1071,1227,1095],{"class":1081},[1071,1229,1230],{"class":1098},"disbursements",[1071,1232,1233],{"class":1081},"'",[1071,1235,1236],{"class":1081},",\n",[1071,1238,1240,1243,1245,1248,1250,1254,1256,1258,1261,1264,1267],{"class":1073,"line":1239},8,[1071,1241,1242],{"class":1199},"  check",[1071,1244,1225],{"class":1081},[1071,1246,1247],{"class":1189}," async",[1071,1249,1027],{"class":1081},[1071,1251,1253],{"class":1252},"sHdIc","incoming",[1071,1255,1136],{"class":1081},[1071,1257,1082],{"class":1081},[1071,1259,1260],{"class":1252}," vault",[1071,1262,1263],{"class":1081}," })",[1071,1265,1266],{"class":1189}," =>",[1071,1268,1269],{"class":1081}," {\n",[1071,1271,1273,1276,1279,1282,1285,1287,1289,1292,1294,1297,1299,1301,1303,1306,1308,1310,1312,1315,1317,1319,1321,1324],{"class":1073,"line":1272},9,[1071,1274,1275],{"class":1189},"    const",[1071,1277,1278],{"class":1085}," inv",[1071,1280,1281],{"class":1081}," =",[1071,1283,1284],{"class":1077}," await",[1071,1286,1260],{"class":1085},[1071,1288,973],{"class":1081},[1071,1290,1291],{"class":1199},"collection",[1071,1293,1202],{"class":1081},[1071,1295,1296],{"class":1205},"Invoice",[1071,1298,1209],{"class":1081},[1071,1300,1212],{"class":1221},[1071,1302,1233],{"class":1081},[1071,1304,1305],{"class":1098},"invoices",[1071,1307,1233],{"class":1081},[1071,1309,1009],{"class":1221},[1071,1311,973],{"class":1081},[1071,1313,1314],{"class":1199},"get",[1071,1316,1212],{"class":1221},[1071,1318,1253],{"class":1085},[1071,1320,973],{"class":1081},[1071,1322,1323],{"class":1085},"invoiceId",[1071,1325,1326],{"class":1221},")\n",[1071,1328,1330,1333,1335,1338,1341,1344,1347,1349,1352,1354,1357],{"class":1073,"line":1329},10,[1071,1331,1332],{"class":1077},"    if",[1071,1334,1027],{"class":1221},[1071,1336,1337],{"class":1085},"inv",[1071,1339,1340],{"class":1081},"?.",[1071,1342,1343],{"class":1085},"status",[1071,1345,1346],{"class":1081}," ===",[1071,1348,1095],{"class":1081},[1071,1350,1351],{"class":1098},"issued",[1071,1353,1233],{"class":1081},[1071,1355,1356],{"class":1221},") ",[1071,1358,1215],{"class":1081},[1071,1360,1362,1365,1368,1370,1372,1374,1376,1378,1380,1383,1385,1388,1390,1392,1395,1397],{"class":1073,"line":1361},11,[1071,1363,1364],{"class":1077},"      throw",[1071,1366,1367],{"class":1081}," new",[1071,1369,1139],{"class":1199},[1071,1371,1212],{"class":1221},[1071,1373,1233],{"class":1081},[1071,1375,1230],{"class":1098},[1071,1377,1233],{"class":1081},[1071,1379,1136],{"class":1081},[1071,1381,1382],{"class":1085}," incoming",[1071,1384,973],{"class":1081},[1071,1386,1387],{"class":1085},"id",[1071,1389,1136],{"class":1081},[1071,1391,1095],{"class":1081},[1071,1393,1394],{"class":1098},"invoice is issued",[1071,1396,1233],{"class":1081},[1071,1398,1326],{"class":1221},[1071,1400,1402],{"class":1073,"line":1401},12,[1071,1403,1404],{"class":1081},"    }\n",[1071,1406,1408],{"class":1073,"line":1407},13,[1071,1409,1410],{"class":1081},"  },\n",[1071,1412,1414,1417,1419],{"class":1073,"line":1413},14,[1071,1415,1416],{"class":1221},"  amendment",[1071,1418,1225],{"class":1081},[1071,1420,1269],{"class":1081},[1071,1422,1424,1427,1429,1432,1434,1436,1438,1440,1442,1444,1446,1449],{"class":1073,"line":1423},15,[1071,1425,1426],{"class":1221},"    roles",[1071,1428,1225],{"class":1081},[1071,1430,1431],{"class":1085}," [",[1071,1433,1233],{"class":1081},[1071,1435,1044],{"class":1098},[1071,1437,1233],{"class":1081},[1071,1439,1136],{"class":1081},[1071,1441,1095],{"class":1081},[1071,1443,1048],{"class":1098},[1071,1445,1233],{"class":1081},[1071,1447,1448],{"class":1085},"]",[1071,1450,1236],{"class":1081},[1071,1452,1454,1457,1459,1461,1464,1466,1468],{"class":1073,"line":1453},16,[1071,1455,1456],{"class":1199},"    invariant",[1071,1458,1225],{"class":1081},[1071,1460,1027],{"class":1081},[1071,1462,1463],{"class":1252},"changes",[1071,1465,1009],{"class":1081},[1071,1467,1266],{"class":1189},[1071,1469,1269],{"class":1081},[1071,1471,1473,1476,1479,1481,1483,1486,1488,1490,1493,1495,1498,1500,1503,1505,1507],{"class":1073,"line":1472},17,[1071,1474,1475],{"class":1189},"      const",[1071,1477,1478],{"class":1085}," sum",[1071,1480,1281],{"class":1081},[1071,1482,1027],{"class":1081},[1071,1484,1485],{"class":1252},"s",[1071,1487,1225],{"class":1081},[1071,1489,1095],{"class":1081},[1071,1491,1492],{"class":1098},"before",[1071,1494,1233],{"class":1081},[1071,1496,1497],{"class":1081}," |",[1071,1499,1095],{"class":1081},[1071,1501,1502],{"class":1098},"after",[1071,1504,1233],{"class":1081},[1071,1506,1009],{"class":1081},[1071,1508,1509],{"class":1189}," =>\n",[1071,1511,1513,1516,1518,1520,1522,1524,1527,1529,1532,1534,1536,1539,1542,1545,1548,1551,1553,1556,1558,1560,1563,1567,1569,1571,1573],{"class":1073,"line":1512},18,[1071,1514,1515],{"class":1085},"        changes",[1071,1517,973],{"class":1081},[1071,1519,804],{"class":1199},[1071,1521,1212],{"class":1221},[1071,1523,1212],{"class":1081},[1071,1525,1526],{"class":1252},"t",[1071,1528,1136],{"class":1081},[1071,1530,1531],{"class":1252}," c",[1071,1533,1009],{"class":1081},[1071,1535,1266],{"class":1189},[1071,1537,1538],{"class":1085}," t",[1071,1540,1541],{"class":1081}," +",[1071,1543,1544],{"class":1221}," ((",[1071,1546,1547],{"class":1085},"c",[1071,1549,1550],{"class":1221},"[",[1071,1552,1485],{"class":1085},[1071,1554,1555],{"class":1221},"])",[1071,1557,1340],{"class":1081},[1071,1559,1004],{"class":1085},[1071,1561,1562],{"class":1081}," ??",[1071,1564,1566],{"class":1565},"sbssI"," 0",[1071,1568,1009],{"class":1221},[1071,1570,1136],{"class":1081},[1071,1572,1566],{"class":1565},[1071,1574,1326],{"class":1221},[1071,1576,1578,1581,1583,1586,1588,1590,1592,1594,1596,1599,1601,1603,1605,1607,1609,1612],{"class":1073,"line":1577},19,[1071,1579,1580],{"class":1077},"      if",[1071,1582,1027],{"class":1221},[1071,1584,1585],{"class":1199},"sum",[1071,1587,1212],{"class":1221},[1071,1589,1233],{"class":1081},[1071,1591,1492],{"class":1098},[1071,1593,1233],{"class":1081},[1071,1595,1356],{"class":1221},[1071,1597,1598],{"class":1081},"!==",[1071,1600,1478],{"class":1199},[1071,1602,1212],{"class":1221},[1071,1604,1233],{"class":1081},[1071,1606,1502],{"class":1098},[1071,1608,1233],{"class":1081},[1071,1610,1611],{"class":1221},")) ",[1071,1613,1215],{"class":1081},[1071,1615,1617,1620,1622,1624,1626,1628,1631,1633],{"class":1073,"line":1616},20,[1071,1618,1619],{"class":1077},"        throw",[1071,1621,1367],{"class":1081},[1071,1623,1144],{"class":1199},[1071,1625,1212],{"class":1221},[1071,1627,1233],{"class":1081},[1071,1629,1630],{"class":1098},"total must be preserved",[1071,1632,1233],{"class":1081},[1071,1634,1326],{"class":1221},[1071,1636,1638],{"class":1073,"line":1637},21,[1071,1639,1640],{"class":1081},"      }\n",[1071,1642,1644],{"class":1073,"line":1643},22,[1071,1645,1646],{"class":1081},"    },\n",[1071,1648,1650],{"class":1073,"line":1649},23,[1071,1651,1410],{"class":1081},[1071,1653,1655,1658],{"class":1073,"line":1654},24,[1071,1656,1657],{"class":1081},"}",[1071,1659,1326],{"class":1085},[1071,1661,1663],{"class":1073,"line":1662},25,[1071,1664,1183],{"emptyLinePlaceholder":1182},[1071,1666,1668,1670,1673,1675,1677,1679,1681],{"class":1073,"line":1667},26,[1071,1669,1190],{"class":1189},[1071,1671,1672],{"class":1085}," db ",[1071,1674,1196],{"class":1081},[1071,1676,1284],{"class":1077},[1071,1678,1086],{"class":1199},[1071,1680,1212],{"class":1085},[1071,1682,1215],{"class":1081},[1071,1684,1686,1689,1691,1693,1696],{"class":1073,"line":1685},27,[1071,1687,1688],{"class":1221},"  store",[1071,1690,1225],{"class":1081},[1071,1692,1112],{"class":1199},[1071,1694,1695],{"class":1085},"()",[1071,1697,1236],{"class":1081},[1071,1699,1701,1704,1706,1708,1711,1713],{"class":1073,"line":1700},28,[1071,1702,1703],{"class":1221},"  user",[1071,1705,1225],{"class":1081},[1071,1707,1095],{"class":1081},[1071,1709,1710],{"class":1098},"alice",[1071,1712,1233],{"class":1081},[1071,1714,1236],{"class":1081},[1071,1716,1718,1721,1723,1726],{"class":1073,"line":1717},29,[1071,1719,1720],{"class":1221},"  guardStrategies",[1071,1722,1225],{"class":1081},[1071,1724,1725],{"class":1085}," [disbursementGuard]",[1071,1727,1236],{"class":1081},[1071,1729,1731,1734,1736,1738,1740,1742],{"class":1073,"line":1730},30,[1071,1732,1733],{"class":1221},"  transactionsStrategy",[1071,1735,1225],{"class":1081},[1071,1737,1165],{"class":1199},[1071,1739,1695],{"class":1085},[1071,1741,1136],{"class":1081},[1071,1743,1745],{"class":1744},"sHwdD"," \u002F\u002F required for amendment mode\n",[1071,1747,1749,1751],{"class":1073,"line":1748},31,[1071,1750,1657],{"class":1081},[1071,1752,1326],{"class":1085},[1071,1754,1756],{"class":1073,"line":1755},32,[1071,1757,1183],{"emptyLinePlaceholder":1182},[1071,1759,1761,1763,1766,1768,1770,1773,1775,1778,1780,1782,1785,1787],{"class":1073,"line":1760},33,[1071,1762,1190],{"class":1189},[1071,1764,1765],{"class":1085}," vault ",[1071,1767,1196],{"class":1081},[1071,1769,1284],{"class":1077},[1071,1771,1772],{"class":1085}," db",[1071,1774,973],{"class":1081},[1071,1776,1777],{"class":1199},"openVault",[1071,1779,1212],{"class":1085},[1071,1781,1233],{"class":1081},[1071,1783,1784],{"class":1098},"books",[1071,1786,1233],{"class":1081},[1071,1788,1326],{"class":1085},[941,1790,1792],{"id":1791},"usage","Usage",[1794,1795,1797],"h3",{"id":1796},"a-locked-write-is-rejected","A locked write is rejected",[946,1799,1800,1801,1804,1805,1808,1809,1812,1813,1815],{},"The ",[949,1802,1803],{},"check"," callback above runs on every ",[949,1806,1807],{},"put()",". If ",[949,1810,1811],{},"inv-1"," is already\n",[949,1814,1351],{},", the disbursement is locked and the write throws before it ever\nreaches encryption or storage:",[1062,1817,1819],{"className":1064,"code":1818,"language":1066,"meta":1067,"style":1067},"await vault.collection\u003CDisbursement>('disbursements').put('d1', {\n  id: 'd1', invoiceId: 'inv-1', amount: 100,\n})\n\u002F\u002F → throws RecordLockedError:\n\u002F\u002F \"Cannot modify disbursements\u002Fd1 — locked by guard: invoice is issued.\n\u002F\u002F  Use withTransactions({ amendment: true, reason }) with admin\u002Fowner role to override.\"\n",[949,1820,1821,1866,1904,1910,1915,1920],{"__ignoreMap":1067},[1071,1822,1823,1826,1828,1830,1832,1834,1836,1838,1840,1842,1844,1846,1848,1850,1853,1855,1857,1860,1862,1864],{"class":1073,"line":1074},[1071,1824,1825],{"class":1077},"await",[1071,1827,1260],{"class":1085},[1071,1829,973],{"class":1081},[1071,1831,1291],{"class":1199},[1071,1833,1202],{"class":1081},[1071,1835,1206],{"class":1205},[1071,1837,1209],{"class":1081},[1071,1839,1212],{"class":1085},[1071,1841,1233],{"class":1081},[1071,1843,1230],{"class":1098},[1071,1845,1233],{"class":1081},[1071,1847,1009],{"class":1085},[1071,1849,973],{"class":1081},[1071,1851,1852],{"class":1199},"put",[1071,1854,1212],{"class":1085},[1071,1856,1233],{"class":1081},[1071,1858,1859],{"class":1098},"d1",[1071,1861,1233],{"class":1081},[1071,1863,1136],{"class":1081},[1071,1865,1269],{"class":1081},[1071,1867,1868,1871,1873,1875,1877,1879,1881,1884,1886,1888,1890,1892,1894,1897,1899,1902],{"class":1073,"line":1105},[1071,1869,1870],{"class":1221},"  id",[1071,1872,1225],{"class":1081},[1071,1874,1095],{"class":1081},[1071,1876,1859],{"class":1098},[1071,1878,1233],{"class":1081},[1071,1880,1136],{"class":1081},[1071,1882,1883],{"class":1221}," invoiceId",[1071,1885,1225],{"class":1081},[1071,1887,1095],{"class":1081},[1071,1889,1811],{"class":1098},[1071,1891,1233],{"class":1081},[1071,1893,1136],{"class":1081},[1071,1895,1896],{"class":1221}," amount",[1071,1898,1225],{"class":1081},[1071,1900,1901],{"class":1565}," 100",[1071,1903,1236],{"class":1081},[1071,1905,1906,1908],{"class":1073,"line":1126},[1071,1907,1657],{"class":1081},[1071,1909,1326],{"class":1085},[1071,1911,1912],{"class":1073,"line":1158},[1071,1913,1914],{"class":1744},"\u002F\u002F → throws RecordLockedError:\n",[1071,1916,1917],{"class":1073,"line":1179},[1071,1918,1919],{"class":1744},"\u002F\u002F \"Cannot modify disbursements\u002Fd1 — locked by guard: invoice is issued.\n",[1071,1921,1922],{"class":1073,"line":1186},[1071,1923,1924],{"class":1744},"\u002F\u002F  Use withTransactions({ amendment: true, reason }) with admin\u002Fowner role to override.\"\n",[1794,1926,1928],{"id":1927},"a-frozen-field-is-rejected","A frozen field is rejected",[946,1930,1931,1934,1935,1937,1938,1941,1942,1945,1946,1948],{},[949,1932,1933],{},"frozenFields"," locks specific fields once a condition on the existing\nrecord becomes true — here, ",[949,1936,1004],{}," can no longer change once an invoice\nis ",[949,1939,1940],{},"paid",". Registered the same way as ",[949,1943,1944],{},"disbursementGuard"," above (add it to\n",[949,1947,1030],{},"):",[1062,1950,1952],{"className":1064,"code":1951,"language":1066,"meta":1067,"style":1067},"import { withGuard, FieldFrozenError } from '@noy-db\u002Fhub\u002Fguards'\n\nconst invoiceGuard = withGuard\u003CInvoice>({\n  collection: 'invoices',\n  frozenFields: {\n    when: (existing) => existing.status === 'paid',\n    fields: ['amount'],\n  },\n})\n\nawait vault.collection\u003CInvoice>('invoices').put('inv-2', { id: 'inv-2', status: 'paid', amount: 500 })\nawait vault.collection\u003CInvoice>('invoices').put('inv-2', { id: 'inv-2', status: 'paid', amount: 600 })\n\u002F\u002F → throws FieldFrozenError:\n\u002F\u002F \"Cannot change frozen field(s) on invoices\u002Finv-2: amount.\n\u002F\u002F  Use withTransactions({ amendment: true, reason }) with admin\u002Fowner role to override.\"\n",[949,1953,1954,1977,1981,2002,2016,2025,2060,2079,2083,2089,2093,2173,2250,2255,2260],{"__ignoreMap":1067},[1071,1955,1956,1958,1960,1962,1964,1967,1969,1971,1973,1975],{"class":1073,"line":1074},[1071,1957,1078],{"class":1077},[1071,1959,1082],{"class":1081},[1071,1961,1133],{"class":1085},[1071,1963,1136],{"class":1081},[1071,1965,1966],{"class":1085}," FieldFrozenError",[1071,1968,1089],{"class":1081},[1071,1970,1092],{"class":1077},[1071,1972,1095],{"class":1081},[1071,1974,1153],{"class":1098},[1071,1976,1102],{"class":1081},[1071,1978,1979],{"class":1073,"line":1105},[1071,1980,1183],{"emptyLinePlaceholder":1182},[1071,1982,1983,1985,1988,1990,1992,1994,1996,1998,2000],{"class":1073,"line":1126},[1071,1984,1190],{"class":1189},[1071,1986,1987],{"class":1085}," invoiceGuard ",[1071,1989,1196],{"class":1081},[1071,1991,1133],{"class":1199},[1071,1993,1202],{"class":1081},[1071,1995,1296],{"class":1205},[1071,1997,1209],{"class":1081},[1071,1999,1212],{"class":1085},[1071,2001,1215],{"class":1081},[1071,2003,2004,2006,2008,2010,2012,2014],{"class":1073,"line":1158},[1071,2005,1222],{"class":1221},[1071,2007,1225],{"class":1081},[1071,2009,1095],{"class":1081},[1071,2011,1305],{"class":1098},[1071,2013,1233],{"class":1081},[1071,2015,1236],{"class":1081},[1071,2017,2018,2021,2023],{"class":1073,"line":1179},[1071,2019,2020],{"class":1221},"  frozenFields",[1071,2022,1225],{"class":1081},[1071,2024,1269],{"class":1081},[1071,2026,2027,2030,2032,2034,2037,2039,2041,2044,2046,2049,2052,2054,2056,2058],{"class":1073,"line":1186},[1071,2028,2029],{"class":1199},"    when",[1071,2031,1225],{"class":1081},[1071,2033,1027],{"class":1081},[1071,2035,2036],{"class":1252},"existing",[1071,2038,1009],{"class":1081},[1071,2040,1266],{"class":1189},[1071,2042,2043],{"class":1085}," existing",[1071,2045,973],{"class":1081},[1071,2047,2048],{"class":1085},"status ",[1071,2050,2051],{"class":1081},"===",[1071,2053,1095],{"class":1081},[1071,2055,1940],{"class":1098},[1071,2057,1233],{"class":1081},[1071,2059,1236],{"class":1081},[1071,2061,2062,2065,2067,2069,2071,2073,2075,2077],{"class":1073,"line":1218},[1071,2063,2064],{"class":1221},"    fields",[1071,2066,1225],{"class":1081},[1071,2068,1431],{"class":1085},[1071,2070,1233],{"class":1081},[1071,2072,1004],{"class":1098},[1071,2074,1233],{"class":1081},[1071,2076,1448],{"class":1085},[1071,2078,1236],{"class":1081},[1071,2080,2081],{"class":1073,"line":1239},[1071,2082,1410],{"class":1081},[1071,2084,2085,2087],{"class":1073,"line":1272},[1071,2086,1657],{"class":1081},[1071,2088,1326],{"class":1085},[1071,2090,2091],{"class":1073,"line":1329},[1071,2092,1183],{"emptyLinePlaceholder":1182},[1071,2094,2095,2097,2099,2101,2103,2105,2107,2109,2111,2113,2115,2117,2119,2121,2123,2125,2127,2130,2132,2134,2136,2139,2141,2143,2145,2147,2149,2152,2154,2156,2158,2160,2162,2164,2166,2169,2171],{"class":1073,"line":1361},[1071,2096,1825],{"class":1077},[1071,2098,1260],{"class":1085},[1071,2100,973],{"class":1081},[1071,2102,1291],{"class":1199},[1071,2104,1202],{"class":1081},[1071,2106,1296],{"class":1205},[1071,2108,1209],{"class":1081},[1071,2110,1212],{"class":1085},[1071,2112,1233],{"class":1081},[1071,2114,1305],{"class":1098},[1071,2116,1233],{"class":1081},[1071,2118,1009],{"class":1085},[1071,2120,973],{"class":1081},[1071,2122,1852],{"class":1199},[1071,2124,1212],{"class":1085},[1071,2126,1233],{"class":1081},[1071,2128,2129],{"class":1098},"inv-2",[1071,2131,1233],{"class":1081},[1071,2133,1136],{"class":1081},[1071,2135,1082],{"class":1081},[1071,2137,2138],{"class":1221}," id",[1071,2140,1225],{"class":1081},[1071,2142,1095],{"class":1081},[1071,2144,2129],{"class":1098},[1071,2146,1233],{"class":1081},[1071,2148,1136],{"class":1081},[1071,2150,2151],{"class":1221}," status",[1071,2153,1225],{"class":1081},[1071,2155,1095],{"class":1081},[1071,2157,1940],{"class":1098},[1071,2159,1233],{"class":1081},[1071,2161,1136],{"class":1081},[1071,2163,1896],{"class":1221},[1071,2165,1225],{"class":1081},[1071,2167,2168],{"class":1565}," 500",[1071,2170,1089],{"class":1081},[1071,2172,1326],{"class":1085},[1071,2174,2175,2177,2179,2181,2183,2185,2187,2189,2191,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213,2215,2217,2219,2221,2223,2225,2227,2229,2231,2233,2235,2237,2239,2241,2243,2246,2248],{"class":1073,"line":1401},[1071,2176,1825],{"class":1077},[1071,2178,1260],{"class":1085},[1071,2180,973],{"class":1081},[1071,2182,1291],{"class":1199},[1071,2184,1202],{"class":1081},[1071,2186,1296],{"class":1205},[1071,2188,1209],{"class":1081},[1071,2190,1212],{"class":1085},[1071,2192,1233],{"class":1081},[1071,2194,1305],{"class":1098},[1071,2196,1233],{"class":1081},[1071,2198,1009],{"class":1085},[1071,2200,973],{"class":1081},[1071,2202,1852],{"class":1199},[1071,2204,1212],{"class":1085},[1071,2206,1233],{"class":1081},[1071,2208,2129],{"class":1098},[1071,2210,1233],{"class":1081},[1071,2212,1136],{"class":1081},[1071,2214,1082],{"class":1081},[1071,2216,2138],{"class":1221},[1071,2218,1225],{"class":1081},[1071,2220,1095],{"class":1081},[1071,2222,2129],{"class":1098},[1071,2224,1233],{"class":1081},[1071,2226,1136],{"class":1081},[1071,2228,2151],{"class":1221},[1071,2230,1225],{"class":1081},[1071,2232,1095],{"class":1081},[1071,2234,1940],{"class":1098},[1071,2236,1233],{"class":1081},[1071,2238,1136],{"class":1081},[1071,2240,1896],{"class":1221},[1071,2242,1225],{"class":1081},[1071,2244,2245],{"class":1565}," 600",[1071,2247,1089],{"class":1081},[1071,2249,1326],{"class":1085},[1071,2251,2252],{"class":1073,"line":1407},[1071,2253,2254],{"class":1744},"\u002F\u002F → throws FieldFrozenError:\n",[1071,2256,2257],{"class":1073,"line":1413},[1071,2258,2259],{"class":1744},"\u002F\u002F \"Cannot change frozen field(s) on invoices\u002Finv-2: amount.\n",[1071,2261,2262],{"class":1073,"line":1423},[1071,2263,1924],{"class":1744},[1794,2265,2267],{"id":2266},"an-authorized-amendment-overrides-the-lock","An authorized amendment overrides the lock",[946,2269,2270,2271,2273,2274,2276,2277,2280,2281,2284,2285,2289,2290,1045,2292,2294,2295,1225],{},"Both ",[949,2272,1803],{}," and ",[949,2275,1933],{}," are skipped inside an amendment\ntransaction — ",[949,2278,2279],{},"db.transaction({ amendment: true, reason }, fn)",", available\nonce ",[949,2282,2283],{},"withTransactions()"," is opted in. The caller's ",[978,2286,2288],{"href":2287},"..\u002Fcore\u002F06-permissions-and-keyring","keyring\nrole"," must be ",[949,2291,1044],{},[949,2293,1048],{},", or\n",[949,2296,1052],{},[1062,2298,2300],{"className":1064,"code":2299,"language":1066,"meta":1067,"style":1067},"await db.transaction({ amendment: true, reason: 'correct posted amount' }, async (tx) => {\n  tx.vault('books').collection\u003CInvoice>('invoices').put('inv-2', {\n    id: 'inv-2', status: 'paid', amount: 600,\n  })\n})\n\nawait vault.collection\u003CInvoice>('invoices').get('inv-2')\n\u002F\u002F → { id: 'inv-2', status: 'paid', amount: 600 }\n",[949,2301,2302,2357,2413,2448,2455,2461,2465,2505],{"__ignoreMap":1067},[1071,2303,2304,2306,2308,2310,2313,2315,2318,2321,2323,2327,2329,2332,2334,2336,2339,2341,2344,2346,2348,2351,2353,2355],{"class":1073,"line":1074},[1071,2305,1825],{"class":1077},[1071,2307,1772],{"class":1085},[1071,2309,973],{"class":1081},[1071,2311,2312],{"class":1199},"transaction",[1071,2314,1212],{"class":1085},[1071,2316,2317],{"class":1081},"{",[1071,2319,2320],{"class":1221}," amendment",[1071,2322,1225],{"class":1081},[1071,2324,2326],{"class":2325},"sfNiH"," true",[1071,2328,1136],{"class":1081},[1071,2330,2331],{"class":1221}," reason",[1071,2333,1225],{"class":1081},[1071,2335,1095],{"class":1081},[1071,2337,2338],{"class":1098},"correct posted amount",[1071,2340,1233],{"class":1081},[1071,2342,2343],{"class":1081}," },",[1071,2345,1247],{"class":1189},[1071,2347,1027],{"class":1081},[1071,2349,2350],{"class":1252},"tx",[1071,2352,1009],{"class":1081},[1071,2354,1266],{"class":1189},[1071,2356,1269],{"class":1081},[1071,2358,2359,2362,2364,2367,2369,2371,2373,2375,2377,2379,2381,2383,2385,2387,2389,2391,2393,2395,2397,2399,2401,2403,2405,2407,2409,2411],{"class":1073,"line":1105},[1071,2360,2361],{"class":1085},"  tx",[1071,2363,973],{"class":1081},[1071,2365,2366],{"class":1199},"vault",[1071,2368,1212],{"class":1221},[1071,2370,1233],{"class":1081},[1071,2372,1784],{"class":1098},[1071,2374,1233],{"class":1081},[1071,2376,1009],{"class":1221},[1071,2378,973],{"class":1081},[1071,2380,1291],{"class":1199},[1071,2382,1202],{"class":1081},[1071,2384,1296],{"class":1205},[1071,2386,1209],{"class":1081},[1071,2388,1212],{"class":1221},[1071,2390,1233],{"class":1081},[1071,2392,1305],{"class":1098},[1071,2394,1233],{"class":1081},[1071,2396,1009],{"class":1221},[1071,2398,973],{"class":1081},[1071,2400,1852],{"class":1199},[1071,2402,1212],{"class":1221},[1071,2404,1233],{"class":1081},[1071,2406,2129],{"class":1098},[1071,2408,1233],{"class":1081},[1071,2410,1136],{"class":1081},[1071,2412,1269],{"class":1081},[1071,2414,2415,2418,2420,2422,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442,2444,2446],{"class":1073,"line":1126},[1071,2416,2417],{"class":1221},"    id",[1071,2419,1225],{"class":1081},[1071,2421,1095],{"class":1081},[1071,2423,2129],{"class":1098},[1071,2425,1233],{"class":1081},[1071,2427,1136],{"class":1081},[1071,2429,2151],{"class":1221},[1071,2431,1225],{"class":1081},[1071,2433,1095],{"class":1081},[1071,2435,1940],{"class":1098},[1071,2437,1233],{"class":1081},[1071,2439,1136],{"class":1081},[1071,2441,1896],{"class":1221},[1071,2443,1225],{"class":1081},[1071,2445,2245],{"class":1565},[1071,2447,1236],{"class":1081},[1071,2449,2450,2453],{"class":1073,"line":1158},[1071,2451,2452],{"class":1081},"  }",[1071,2454,1326],{"class":1221},[1071,2456,2457,2459],{"class":1073,"line":1179},[1071,2458,1657],{"class":1081},[1071,2460,1326],{"class":1085},[1071,2462,2463],{"class":1073,"line":1186},[1071,2464,1183],{"emptyLinePlaceholder":1182},[1071,2466,2467,2469,2471,2473,2475,2477,2479,2481,2483,2485,2487,2489,2491,2493,2495,2497,2499,2501,2503],{"class":1073,"line":1218},[1071,2468,1825],{"class":1077},[1071,2470,1260],{"class":1085},[1071,2472,973],{"class":1081},[1071,2474,1291],{"class":1199},[1071,2476,1202],{"class":1081},[1071,2478,1296],{"class":1205},[1071,2480,1209],{"class":1081},[1071,2482,1212],{"class":1085},[1071,2484,1233],{"class":1081},[1071,2486,1305],{"class":1098},[1071,2488,1233],{"class":1081},[1071,2490,1009],{"class":1085},[1071,2492,973],{"class":1081},[1071,2494,1314],{"class":1199},[1071,2496,1212],{"class":1085},[1071,2498,1233],{"class":1081},[1071,2500,2129],{"class":1098},[1071,2502,1233],{"class":1081},[1071,2504,1326],{"class":1085},[1071,2506,2507],{"class":1073,"line":1239},[1071,2508,2509],{"class":1744},"\u002F\u002F → { id: 'inv-2', status: 'paid', amount: 600 }\n",[946,2511,2512,2513,2516,2517,2521],{},"If a guard declares an ",[949,2514,2515],{},"amendment.invariant",", it still runs at commit over\nthe whole change-set and can reject the amendment — see ",[978,2518,2520],{"href":2519},"#amendment-flow","Amendment\nflow"," below.",[941,2523,2525],{"id":2524},"api","API",[946,2527,2528],{},"Four primitives, one strategy:",[2530,2531,2532,2548],"table",{},[2533,2534,2535],"thead",{},[2536,2537,2538,2542,2545],"tr",{},[2539,2540,2541],"th",{},"Primitive",[2539,2543,2544],{},"When it fires",[2539,2546,2547],{},"Throws",[2549,2550,2551,2570,2587,2608],"tbody",{},[2536,2552,2553,2558,2564],{},[2554,2555,2556],"td",{},[949,2557,1803],{},[2554,2559,2560,2561,2563],{},"Every ",[949,2562,1807],{}," (skipped in amendment mode)",[2554,2565,2566,2567],{},"Anything; conventionally ",[949,2568,2569],{},"RecordLockedError",[2536,2571,2572,2577,2583],{},[2554,2573,2574],{},[949,2575,2576],{},"onDelete",[2554,2578,2560,2579,2582],{},[949,2580,2581],{},"delete()"," of an existing record (skipped in amendment mode); skipped for delete-of-absent",[2554,2584,2566,2585],{},[949,2586,2569],{},[2536,2588,2589,2593,2602],{},[2554,2590,2591],{},[949,2592,1933],{},[2554,2594,2560,2595,2597,2598,2601],{},[949,2596,1807],{}," after ",[949,2599,2600],{},"when(existing)"," becomes true",[2554,2603,2604,2607],{},[949,2605,2606],{},"FieldFrozenError"," listing changed frozen fields",[2536,2609,2610,2614,2620],{},[2554,2611,2612],{},[949,2613,963],{},[2554,2615,2616,2617],{},"Inside ",[949,2618,2619],{},"withTransactions({ amendment: true, reason })",[2554,2621,2622,2625],{},[949,2623,2624],{},"InvariantError"," if the rule fails",[946,2627,2628,2630,2631,2633,2634,2637,2638,2641,2642,2637,2645,973],{},[949,2629,1803],{}," is put-only — ",[949,2632,2576],{}," is the dedicated delete-time hook. The\nargument shapes mirror each other but the semantics are explicit:\n",[949,2635,2636],{},"check(incoming, ctx)"," validates a record being ",[953,2639,2640],{},"written",";\n",[949,2643,2644],{},"onDelete(existing, ctx)",[953,2646,2647],{},"removed",[1794,2649,2651,2653],{"id":2650},"ondelete-bypass-paths",[949,2652,2576],{}," bypass paths",[946,2655,2656,2657,2659],{},"Two paths skip the ",[949,2658,2576],{}," callback. Both are by design:",[2661,2662,2663,2682],"ol",{},[996,2664,2665,1027,2668,2671,2672,2674,2675,2677,2678,2681],{},[953,2666,2667],{},"Amendment transactions",[949,2669,2670],{},"db.transaction({ amendment: true })",")\nfor an authorized role — amendments are the generic unlock primitive,\nconsistent with how ",[949,2673,1933],{}," lets staged writes through. The\n",[949,2676,2515],{}," block (if declared) DOES still see the\n",[949,2679,2680],{},"{ before, after: null }"," change pair and can reject the delete at\ncommit time.",[996,2683,2684,2687,2688,2691,2692,2696,2697,2700,2701,2703],{},[953,2685,2686],{},"System-internal deletes"," — ",[978,2689,665],{"href":2690},".\u002Fderivations"," tombstones\nand ",[978,2693,2695],{"href":2694},".\u002Fmaterialized-views","materialized-view"," refresh deletes route\nthrough an internal-only delete path that bypasses every user-facing\nguard. Housekeeping writes are not user-initiated and would otherwise\ntrip user invariants registered against output collections. ",[953,2698,2699],{},"If\nthe internal delete fires while an amendment window is open","\n(e.g. an admin amendment edits a source row → triggers a\nderivation cascade → cascades a tombstone), the change pair IS\npushed onto the amendment's change-set and surfaces to\n",[949,2702,2515],{},". This keeps the \"truly unconditional\" paired\npattern below honest.",[1794,2705,2707],{"id":2706},"truly-unconditional-delete-block-pair-the-two-hooks","Truly unconditional delete-block — pair the two hooks",[946,2709,2710,2713,2714,2716,2717,2719],{},[949,2711,2712],{},"onDelete: () => { throw }"," alone is NOT unconditional. An admin\namendment can still bypass it. For legal-document immutability rules\n(e.g. Thai Revenue Code §86: receipts are append-only forever) pair\n",[949,2715,2576],{}," with an ",[949,2718,2515],{}," that re-throws on any\ndelete-shaped change:",[1062,2721,2723],{"className":1064,"code":2722,"language":1066,"meta":1067,"style":1067},"withGuard\u003CReceipt>({\n  collection: 'receipts',\n  onDelete: () => {\n    throw new RecordLockedError('receipts', '', 'receipts are append-only')\n  },\n  amendment: {\n    roles: ['admin', 'owner'],\n    invariant: (changes) => {\n      for (const c of changes) {\n        if (c.before !== null && c.after === null) {\n          throw new RecordLockedError('receipts', '', 'amendment cannot delete')\n        }\n      }\n    },\n  },\n})\n\n\u002F\u002F Ordinary delete — blocked by `onDelete` before it ever reaches an amendment:\nawait vault.collection\u003CReceipt>('receipts').delete('r1')\n\u002F\u002F → throws RecordLockedError: \"Cannot modify receipts\u002F — locked by guard:\n\u002F\u002F   receipts are append-only. Use withTransactions({ amendment: true, reason })\n\u002F\u002F   with admin\u002Fowner role to override.\"\n\n\u002F\u002F Admin amendment attempting the same delete — blocked by the invariant instead:\nawait db.transaction({ amendment: true, reason: 'cleanup' }, async (tx) => {\n  tx.vault('books').collection\u003CReceipt>('receipts').delete('r1')\n})\n\u002F\u002F → throws InvariantError: \"Cannot modify receipts\u002F — locked by guard:\n\u002F\u002F   amendment cannot delete. Use withTransactions({ amendment: true, reason })\n\u002F\u002F   with admin\u002Fowner role to override.\"\n",[949,2724,2725,2741,2756,2770,2803,2807,2815,2841,2857,2878,2914,2946,2951,2955,2959,2963,2969,2973,2978,3020,3025,3030,3035,3039,3044,3091,3143,3149,3154,3159],{"__ignoreMap":1067},[1071,2726,2727,2730,2732,2735,2737,2739],{"class":1073,"line":1074},[1071,2728,2729],{"class":1199},"withGuard",[1071,2731,1202],{"class":1081},[1071,2733,2734],{"class":1205},"Receipt",[1071,2736,1209],{"class":1081},[1071,2738,1212],{"class":1085},[1071,2740,1215],{"class":1081},[1071,2742,2743,2745,2747,2749,2752,2754],{"class":1073,"line":1105},[1071,2744,1222],{"class":1221},[1071,2746,1225],{"class":1081},[1071,2748,1095],{"class":1081},[1071,2750,2751],{"class":1098},"receipts",[1071,2753,1233],{"class":1081},[1071,2755,1236],{"class":1081},[1071,2757,2758,2761,2763,2766,2768],{"class":1073,"line":1126},[1071,2759,2760],{"class":1199},"  onDelete",[1071,2762,1225],{"class":1081},[1071,2764,2765],{"class":1081}," ()",[1071,2767,1266],{"class":1189},[1071,2769,1269],{"class":1081},[1071,2771,2772,2775,2777,2779,2781,2783,2785,2787,2789,2792,2794,2796,2799,2801],{"class":1073,"line":1158},[1071,2773,2774],{"class":1077},"    throw",[1071,2776,1367],{"class":1081},[1071,2778,1139],{"class":1199},[1071,2780,1212],{"class":1221},[1071,2782,1233],{"class":1081},[1071,2784,2751],{"class":1098},[1071,2786,1233],{"class":1081},[1071,2788,1136],{"class":1081},[1071,2790,2791],{"class":1081}," ''",[1071,2793,1136],{"class":1081},[1071,2795,1095],{"class":1081},[1071,2797,2798],{"class":1098},"receipts are append-only",[1071,2800,1233],{"class":1081},[1071,2802,1326],{"class":1221},[1071,2804,2805],{"class":1073,"line":1179},[1071,2806,1410],{"class":1081},[1071,2808,2809,2811,2813],{"class":1073,"line":1186},[1071,2810,1416],{"class":1221},[1071,2812,1225],{"class":1081},[1071,2814,1269],{"class":1081},[1071,2816,2817,2819,2821,2823,2825,2827,2829,2831,2833,2835,2837,2839],{"class":1073,"line":1218},[1071,2818,1426],{"class":1221},[1071,2820,1225],{"class":1081},[1071,2822,1431],{"class":1085},[1071,2824,1233],{"class":1081},[1071,2826,1044],{"class":1098},[1071,2828,1233],{"class":1081},[1071,2830,1136],{"class":1081},[1071,2832,1095],{"class":1081},[1071,2834,1048],{"class":1098},[1071,2836,1233],{"class":1081},[1071,2838,1448],{"class":1085},[1071,2840,1236],{"class":1081},[1071,2842,2843,2845,2847,2849,2851,2853,2855],{"class":1073,"line":1239},[1071,2844,1456],{"class":1199},[1071,2846,1225],{"class":1081},[1071,2848,1027],{"class":1081},[1071,2850,1463],{"class":1252},[1071,2852,1009],{"class":1081},[1071,2854,1266],{"class":1189},[1071,2856,1269],{"class":1081},[1071,2858,2859,2862,2864,2866,2868,2871,2874,2876],{"class":1073,"line":1272},[1071,2860,2861],{"class":1077},"      for",[1071,2863,1027],{"class":1221},[1071,2865,1190],{"class":1189},[1071,2867,1531],{"class":1085},[1071,2869,2870],{"class":1081}," of",[1071,2872,2873],{"class":1085}," changes",[1071,2875,1356],{"class":1221},[1071,2877,1215],{"class":1081},[1071,2879,2880,2883,2885,2887,2889,2891,2894,2897,2900,2902,2904,2906,2908,2910,2912],{"class":1073,"line":1329},[1071,2881,2882],{"class":1077},"        if",[1071,2884,1027],{"class":1221},[1071,2886,1547],{"class":1085},[1071,2888,973],{"class":1081},[1071,2890,1492],{"class":1085},[1071,2892,2893],{"class":1081}," !==",[1071,2895,2896],{"class":1081}," null",[1071,2898,2899],{"class":1081}," &&",[1071,2901,1531],{"class":1085},[1071,2903,973],{"class":1081},[1071,2905,1502],{"class":1085},[1071,2907,1346],{"class":1081},[1071,2909,2896],{"class":1081},[1071,2911,1356],{"class":1221},[1071,2913,1215],{"class":1081},[1071,2915,2916,2919,2921,2923,2925,2927,2929,2931,2933,2935,2937,2939,2942,2944],{"class":1073,"line":1361},[1071,2917,2918],{"class":1077},"          throw",[1071,2920,1367],{"class":1081},[1071,2922,1139],{"class":1199},[1071,2924,1212],{"class":1221},[1071,2926,1233],{"class":1081},[1071,2928,2751],{"class":1098},[1071,2930,1233],{"class":1081},[1071,2932,1136],{"class":1081},[1071,2934,2791],{"class":1081},[1071,2936,1136],{"class":1081},[1071,2938,1095],{"class":1081},[1071,2940,2941],{"class":1098},"amendment cannot delete",[1071,2943,1233],{"class":1081},[1071,2945,1326],{"class":1221},[1071,2947,2948],{"class":1073,"line":1401},[1071,2949,2950],{"class":1081},"        }\n",[1071,2952,2953],{"class":1073,"line":1407},[1071,2954,1640],{"class":1081},[1071,2956,2957],{"class":1073,"line":1413},[1071,2958,1646],{"class":1081},[1071,2960,2961],{"class":1073,"line":1423},[1071,2962,1410],{"class":1081},[1071,2964,2965,2967],{"class":1073,"line":1453},[1071,2966,1657],{"class":1081},[1071,2968,1326],{"class":1085},[1071,2970,2971],{"class":1073,"line":1472},[1071,2972,1183],{"emptyLinePlaceholder":1182},[1071,2974,2975],{"class":1073,"line":1512},[1071,2976,2977],{"class":1744},"\u002F\u002F Ordinary delete — blocked by `onDelete` before it ever reaches an amendment:\n",[1071,2979,2980,2982,2984,2986,2988,2990,2992,2994,2996,2998,3000,3002,3004,3006,3009,3011,3013,3016,3018],{"class":1073,"line":1577},[1071,2981,1825],{"class":1077},[1071,2983,1260],{"class":1085},[1071,2985,973],{"class":1081},[1071,2987,1291],{"class":1199},[1071,2989,1202],{"class":1081},[1071,2991,2734],{"class":1205},[1071,2993,1209],{"class":1081},[1071,2995,1212],{"class":1085},[1071,2997,1233],{"class":1081},[1071,2999,2751],{"class":1098},[1071,3001,1233],{"class":1081},[1071,3003,1009],{"class":1085},[1071,3005,973],{"class":1081},[1071,3007,3008],{"class":1199},"delete",[1071,3010,1212],{"class":1085},[1071,3012,1233],{"class":1081},[1071,3014,3015],{"class":1098},"r1",[1071,3017,1233],{"class":1081},[1071,3019,1326],{"class":1085},[1071,3021,3022],{"class":1073,"line":1616},[1071,3023,3024],{"class":1744},"\u002F\u002F → throws RecordLockedError: \"Cannot modify receipts\u002F — locked by guard:\n",[1071,3026,3027],{"class":1073,"line":1637},[1071,3028,3029],{"class":1744},"\u002F\u002F   receipts are append-only. Use withTransactions({ amendment: true, reason })\n",[1071,3031,3032],{"class":1073,"line":1643},[1071,3033,3034],{"class":1744},"\u002F\u002F   with admin\u002Fowner role to override.\"\n",[1071,3036,3037],{"class":1073,"line":1649},[1071,3038,1183],{"emptyLinePlaceholder":1182},[1071,3040,3041],{"class":1073,"line":1654},[1071,3042,3043],{"class":1744},"\u002F\u002F Admin amendment attempting the same delete — blocked by the invariant instead:\n",[1071,3045,3046,3048,3050,3052,3054,3056,3058,3060,3062,3064,3066,3068,3070,3072,3075,3077,3079,3081,3083,3085,3087,3089],{"class":1073,"line":1662},[1071,3047,1825],{"class":1077},[1071,3049,1772],{"class":1085},[1071,3051,973],{"class":1081},[1071,3053,2312],{"class":1199},[1071,3055,1212],{"class":1085},[1071,3057,2317],{"class":1081},[1071,3059,2320],{"class":1221},[1071,3061,1225],{"class":1081},[1071,3063,2326],{"class":2325},[1071,3065,1136],{"class":1081},[1071,3067,2331],{"class":1221},[1071,3069,1225],{"class":1081},[1071,3071,1095],{"class":1081},[1071,3073,3074],{"class":1098},"cleanup",[1071,3076,1233],{"class":1081},[1071,3078,2343],{"class":1081},[1071,3080,1247],{"class":1189},[1071,3082,1027],{"class":1081},[1071,3084,2350],{"class":1252},[1071,3086,1009],{"class":1081},[1071,3088,1266],{"class":1189},[1071,3090,1269],{"class":1081},[1071,3092,3093,3095,3097,3099,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119,3121,3123,3125,3127,3129,3131,3133,3135,3137,3139,3141],{"class":1073,"line":1667},[1071,3094,2361],{"class":1085},[1071,3096,973],{"class":1081},[1071,3098,2366],{"class":1199},[1071,3100,1212],{"class":1221},[1071,3102,1233],{"class":1081},[1071,3104,1784],{"class":1098},[1071,3106,1233],{"class":1081},[1071,3108,1009],{"class":1221},[1071,3110,973],{"class":1081},[1071,3112,1291],{"class":1199},[1071,3114,1202],{"class":1081},[1071,3116,2734],{"class":1205},[1071,3118,1209],{"class":1081},[1071,3120,1212],{"class":1221},[1071,3122,1233],{"class":1081},[1071,3124,2751],{"class":1098},[1071,3126,1233],{"class":1081},[1071,3128,1009],{"class":1221},[1071,3130,973],{"class":1081},[1071,3132,3008],{"class":1199},[1071,3134,1212],{"class":1221},[1071,3136,1233],{"class":1081},[1071,3138,3015],{"class":1098},[1071,3140,1233],{"class":1081},[1071,3142,1326],{"class":1221},[1071,3144,3145,3147],{"class":1073,"line":1685},[1071,3146,1657],{"class":1081},[1071,3148,1326],{"class":1085},[1071,3150,3151],{"class":1073,"line":1700},[1071,3152,3153],{"class":1744},"\u002F\u002F → throws InvariantError: \"Cannot modify receipts\u002F — locked by guard:\n",[1071,3155,3156],{"class":1073,"line":1717},[1071,3157,3158],{"class":1744},"\u002F\u002F   amendment cannot delete. Use withTransactions({ amendment: true, reason })\n",[1071,3160,3161],{"class":1073,"line":1730},[1071,3162,3034],{"class":1744},[946,3164,3165,3166,3168,3169,3172,3173,3175,3176,3179],{},"The thrown ",[949,3167,2569],{}," inside ",[949,3170,3171],{},"invariant"," is wrapped in\n",[949,3174,2624],{}," by ",[949,3177,3178],{},"GuardExecutor.runInvariant"," (the message survives);\nthe staged delete rolls back, the record stays.",[1794,3181,3183,2273,3186],{"id":3182},"immutableguard-and-amendmentinvariant",[949,3184,3185],{},"immutableGuard",[949,3187,3188],{},"amendmentInvariant",[946,3190,3191,3193,3194,3197,3198,3201,3202,3205,3206,3208,3209,3211,3212,3215,3216,973],{},[949,3192,3185],{}," packages the append-only pattern above into one helper.\nGive it either ",[949,3195,3196],{},"after: (record) => boolean"," — the record becomes immutable\nonce the predicate turns true — or ",[949,3199,3200],{},"appendOnly: true",", shorthand for\n\"immutable from creation\" (they're mutually exclusive; omitting both throws\n",[949,3203,3204],{},"ValidationError","). By default its amendment override is an empty-allow (so\nan authorized role can amend freely) — backward compatible with a hand-rolled\n",[949,3207,2729],{},". Pass the optional ",[949,3210,3188],{}," to keep a rule inviolable\n",[953,3213,3214],{},"even inside an amendment tx","; it has the same signature as\n",[949,3217,3218],{},"GuardStrategy.amendment.invariant",[1062,3220,3222],{"className":1064,"code":3221,"language":1066,"meta":1067,"style":1067},"import { immutableGuard, RecordLockedError } from '@noy-db\u002Fhub\u002Fguards'\n\nconst receiptGuard = immutableGuard\u003CReceipt>({\n  collection: 'receipts',\n  appendOnly: true, \u002F\u002F immutable from creation — no `after` needed\n  amendmentInvariant: (changes) => {\n    for (const c of changes) {\n      if (c.before !== null && c.after === null) {\n        throw new RecordLockedError('receipts', '', 'amendment cannot delete')\n      }\n    }\n  },\n})\n\nawait vault.collection\u003CReceipt>('receipts').put('r1', { id: 'r1', total: 500 })\nawait vault.collection\u003CReceipt>('receipts').put('r1', { id: 'r1', total: 600 })\n\u002F\u002F → throws RecordLockedError: \"Cannot modify receipts\u002Fr1 — locked by guard:\n\u002F\u002F   append-only collection. Use withTransactions({ amendment: true, reason })\n\u002F\u002F   with admin\u002Fowner role to override.\"\n",[949,3223,3224,3247,3251,3272,3286,3300,3317,3336,3368,3398,3402,3406,3410,3416,3420,3485,3549,3554,3559],{"__ignoreMap":1067},[1071,3225,3226,3228,3230,3233,3235,3237,3239,3241,3243,3245],{"class":1073,"line":1074},[1071,3227,1078],{"class":1077},[1071,3229,1082],{"class":1081},[1071,3231,3232],{"class":1085}," immutableGuard",[1071,3234,1136],{"class":1081},[1071,3236,1139],{"class":1085},[1071,3238,1089],{"class":1081},[1071,3240,1092],{"class":1077},[1071,3242,1095],{"class":1081},[1071,3244,1153],{"class":1098},[1071,3246,1102],{"class":1081},[1071,3248,3249],{"class":1073,"line":1105},[1071,3250,1183],{"emptyLinePlaceholder":1182},[1071,3252,3253,3255,3258,3260,3262,3264,3266,3268,3270],{"class":1073,"line":1126},[1071,3254,1190],{"class":1189},[1071,3256,3257],{"class":1085}," receiptGuard ",[1071,3259,1196],{"class":1081},[1071,3261,3232],{"class":1199},[1071,3263,1202],{"class":1081},[1071,3265,2734],{"class":1205},[1071,3267,1209],{"class":1081},[1071,3269,1212],{"class":1085},[1071,3271,1215],{"class":1081},[1071,3273,3274,3276,3278,3280,3282,3284],{"class":1073,"line":1158},[1071,3275,1222],{"class":1221},[1071,3277,1225],{"class":1081},[1071,3279,1095],{"class":1081},[1071,3281,2751],{"class":1098},[1071,3283,1233],{"class":1081},[1071,3285,1236],{"class":1081},[1071,3287,3288,3291,3293,3295,3297],{"class":1073,"line":1179},[1071,3289,3290],{"class":1221},"  appendOnly",[1071,3292,1225],{"class":1081},[1071,3294,2326],{"class":2325},[1071,3296,1136],{"class":1081},[1071,3298,3299],{"class":1744}," \u002F\u002F immutable from creation — no `after` needed\n",[1071,3301,3302,3305,3307,3309,3311,3313,3315],{"class":1073,"line":1186},[1071,3303,3304],{"class":1199},"  amendmentInvariant",[1071,3306,1225],{"class":1081},[1071,3308,1027],{"class":1081},[1071,3310,1463],{"class":1252},[1071,3312,1009],{"class":1081},[1071,3314,1266],{"class":1189},[1071,3316,1269],{"class":1081},[1071,3318,3319,3322,3324,3326,3328,3330,3332,3334],{"class":1073,"line":1218},[1071,3320,3321],{"class":1077},"    for",[1071,3323,1027],{"class":1221},[1071,3325,1190],{"class":1189},[1071,3327,1531],{"class":1085},[1071,3329,2870],{"class":1081},[1071,3331,2873],{"class":1085},[1071,3333,1356],{"class":1221},[1071,3335,1215],{"class":1081},[1071,3337,3338,3340,3342,3344,3346,3348,3350,3352,3354,3356,3358,3360,3362,3364,3366],{"class":1073,"line":1239},[1071,3339,1580],{"class":1077},[1071,3341,1027],{"class":1221},[1071,3343,1547],{"class":1085},[1071,3345,973],{"class":1081},[1071,3347,1492],{"class":1085},[1071,3349,2893],{"class":1081},[1071,3351,2896],{"class":1081},[1071,3353,2899],{"class":1081},[1071,3355,1531],{"class":1085},[1071,3357,973],{"class":1081},[1071,3359,1502],{"class":1085},[1071,3361,1346],{"class":1081},[1071,3363,2896],{"class":1081},[1071,3365,1356],{"class":1221},[1071,3367,1215],{"class":1081},[1071,3369,3370,3372,3374,3376,3378,3380,3382,3384,3386,3388,3390,3392,3394,3396],{"class":1073,"line":1272},[1071,3371,1619],{"class":1077},[1071,3373,1367],{"class":1081},[1071,3375,1139],{"class":1199},[1071,3377,1212],{"class":1221},[1071,3379,1233],{"class":1081},[1071,3381,2751],{"class":1098},[1071,3383,1233],{"class":1081},[1071,3385,1136],{"class":1081},[1071,3387,2791],{"class":1081},[1071,3389,1136],{"class":1081},[1071,3391,1095],{"class":1081},[1071,3393,2941],{"class":1098},[1071,3395,1233],{"class":1081},[1071,3397,1326],{"class":1221},[1071,3399,3400],{"class":1073,"line":1329},[1071,3401,1640],{"class":1081},[1071,3403,3404],{"class":1073,"line":1361},[1071,3405,1404],{"class":1081},[1071,3407,3408],{"class":1073,"line":1401},[1071,3409,1410],{"class":1081},[1071,3411,3412,3414],{"class":1073,"line":1407},[1071,3413,1657],{"class":1081},[1071,3415,1326],{"class":1085},[1071,3417,3418],{"class":1073,"line":1413},[1071,3419,1183],{"emptyLinePlaceholder":1182},[1071,3421,3422,3424,3426,3428,3430,3432,3434,3436,3438,3440,3442,3444,3446,3448,3450,3452,3454,3456,3458,3460,3462,3464,3466,3468,3470,3472,3474,3477,3479,3481,3483],{"class":1073,"line":1423},[1071,3423,1825],{"class":1077},[1071,3425,1260],{"class":1085},[1071,3427,973],{"class":1081},[1071,3429,1291],{"class":1199},[1071,3431,1202],{"class":1081},[1071,3433,2734],{"class":1205},[1071,3435,1209],{"class":1081},[1071,3437,1212],{"class":1085},[1071,3439,1233],{"class":1081},[1071,3441,2751],{"class":1098},[1071,3443,1233],{"class":1081},[1071,3445,1009],{"class":1085},[1071,3447,973],{"class":1081},[1071,3449,1852],{"class":1199},[1071,3451,1212],{"class":1085},[1071,3453,1233],{"class":1081},[1071,3455,3015],{"class":1098},[1071,3457,1233],{"class":1081},[1071,3459,1136],{"class":1081},[1071,3461,1082],{"class":1081},[1071,3463,2138],{"class":1221},[1071,3465,1225],{"class":1081},[1071,3467,1095],{"class":1081},[1071,3469,3015],{"class":1098},[1071,3471,1233],{"class":1081},[1071,3473,1136],{"class":1081},[1071,3475,3476],{"class":1221}," total",[1071,3478,1225],{"class":1081},[1071,3480,2168],{"class":1565},[1071,3482,1089],{"class":1081},[1071,3484,1326],{"class":1085},[1071,3486,3487,3489,3491,3493,3495,3497,3499,3501,3503,3505,3507,3509,3511,3513,3515,3517,3519,3521,3523,3525,3527,3529,3531,3533,3535,3537,3539,3541,3543,3545,3547],{"class":1073,"line":1453},[1071,3488,1825],{"class":1077},[1071,3490,1260],{"class":1085},[1071,3492,973],{"class":1081},[1071,3494,1291],{"class":1199},[1071,3496,1202],{"class":1081},[1071,3498,2734],{"class":1205},[1071,3500,1209],{"class":1081},[1071,3502,1212],{"class":1085},[1071,3504,1233],{"class":1081},[1071,3506,2751],{"class":1098},[1071,3508,1233],{"class":1081},[1071,3510,1009],{"class":1085},[1071,3512,973],{"class":1081},[1071,3514,1852],{"class":1199},[1071,3516,1212],{"class":1085},[1071,3518,1233],{"class":1081},[1071,3520,3015],{"class":1098},[1071,3522,1233],{"class":1081},[1071,3524,1136],{"class":1081},[1071,3526,1082],{"class":1081},[1071,3528,2138],{"class":1221},[1071,3530,1225],{"class":1081},[1071,3532,1095],{"class":1081},[1071,3534,3015],{"class":1098},[1071,3536,1233],{"class":1081},[1071,3538,1136],{"class":1081},[1071,3540,3476],{"class":1221},[1071,3542,1225],{"class":1081},[1071,3544,2245],{"class":1565},[1071,3546,1089],{"class":1081},[1071,3548,1326],{"class":1085},[1071,3550,3551],{"class":1073,"line":1472},[1071,3552,3553],{"class":1744},"\u002F\u002F → throws RecordLockedError: \"Cannot modify receipts\u002Fr1 — locked by guard:\n",[1071,3555,3556],{"class":1073,"line":1512},[1071,3557,3558],{"class":1744},"\u002F\u002F   append-only collection. Use withTransactions({ amendment: true, reason })\n",[1071,3560,3561],{"class":1073,"line":1577},[1071,3562,3034],{"class":1744},[946,3564,3565,3566,3568],{},"Omitting ",[949,3567,3188],{}," leaves the empty-allow override in place.",[1794,3570,3572],{"id":3571},"transitionguardopts",[949,3573,3574],{},"transitionGuard(opts)",[946,3576,3577,3580,3581,3583,3584,3587,3588,3590],{},[949,3578,3579],{},"transitionGuard"," generalizes ",[949,3582,3185],{}," from \"any state → locked\"\nto an arbitrary state graph. Declare the allowed arcs once; every write\nthat moves the lifecycle field along an undeclared edge throws\n",[949,3585,3586],{},"IllegalTransitionError",". It's sugar over ",[949,3589,2729],{}," (no new write-path\ncode) and inherits the same ledgered amendment override.",[1062,3592,3594],{"className":1064,"code":3593,"language":1066,"meta":1067,"style":1067},"transitionGuard\u003CSale>({\n  collection: 'sales', field: 'status',\n  transitions: {                          \u002F\u002F absence of an arc = forbidden\n    draft: ['to_verify', 'cancelled'],\n    to_verify: ['proforma', 'draft', 'cancelled'],\n    proforma: ['invoiced', 'cancelled'],\n    invoiced: ['paid'], paid: [], cancelled: [],\n  },\n  initial: ['draft', 'to_verify'],        \u002F\u002F allowed status on insert (default: any)\n  allowIdempotent: true,                  \u002F\u002F same→same write allowed (default true)\n})\n\nawait vault.collection\u003CSale>('sales').put('s1', { id: 's1', status: 'invoiced' })\nawait vault.collection\u003CSale>('sales').put('s1', { id: 's1', status: 'draft' })\n\u002F\u002F → throws IllegalTransitionError: 'Cannot transition sales\u002Fs1 from \"invoiced\"\n\u002F\u002F   to \"draft\" — not a declared arc. Use withTransactions({ amendment: true,\n\u002F\u002F   reason }) with admin\u002Fowner role to override.'\n",[949,3595,3596,3611,3639,3651,3680,3717,3745,3783,3787,3817,3831,3837,3841,3910,3978,3983,3988],{"__ignoreMap":1067},[1071,3597,3598,3600,3602,3605,3607,3609],{"class":1073,"line":1074},[1071,3599,3579],{"class":1199},[1071,3601,1202],{"class":1081},[1071,3603,3604],{"class":1205},"Sale",[1071,3606,1209],{"class":1081},[1071,3608,1212],{"class":1085},[1071,3610,1215],{"class":1081},[1071,3612,3613,3615,3617,3619,3622,3624,3626,3629,3631,3633,3635,3637],{"class":1073,"line":1105},[1071,3614,1222],{"class":1221},[1071,3616,1225],{"class":1081},[1071,3618,1095],{"class":1081},[1071,3620,3621],{"class":1098},"sales",[1071,3623,1233],{"class":1081},[1071,3625,1136],{"class":1081},[1071,3627,3628],{"class":1221}," field",[1071,3630,1225],{"class":1081},[1071,3632,1095],{"class":1081},[1071,3634,1343],{"class":1098},[1071,3636,1233],{"class":1081},[1071,3638,1236],{"class":1081},[1071,3640,3641,3644,3646,3648],{"class":1073,"line":1126},[1071,3642,3643],{"class":1221},"  transitions",[1071,3645,1225],{"class":1081},[1071,3647,1082],{"class":1081},[1071,3649,3650],{"class":1744},"                          \u002F\u002F absence of an arc = forbidden\n",[1071,3652,3653,3656,3658,3660,3662,3665,3667,3669,3671,3674,3676,3678],{"class":1073,"line":1158},[1071,3654,3655],{"class":1221},"    draft",[1071,3657,1225],{"class":1081},[1071,3659,1431],{"class":1085},[1071,3661,1233],{"class":1081},[1071,3663,3664],{"class":1098},"to_verify",[1071,3666,1233],{"class":1081},[1071,3668,1136],{"class":1081},[1071,3670,1095],{"class":1081},[1071,3672,3673],{"class":1098},"cancelled",[1071,3675,1233],{"class":1081},[1071,3677,1448],{"class":1085},[1071,3679,1236],{"class":1081},[1071,3681,3682,3685,3687,3689,3691,3694,3696,3698,3700,3703,3705,3707,3709,3711,3713,3715],{"class":1073,"line":1179},[1071,3683,3684],{"class":1221},"    to_verify",[1071,3686,1225],{"class":1081},[1071,3688,1431],{"class":1085},[1071,3690,1233],{"class":1081},[1071,3692,3693],{"class":1098},"proforma",[1071,3695,1233],{"class":1081},[1071,3697,1136],{"class":1081},[1071,3699,1095],{"class":1081},[1071,3701,3702],{"class":1098},"draft",[1071,3704,1233],{"class":1081},[1071,3706,1136],{"class":1081},[1071,3708,1095],{"class":1081},[1071,3710,3673],{"class":1098},[1071,3712,1233],{"class":1081},[1071,3714,1448],{"class":1085},[1071,3716,1236],{"class":1081},[1071,3718,3719,3722,3724,3726,3728,3731,3733,3735,3737,3739,3741,3743],{"class":1073,"line":1186},[1071,3720,3721],{"class":1221},"    proforma",[1071,3723,1225],{"class":1081},[1071,3725,1431],{"class":1085},[1071,3727,1233],{"class":1081},[1071,3729,3730],{"class":1098},"invoiced",[1071,3732,1233],{"class":1081},[1071,3734,1136],{"class":1081},[1071,3736,1095],{"class":1081},[1071,3738,3673],{"class":1098},[1071,3740,1233],{"class":1081},[1071,3742,1448],{"class":1085},[1071,3744,1236],{"class":1081},[1071,3746,3747,3750,3752,3754,3756,3758,3760,3762,3764,3767,3769,3772,3774,3777,3779,3781],{"class":1073,"line":1218},[1071,3748,3749],{"class":1221},"    invoiced",[1071,3751,1225],{"class":1081},[1071,3753,1431],{"class":1085},[1071,3755,1233],{"class":1081},[1071,3757,1940],{"class":1098},[1071,3759,1233],{"class":1081},[1071,3761,1448],{"class":1085},[1071,3763,1136],{"class":1081},[1071,3765,3766],{"class":1221}," paid",[1071,3768,1225],{"class":1081},[1071,3770,3771],{"class":1085}," []",[1071,3773,1136],{"class":1081},[1071,3775,3776],{"class":1221}," cancelled",[1071,3778,1225],{"class":1081},[1071,3780,3771],{"class":1085},[1071,3782,1236],{"class":1081},[1071,3784,3785],{"class":1073,"line":1239},[1071,3786,1410],{"class":1081},[1071,3788,3789,3792,3794,3796,3798,3800,3802,3804,3806,3808,3810,3812,3814],{"class":1073,"line":1272},[1071,3790,3791],{"class":1221},"  initial",[1071,3793,1225],{"class":1081},[1071,3795,1431],{"class":1085},[1071,3797,1233],{"class":1081},[1071,3799,3702],{"class":1098},[1071,3801,1233],{"class":1081},[1071,3803,1136],{"class":1081},[1071,3805,1095],{"class":1081},[1071,3807,3664],{"class":1098},[1071,3809,1233],{"class":1081},[1071,3811,1448],{"class":1085},[1071,3813,1136],{"class":1081},[1071,3815,3816],{"class":1744},"        \u002F\u002F allowed status on insert (default: any)\n",[1071,3818,3819,3822,3824,3826,3828],{"class":1073,"line":1329},[1071,3820,3821],{"class":1221},"  allowIdempotent",[1071,3823,1225],{"class":1081},[1071,3825,2326],{"class":2325},[1071,3827,1136],{"class":1081},[1071,3829,3830],{"class":1744},"                  \u002F\u002F same→same write allowed (default true)\n",[1071,3832,3833,3835],{"class":1073,"line":1361},[1071,3834,1657],{"class":1081},[1071,3836,1326],{"class":1085},[1071,3838,3839],{"class":1073,"line":1401},[1071,3840,1183],{"emptyLinePlaceholder":1182},[1071,3842,3843,3845,3847,3849,3851,3853,3855,3857,3859,3861,3863,3865,3867,3869,3871,3873,3875,3878,3880,3882,3884,3886,3888,3890,3892,3894,3896,3898,3900,3902,3904,3906,3908],{"class":1073,"line":1407},[1071,3844,1825],{"class":1077},[1071,3846,1260],{"class":1085},[1071,3848,973],{"class":1081},[1071,3850,1291],{"class":1199},[1071,3852,1202],{"class":1081},[1071,3854,3604],{"class":1205},[1071,3856,1209],{"class":1081},[1071,3858,1212],{"class":1085},[1071,3860,1233],{"class":1081},[1071,3862,3621],{"class":1098},[1071,3864,1233],{"class":1081},[1071,3866,1009],{"class":1085},[1071,3868,973],{"class":1081},[1071,3870,1852],{"class":1199},[1071,3872,1212],{"class":1085},[1071,3874,1233],{"class":1081},[1071,3876,3877],{"class":1098},"s1",[1071,3879,1233],{"class":1081},[1071,3881,1136],{"class":1081},[1071,3883,1082],{"class":1081},[1071,3885,2138],{"class":1221},[1071,3887,1225],{"class":1081},[1071,3889,1095],{"class":1081},[1071,3891,3877],{"class":1098},[1071,3893,1233],{"class":1081},[1071,3895,1136],{"class":1081},[1071,3897,2151],{"class":1221},[1071,3899,1225],{"class":1081},[1071,3901,1095],{"class":1081},[1071,3903,3730],{"class":1098},[1071,3905,1233],{"class":1081},[1071,3907,1089],{"class":1081},[1071,3909,1326],{"class":1085},[1071,3911,3912,3914,3916,3918,3920,3922,3924,3926,3928,3930,3932,3934,3936,3938,3940,3942,3944,3946,3948,3950,3952,3954,3956,3958,3960,3962,3964,3966,3968,3970,3972,3974,3976],{"class":1073,"line":1413},[1071,3913,1825],{"class":1077},[1071,3915,1260],{"class":1085},[1071,3917,973],{"class":1081},[1071,3919,1291],{"class":1199},[1071,3921,1202],{"class":1081},[1071,3923,3604],{"class":1205},[1071,3925,1209],{"class":1081},[1071,3927,1212],{"class":1085},[1071,3929,1233],{"class":1081},[1071,3931,3621],{"class":1098},[1071,3933,1233],{"class":1081},[1071,3935,1009],{"class":1085},[1071,3937,973],{"class":1081},[1071,3939,1852],{"class":1199},[1071,3941,1212],{"class":1085},[1071,3943,1233],{"class":1081},[1071,3945,3877],{"class":1098},[1071,3947,1233],{"class":1081},[1071,3949,1136],{"class":1081},[1071,3951,1082],{"class":1081},[1071,3953,2138],{"class":1221},[1071,3955,1225],{"class":1081},[1071,3957,1095],{"class":1081},[1071,3959,3877],{"class":1098},[1071,3961,1233],{"class":1081},[1071,3963,1136],{"class":1081},[1071,3965,2151],{"class":1221},[1071,3967,1225],{"class":1081},[1071,3969,1095],{"class":1081},[1071,3971,3702],{"class":1098},[1071,3973,1233],{"class":1081},[1071,3975,1089],{"class":1081},[1071,3977,1326],{"class":1085},[1071,3979,3980],{"class":1073,"line":1423},[1071,3981,3982],{"class":1744},"\u002F\u002F → throws IllegalTransitionError: 'Cannot transition sales\u002Fs1 from \"invoiced\"\n",[1071,3984,3985],{"class":1073,"line":1453},[1071,3986,3987],{"class":1744},"\u002F\u002F   to \"draft\" — not a declared arc. Use withTransactions({ amendment: true,\n",[1071,3989,3990],{"class":1073,"line":1472},[1071,3991,3992],{"class":1744},"\u002F\u002F   reason }) with admin\u002Fowner role to override.'\n",[993,3994,3995,4018,4036,4050],{},[996,3996,3997,1027,4000,4003,4004,4007,4008,4011,4012,4014,4015,973],{},[953,3998,3999],{},"Insert",[949,4001,4002],{},"existing === null","): ",[949,4005,4006],{},"incoming[field]"," must be in ",[949,4009,4010],{},"initial","\n(any value when ",[949,4013,4010],{}," is omitted); a violation reports ",[949,4016,4017],{},"from: '(none)'",[996,4019,4020,4023,4024,4027,4028,4031,4032,4035],{},[953,4021,4022],{},"Update",": the arc ",[949,4025,4026],{},"(existing[field] → incoming[field])"," must be a\ndeclared edge, else ",[949,4029,4030],{},"IllegalTransitionError(collection, id, from, to)",".\nA state absent from the map (or mapped to ",[949,4033,4034],{},"[]",") is terminal.",[996,4037,4038,4041,4042,4045,4046,4049],{},[953,4039,4040],{},"Idempotent",": a same-state write passes when ",[949,4043,4044],{},"allowIdempotent"," (default\n",[949,4047,4048],{},"true","), so a put that changes other fields without moving state is fine.",[996,4051,4052,4055,4056,4058,4059,4061,4062,4064],{},[953,4053,4054],{},"Override",": an ",[949,4057,963],{}," tx by an authorized role skips the check and\nis ledgered — ",[949,4060,3185],{}," is the WORM special case (every state → ",[949,4063,4034],{},").",[1794,4066,4068],{"id":4067},"amendment-flow","Amendment flow",[1062,4070,4075],{"className":4071,"code":4073,"language":4074},[4072],"language-text","db.transaction({ amendment: true, reason }, async tx => {\n  tx.vault('books').collection('lines').put(...)\n  tx.vault('books').collection('lines').put(...)\n})\n\n  → 1. Validate reason (ValidationError if missing\u002Fempty)\n  → 2. First tx.vault(name): role check (admin | owner | custodian) — AmendmentForbiddenError fail-fast\n  → 3. beginAmendment() on the touched vault's guard registry\n  → 4. Writes buffered — check + frozenFields skipped; each write records\n       (before, after) plus (id, vBefore, vAfter)\n  → 5. Invariant runs at commit, over the full change-set — a throw rolls\n       back every staged write as InvariantError\n  → 6. Audit entry appended to the ledger (op: 'amendment') if a\n       history strategy is configured\n","text",[949,4076,4073],{"__ignoreMap":1067},[1794,4078,4080],{"id":4079},"composition-order","Composition order",[946,4082,4083,4085,4086,2273,4089,4091,4092,4095],{},[949,4084,2729],{}," runs ",[953,4087,4088],{},"before encryption",[953,4090,1492],{}," the period-close check,\nas one stage in the ",[949,4093,4094],{},"Collection.put"," write pipeline:",[1062,4097,4100],{"className":4098,"code":4099,"language":4074},[4072],"Collection.put\n  1. Permission check        — can this user write this collection at all?\n  2. GuardRegistry.check     ← this service\n  3. Period-close check      — is the record's business date in a closed period?\n  4. Schema validation\n  5. i18n auto-translate\n  6. Ref enforcement\n  7. Encrypt + store.put     — plaintext never reaches this line's argument\n  8. Ledger append\n",[949,4101,4099],{"__ignoreMap":1067},[1794,4103,4105],{"id":4104},"errors","Errors",[946,4107,4108,4109,4112,4113,1225],{},"Five error classes, all extending ",[949,4110,4111],{},"NoydbError"," and re-exported from\n",[949,4114,1153],{},[993,4116,4117,4128,4134,4141,4147],{},[996,4118,4119,2687,4122,4124,4125,4127],{},[949,4120,4121],{},"RecordLockedError(collection, id, reason)",[949,4123,1803],{}," or ",[949,4126,2576],{}," threw",[996,4129,4130,4133],{},[949,4131,4132],{},"FieldFrozenError(collection, id, fields[])"," — a frozen field changed",[996,4135,4136,2687,4138,4140],{},[949,4137,4030],{},[949,4139,3579],{}," rejected an undeclared arc",[996,4142,4143,4146],{},[949,4144,4145],{},"InvariantError(message)"," — an amendment invariant rejected the change-set",[996,4148,4149,4152],{},[949,4150,4151],{},"AmendmentForbiddenError(userId, role)"," — caller's role can't open an amendment",[941,4154,4156],{"id":4155},"behavior-when-not-opted-in","Behavior when NOT opted in",[993,4158,4159,4165,4182],{},[996,4160,4161,4164],{},[949,4162,4163],{},"createNoydb({ guardStrategies: [...] })"," is the only way to register guards;\nwithout it, no guard fires for any collection",[996,4166,4167,4168,4171,4172,4174,4175,4177,4178,4181],{},"Amendment mode also needs at least one guard registered: opening\n",[949,4169,4170],{},"db.transaction({ amendment: true, reason })"," on a vault with no\n",[949,4173,1030],{}," throws ",[949,4176,3204],{}," as soon as the body calls\n",[949,4179,4180],{},"tx.vault(name)"," — fail-fast, before any write runs. If guards ARE\nregistered but a touched collection has none of its own, writes to that\ncollection still commit inside the amendment; they just don't contribute\nto any invariant",[996,4183,4184,4186,4187,4186,4189,4191,4192,4186,4194,4197,4198,4200],{},[949,4185,2569],{}," \u002F ",[949,4188,2606],{},[949,4190,3586],{}," \u002F\n",[949,4193,2624],{},[949,4195,4196],{},"AmendmentForbiddenError"," are still importable from\n",[949,4199,1153],{}," but are never thrown by core",[941,4202,4204],{"id":4203},"pairs-well-with","Pairs well with",[993,4206,4207,4215,4222],{},[996,4208,4209,4211,4212],{},[953,4210,876],{}," — amendment mode is layered on ",[949,4213,4214],{},"withTransactions",[996,4216,4217,4219,4220,1009],{},[953,4218,697],{}," — successful amendments append a multi-record summary entry to\nthe hash-chained ledger (per-record entries always fire from ",[949,4221,4094],{},[996,4223,4224,4226,4227,4230],{},[953,4225,776],{}," — guards run before the period seal, so a lock can preempt a\n",[949,4228,4229],{},"PeriodClosedError"," with a more specific reason",[941,4232,4234],{"id":4233},"edge-cases-limits","Edge cases & limits",[993,4236,4237,4251,4267,4275,4281,4301,4310],{},[996,4238,4239,4242,4243,4246,4247,4250],{},[953,4240,4241],{},"Guards see the pre-schema-validation incoming record."," If a schema\nvalidator coerces values (trims strings, applies defaults), the guard\nobserves the raw user-supplied shape; the stored shape is post-coercion.\nGuards should only consume fields declared in ",[949,4244,4245],{},"frozenFields.fields"," or\nread via ",[949,4248,4249],{},"ctx.vault"," — those paths are stable across schema transforms.",[996,4252,4253,1037,4258,4260,4261,4263,4264,4266],{},[953,4254,4255,4257],{},[949,4256,1803],{}," never fires on delete.",[949,4259,2636],{}," runs only on\n",[949,4262,1852],{}," (insert + update); ",[949,4265,2644],{}," is the dedicated\ndelete-time hook, with the currently-persisted record as its argument.",[996,4268,4269,4274],{},[953,4270,4271,4273],{},[949,4272,3008],{}," of a non-existent record is a no-op."," Guards are not consulted\nin that case; the call returns without error.",[996,4276,4277,4280],{},[953,4278,4279],{},"Multiple guards on the same collection"," run in registration order;\nfirst throw wins (short-circuits remaining guards).",[996,4282,4283,4286,4287,4290,4291,4294,4295,1045,4297,1049,4299,973],{},[953,4284,4285],{},"Amendment authorization is declarative-plus-enforced."," The\n",[949,4288,4289],{},"amendment.roles"," field on a guard is documentation for readers of the\nconfig — the actual check is the caller's\n",[978,4292,4293],{"href":2287},"keyring role",", which must be\n",[949,4296,1044],{},[949,4298,1048],{},[949,4300,1052],{},[996,4302,4303,4309],{},[953,4304,4305,4306,973],{},"Amendment audit append is conditional on ",[949,4307,4308],{},"historyStrategy"," Vaults\nwithout history still enforce amendment rules (role check + invariant +\nrollback) but skip the multi-record summary entry.",[996,4311,4312,4324,4325,4328],{},[953,4313,4314,2273,4317,4323],{},[949,4315,4316],{},"verifyBackupIntegrity",[978,4318,4320],{"href":4319},".\u002Fhistory",[949,4321,4322],{},"vault.at(timestamp)"," skip\namendment entries"," — amendment ledger entries carry no ",[949,4326,4327],{},"(collection, id)","\nof their own, so both the backup integrity check and point-in-time reads\ntreat them as opaque audit summaries rather than per-record state.",[1794,4330,4332],{"id":4331},"zero-knowledge-guarantee","Zero-knowledge guarantee",[946,4334,4335,4336,4339,4340,4343,4344,4346],{},"Guard functions run on plaintext, after the ",[978,4337,4338],{"href":980},"encryption key is\nunwrapped",", inside the client — never inside the\nstorage backend. The store sees only ciphertext envelopes. The\n",[949,4341,4342],{},"ReadOnlyVaultFacade"," passed as ",[949,4345,4249],{}," decrypts on access; no\nplaintext ever reaches the store.",[1794,4348,4350,4352],{"id":4349},"readonlyvaultfacade-surface",[949,4351,4342],{}," surface",[1062,4354,4356],{"className":1064,"code":4355,"language":1066,"meta":1067,"style":1067},"ctx.vault.collection\u003CT>(name).get(id)    \u002F\u002F single record\nctx.vault.collection\u003CT>(name).list()     \u002F\u002F every record (decrypts all)\nctx.vault.collection\u003CT>(name).query()    \u002F\u002F chainable read-only builder\n",[949,4357,4358,4391,4422],{"__ignoreMap":1067},[1071,4359,4360,4363,4365,4367,4369,4371,4373,4376,4378,4381,4383,4385,4388],{"class":1073,"line":1074},[1071,4361,4362],{"class":1085},"ctx",[1071,4364,973],{"class":1081},[1071,4366,2366],{"class":1085},[1071,4368,973],{"class":1081},[1071,4370,1291],{"class":1199},[1071,4372,1202],{"class":1081},[1071,4374,4375],{"class":1205},"T",[1071,4377,1209],{"class":1081},[1071,4379,4380],{"class":1085},"(name)",[1071,4382,973],{"class":1081},[1071,4384,1314],{"class":1199},[1071,4386,4387],{"class":1085},"(id)    ",[1071,4389,4390],{"class":1744},"\u002F\u002F single record\n",[1071,4392,4393,4395,4397,4399,4401,4403,4405,4407,4409,4411,4413,4416,4419],{"class":1073,"line":1105},[1071,4394,4362],{"class":1085},[1071,4396,973],{"class":1081},[1071,4398,2366],{"class":1085},[1071,4400,973],{"class":1081},[1071,4402,1291],{"class":1199},[1071,4404,1202],{"class":1081},[1071,4406,4375],{"class":1205},[1071,4408,1209],{"class":1081},[1071,4410,4380],{"class":1085},[1071,4412,973],{"class":1081},[1071,4414,4415],{"class":1199},"list",[1071,4417,4418],{"class":1085},"()     ",[1071,4420,4421],{"class":1744},"\u002F\u002F every record (decrypts all)\n",[1071,4423,4424,4426,4428,4430,4432,4434,4436,4438,4440,4442,4444,4447,4450],{"class":1073,"line":1126},[1071,4425,4362],{"class":1085},[1071,4427,973],{"class":1081},[1071,4429,2366],{"class":1085},[1071,4431,973],{"class":1081},[1071,4433,1291],{"class":1199},[1071,4435,1202],{"class":1081},[1071,4437,4375],{"class":1205},[1071,4439,1209],{"class":1081},[1071,4441,4380],{"class":1085},[1071,4443,973],{"class":1081},[1071,4445,4446],{"class":1199},"query",[1071,4448,4449],{"class":1085},"()    ",[1071,4451,4452],{"class":1744},"\u002F\u002F chainable read-only builder\n",[946,4454,4455,4458,4459,4462,4463,1045,4466,1045,4469,1045,4472,1236,4475,1045,4478,4480,4481,4186,4484,4487,4488,4491,4492,4495,4496,4499],{},[949,4456,4457],{},"query()"," returns the same ",[949,4460,4461],{},"Query\u003CT>"," builder used elsewhere in the\nlibrary. Its terminals (",[949,4464,4465],{},"toArray",[949,4467,4468],{},"first",[949,4470,4471],{},"count",[949,4473,4474],{},"aggregate",[949,4476,4477],{},"groupBy",[949,4479,727],{},") are read-only — there is no ",[949,4482,4483],{},".update()",[949,4485,4486],{},".delete()","\non a ",[949,4489,4490],{},"Query",". Prefer ",[949,4493,4494],{},".query().aggregate({ ... })"," over ",[949,4497,4498],{},".list()"," +\nmanual reduce when enforcing Σ-style invariants: only the records the\npredicate touches get materialised, and the aggregate path is the same\none used by the rest of the library.",[1062,4501,4503],{"className":1064,"code":4502,"language":1066,"meta":1067,"style":1067},"\u002F\u002F Σ-over-siblings invariant — payment-allocation sum must not exceed payment\nimport { withGuard, InvariantError } from '@noy-db\u002Fhub\u002Fguards'\nimport { sum } from '@noy-db\u002Fhub\u002Freduce'\n\nconst allocationGuard = withGuard\u003CAllocation>({\n  collection: 'allocations',\n  check: async (incoming, { vault, existing }) => {\n    const payment = await vault.collection\u003CPayment>('payments').get(incoming.paymentId)\n    const { total } = await vault\n      .collection\u003CAllocation>('allocations')\n      .query()\n      .where('paymentId', '==', incoming.paymentId)\n      .aggregate({ total: sum('appliedAmount') })\n      .run()\n    const otherTotal = total - (existing?.appliedAmount ?? 0)\n    if (otherTotal + incoming.appliedAmount > payment.amount) {\n      throw new InvariantError('allocation total would exceed payment amount')\n    }\n  },\n})\n\nawait vault.collection\u003CAllocation>('allocations').put('a1', {\n  id: 'a1', paymentId: 'p1', appliedAmount: 1_000,\n})\n\u002F\u002F → throws InvariantError: \"allocation total would exceed payment amount\"\n",[949,4504,4505,4510,4532,4551,4555,4577,4592,4620,4670,4687,4710,4719,4753,4784,4793,4821,4851,4870,4874,4878,4884,4888,4931,4969,4975],{"__ignoreMap":1067},[1071,4506,4507],{"class":1073,"line":1074},[1071,4508,4509],{"class":1744},"\u002F\u002F Σ-over-siblings invariant — payment-allocation sum must not exceed payment\n",[1071,4511,4512,4514,4516,4518,4520,4522,4524,4526,4528,4530],{"class":1073,"line":1105},[1071,4513,1078],{"class":1077},[1071,4515,1082],{"class":1081},[1071,4517,1133],{"class":1085},[1071,4519,1136],{"class":1081},[1071,4521,1144],{"class":1085},[1071,4523,1089],{"class":1081},[1071,4525,1092],{"class":1077},[1071,4527,1095],{"class":1081},[1071,4529,1153],{"class":1098},[1071,4531,1102],{"class":1081},[1071,4533,4534,4536,4538,4540,4542,4544,4546,4549],{"class":1073,"line":1126},[1071,4535,1078],{"class":1077},[1071,4537,1082],{"class":1081},[1071,4539,1478],{"class":1085},[1071,4541,1089],{"class":1081},[1071,4543,1092],{"class":1077},[1071,4545,1095],{"class":1081},[1071,4547,4548],{"class":1098},"@noy-db\u002Fhub\u002Freduce",[1071,4550,1102],{"class":1081},[1071,4552,4553],{"class":1073,"line":1158},[1071,4554,1183],{"emptyLinePlaceholder":1182},[1071,4556,4557,4559,4562,4564,4566,4568,4571,4573,4575],{"class":1073,"line":1179},[1071,4558,1190],{"class":1189},[1071,4560,4561],{"class":1085}," allocationGuard ",[1071,4563,1196],{"class":1081},[1071,4565,1133],{"class":1199},[1071,4567,1202],{"class":1081},[1071,4569,4570],{"class":1205},"Allocation",[1071,4572,1209],{"class":1081},[1071,4574,1212],{"class":1085},[1071,4576,1215],{"class":1081},[1071,4578,4579,4581,4583,4585,4588,4590],{"class":1073,"line":1186},[1071,4580,1222],{"class":1221},[1071,4582,1225],{"class":1081},[1071,4584,1095],{"class":1081},[1071,4586,4587],{"class":1098},"allocations",[1071,4589,1233],{"class":1081},[1071,4591,1236],{"class":1081},[1071,4593,4594,4596,4598,4600,4602,4604,4606,4608,4610,4612,4614,4616,4618],{"class":1073,"line":1218},[1071,4595,1242],{"class":1199},[1071,4597,1225],{"class":1081},[1071,4599,1247],{"class":1189},[1071,4601,1027],{"class":1081},[1071,4603,1253],{"class":1252},[1071,4605,1136],{"class":1081},[1071,4607,1082],{"class":1081},[1071,4609,1260],{"class":1252},[1071,4611,1136],{"class":1081},[1071,4613,2043],{"class":1252},[1071,4615,1263],{"class":1081},[1071,4617,1266],{"class":1189},[1071,4619,1269],{"class":1081},[1071,4621,4622,4624,4627,4629,4631,4633,4635,4637,4639,4642,4644,4646,4648,4651,4653,4655,4657,4659,4661,4663,4665,4668],{"class":1073,"line":1239},[1071,4623,1275],{"class":1189},[1071,4625,4626],{"class":1085}," payment",[1071,4628,1281],{"class":1081},[1071,4630,1284],{"class":1077},[1071,4632,1260],{"class":1085},[1071,4634,973],{"class":1081},[1071,4636,1291],{"class":1199},[1071,4638,1202],{"class":1081},[1071,4640,4641],{"class":1205},"Payment",[1071,4643,1209],{"class":1081},[1071,4645,1212],{"class":1221},[1071,4647,1233],{"class":1081},[1071,4649,4650],{"class":1098},"payments",[1071,4652,1233],{"class":1081},[1071,4654,1009],{"class":1221},[1071,4656,973],{"class":1081},[1071,4658,1314],{"class":1199},[1071,4660,1212],{"class":1221},[1071,4662,1253],{"class":1085},[1071,4664,973],{"class":1081},[1071,4666,4667],{"class":1085},"paymentId",[1071,4669,1326],{"class":1221},[1071,4671,4672,4674,4676,4678,4680,4682,4684],{"class":1073,"line":1272},[1071,4673,1275],{"class":1189},[1071,4675,1082],{"class":1081},[1071,4677,3476],{"class":1085},[1071,4679,1089],{"class":1081},[1071,4681,1281],{"class":1081},[1071,4683,1284],{"class":1077},[1071,4685,4686],{"class":1085}," vault\n",[1071,4688,4689,4692,4694,4696,4698,4700,4702,4704,4706,4708],{"class":1073,"line":1329},[1071,4690,4691],{"class":1081},"      .",[1071,4693,1291],{"class":1199},[1071,4695,1202],{"class":1081},[1071,4697,4570],{"class":1205},[1071,4699,1209],{"class":1081},[1071,4701,1212],{"class":1221},[1071,4703,1233],{"class":1081},[1071,4705,4587],{"class":1098},[1071,4707,1233],{"class":1081},[1071,4709,1326],{"class":1221},[1071,4711,4712,4714,4716],{"class":1073,"line":1361},[1071,4713,4691],{"class":1081},[1071,4715,4446],{"class":1199},[1071,4717,4718],{"class":1221},"()\n",[1071,4720,4721,4723,4726,4728,4730,4732,4734,4736,4738,4741,4743,4745,4747,4749,4751],{"class":1073,"line":1401},[1071,4722,4691],{"class":1081},[1071,4724,4725],{"class":1199},"where",[1071,4727,1212],{"class":1221},[1071,4729,1233],{"class":1081},[1071,4731,4667],{"class":1098},[1071,4733,1233],{"class":1081},[1071,4735,1136],{"class":1081},[1071,4737,1095],{"class":1081},[1071,4739,4740],{"class":1098},"==",[1071,4742,1233],{"class":1081},[1071,4744,1136],{"class":1081},[1071,4746,1382],{"class":1085},[1071,4748,973],{"class":1081},[1071,4750,4667],{"class":1085},[1071,4752,1326],{"class":1221},[1071,4754,4755,4757,4759,4761,4763,4765,4767,4769,4771,4773,4776,4778,4780,4782],{"class":1073,"line":1407},[1071,4756,4691],{"class":1081},[1071,4758,4474],{"class":1199},[1071,4760,1212],{"class":1221},[1071,4762,2317],{"class":1081},[1071,4764,3476],{"class":1221},[1071,4766,1225],{"class":1081},[1071,4768,1478],{"class":1199},[1071,4770,1212],{"class":1221},[1071,4772,1233],{"class":1081},[1071,4774,4775],{"class":1098},"appliedAmount",[1071,4777,1233],{"class":1081},[1071,4779,1356],{"class":1221},[1071,4781,1657],{"class":1081},[1071,4783,1326],{"class":1221},[1071,4785,4786,4788,4791],{"class":1073,"line":1413},[1071,4787,4691],{"class":1081},[1071,4789,4790],{"class":1199},"run",[1071,4792,4718],{"class":1221},[1071,4794,4795,4797,4800,4802,4804,4807,4809,4811,4813,4815,4817,4819],{"class":1073,"line":1423},[1071,4796,1275],{"class":1189},[1071,4798,4799],{"class":1085}," otherTotal",[1071,4801,1281],{"class":1081},[1071,4803,3476],{"class":1085},[1071,4805,4806],{"class":1081}," -",[1071,4808,1027],{"class":1221},[1071,4810,2036],{"class":1085},[1071,4812,1340],{"class":1081},[1071,4814,4775],{"class":1085},[1071,4816,1562],{"class":1081},[1071,4818,1566],{"class":1565},[1071,4820,1326],{"class":1221},[1071,4822,4823,4825,4827,4830,4832,4834,4836,4838,4841,4843,4845,4847,4849],{"class":1073,"line":1453},[1071,4824,1332],{"class":1077},[1071,4826,1027],{"class":1221},[1071,4828,4829],{"class":1085},"otherTotal",[1071,4831,1541],{"class":1081},[1071,4833,1382],{"class":1085},[1071,4835,973],{"class":1081},[1071,4837,4775],{"class":1085},[1071,4839,4840],{"class":1081}," >",[1071,4842,4626],{"class":1085},[1071,4844,973],{"class":1081},[1071,4846,1004],{"class":1085},[1071,4848,1356],{"class":1221},[1071,4850,1215],{"class":1081},[1071,4852,4853,4855,4857,4859,4861,4863,4866,4868],{"class":1073,"line":1472},[1071,4854,1364],{"class":1077},[1071,4856,1367],{"class":1081},[1071,4858,1144],{"class":1199},[1071,4860,1212],{"class":1221},[1071,4862,1233],{"class":1081},[1071,4864,4865],{"class":1098},"allocation total would exceed payment amount",[1071,4867,1233],{"class":1081},[1071,4869,1326],{"class":1221},[1071,4871,4872],{"class":1073,"line":1512},[1071,4873,1404],{"class":1081},[1071,4875,4876],{"class":1073,"line":1577},[1071,4877,1410],{"class":1081},[1071,4879,4880,4882],{"class":1073,"line":1616},[1071,4881,1657],{"class":1081},[1071,4883,1326],{"class":1085},[1071,4885,4886],{"class":1073,"line":1637},[1071,4887,1183],{"emptyLinePlaceholder":1182},[1071,4889,4890,4892,4894,4896,4898,4900,4902,4904,4906,4908,4910,4912,4914,4916,4918,4920,4922,4925,4927,4929],{"class":1073,"line":1643},[1071,4891,1825],{"class":1077},[1071,4893,1260],{"class":1085},[1071,4895,973],{"class":1081},[1071,4897,1291],{"class":1199},[1071,4899,1202],{"class":1081},[1071,4901,4570],{"class":1205},[1071,4903,1209],{"class":1081},[1071,4905,1212],{"class":1085},[1071,4907,1233],{"class":1081},[1071,4909,4587],{"class":1098},[1071,4911,1233],{"class":1081},[1071,4913,1009],{"class":1085},[1071,4915,973],{"class":1081},[1071,4917,1852],{"class":1199},[1071,4919,1212],{"class":1085},[1071,4921,1233],{"class":1081},[1071,4923,4924],{"class":1098},"a1",[1071,4926,1233],{"class":1081},[1071,4928,1136],{"class":1081},[1071,4930,1269],{"class":1081},[1071,4932,4933,4935,4937,4939,4941,4943,4945,4948,4950,4952,4955,4957,4959,4962,4964,4967],{"class":1073,"line":1649},[1071,4934,1870],{"class":1221},[1071,4936,1225],{"class":1081},[1071,4938,1095],{"class":1081},[1071,4940,4924],{"class":1098},[1071,4942,1233],{"class":1081},[1071,4944,1136],{"class":1081},[1071,4946,4947],{"class":1221}," paymentId",[1071,4949,1225],{"class":1081},[1071,4951,1095],{"class":1081},[1071,4953,4954],{"class":1098},"p1",[1071,4956,1233],{"class":1081},[1071,4958,1136],{"class":1081},[1071,4960,4961],{"class":1221}," appliedAmount",[1071,4963,1225],{"class":1081},[1071,4965,4966],{"class":1565}," 1_000",[1071,4968,1236],{"class":1081},[1071,4970,4971,4973],{"class":1073,"line":1654},[1071,4972,1657],{"class":1081},[1071,4974,1326],{"class":1085},[1071,4976,4977],{"class":1073,"line":1662},[1071,4978,4979],{"class":1744},"\u002F\u002F → throws InvariantError: \"allocation total would exceed payment amount\"\n",[946,4981,4982,4983,4986,4987,4989],{},"Aggregates require the ",[949,4984,4985],{},"reduceStrategy: withReduce()"," opt-in (the\nsame opt-in everything else in the query DSL respects) — ",[949,4988,4457],{},"\nitself is always present on the facade.",[1794,4991,4993],{"id":4992},"audit-entry-shape","Audit-entry shape",[1062,4995,4997],{"className":1064,"code":4996,"language":1066,"meta":1067,"style":1067},"{\n  op: 'amendment',\n  actor: 'alice',\n  ts: '2026-05-18T...',\n  collection: '',  \u002F\u002F amendment is multi-record; collection\u002Fid are empty\n  id: '',\n  version: 0,\n  payloadHash: '',  \u002F\u002F per-record entries carry real hashes\n  amendment: {\n    reason: 'correct split between travel and meals',\n    role: 'admin',\n    changes: [\n      { collection: 'disbursements', id: 'd1', vBefore: 2, vAfter: 3 },\n      { collection: 'disbursements', id: 'd2', vBefore: 1, vAfter: 2 },\n    ],\n    invariantsPassed: ['disbursements'],\n  },\n}\n",[949,4998,4999,5003,5018,5033,5049,5062,5072,5083,5097,5105,5121,5136,5146,5197,5243,5250,5269,5273],{"__ignoreMap":1067},[1071,5000,5001],{"class":1073,"line":1074},[1071,5002,1215],{"class":1081},[1071,5004,5005,5008,5010,5012,5014,5016],{"class":1073,"line":1105},[1071,5006,5007],{"class":1205},"  op",[1071,5009,1225],{"class":1081},[1071,5011,1095],{"class":1081},[1071,5013,963],{"class":1098},[1071,5015,1233],{"class":1081},[1071,5017,1236],{"class":1081},[1071,5019,5020,5023,5025,5027,5029,5031],{"class":1073,"line":1126},[1071,5021,5022],{"class":1205},"  actor",[1071,5024,1225],{"class":1081},[1071,5026,1095],{"class":1081},[1071,5028,1710],{"class":1098},[1071,5030,1233],{"class":1081},[1071,5032,1236],{"class":1081},[1071,5034,5035,5038,5040,5042,5045,5047],{"class":1073,"line":1158},[1071,5036,5037],{"class":1205},"  ts",[1071,5039,1225],{"class":1081},[1071,5041,1095],{"class":1081},[1071,5043,5044],{"class":1098},"2026-05-18T...",[1071,5046,1233],{"class":1081},[1071,5048,1236],{"class":1081},[1071,5050,5051,5053,5055,5057,5059],{"class":1073,"line":1179},[1071,5052,1222],{"class":1205},[1071,5054,1225],{"class":1081},[1071,5056,2791],{"class":1081},[1071,5058,1136],{"class":1081},[1071,5060,5061],{"class":1744},"  \u002F\u002F amendment is multi-record; collection\u002Fid are empty\n",[1071,5063,5064,5066,5068,5070],{"class":1073,"line":1186},[1071,5065,1870],{"class":1205},[1071,5067,1225],{"class":1081},[1071,5069,2791],{"class":1081},[1071,5071,1236],{"class":1081},[1071,5073,5074,5077,5079,5081],{"class":1073,"line":1218},[1071,5075,5076],{"class":1205},"  version",[1071,5078,1225],{"class":1081},[1071,5080,1566],{"class":1565},[1071,5082,1236],{"class":1081},[1071,5084,5085,5088,5090,5092,5094],{"class":1073,"line":1239},[1071,5086,5087],{"class":1205},"  payloadHash",[1071,5089,1225],{"class":1081},[1071,5091,2791],{"class":1081},[1071,5093,1136],{"class":1081},[1071,5095,5096],{"class":1744},"  \u002F\u002F per-record entries carry real hashes\n",[1071,5098,5099,5101,5103],{"class":1073,"line":1272},[1071,5100,1416],{"class":1205},[1071,5102,1225],{"class":1081},[1071,5104,1269],{"class":1081},[1071,5106,5107,5110,5112,5114,5117,5119],{"class":1073,"line":1329},[1071,5108,5109],{"class":1205},"    reason",[1071,5111,1225],{"class":1081},[1071,5113,1095],{"class":1081},[1071,5115,5116],{"class":1098},"correct split between travel and meals",[1071,5118,1233],{"class":1081},[1071,5120,1236],{"class":1081},[1071,5122,5123,5126,5128,5130,5132,5134],{"class":1073,"line":1361},[1071,5124,5125],{"class":1205},"    role",[1071,5127,1225],{"class":1081},[1071,5129,1095],{"class":1081},[1071,5131,1044],{"class":1098},[1071,5133,1233],{"class":1081},[1071,5135,1236],{"class":1081},[1071,5137,5138,5141,5143],{"class":1073,"line":1401},[1071,5139,5140],{"class":1205},"    changes",[1071,5142,1225],{"class":1081},[1071,5144,5145],{"class":1221}," [\n",[1071,5147,5148,5151,5154,5156,5158,5160,5162,5164,5166,5168,5170,5172,5174,5176,5179,5181,5184,5186,5189,5191,5194],{"class":1073,"line":1407},[1071,5149,5150],{"class":1081},"      {",[1071,5152,5153],{"class":1221}," collection",[1071,5155,1225],{"class":1081},[1071,5157,1095],{"class":1081},[1071,5159,1230],{"class":1098},[1071,5161,1233],{"class":1081},[1071,5163,1136],{"class":1081},[1071,5165,2138],{"class":1221},[1071,5167,1225],{"class":1081},[1071,5169,1095],{"class":1081},[1071,5171,1859],{"class":1098},[1071,5173,1233],{"class":1081},[1071,5175,1136],{"class":1081},[1071,5177,5178],{"class":1221}," vBefore",[1071,5180,1225],{"class":1081},[1071,5182,5183],{"class":1565}," 2",[1071,5185,1136],{"class":1081},[1071,5187,5188],{"class":1221}," vAfter",[1071,5190,1225],{"class":1081},[1071,5192,5193],{"class":1565}," 3",[1071,5195,5196],{"class":1081}," },\n",[1071,5198,5199,5201,5203,5205,5207,5209,5211,5213,5215,5217,5219,5222,5224,5226,5228,5230,5233,5235,5237,5239,5241],{"class":1073,"line":1413},[1071,5200,5150],{"class":1081},[1071,5202,5153],{"class":1221},[1071,5204,1225],{"class":1081},[1071,5206,1095],{"class":1081},[1071,5208,1230],{"class":1098},[1071,5210,1233],{"class":1081},[1071,5212,1136],{"class":1081},[1071,5214,2138],{"class":1221},[1071,5216,1225],{"class":1081},[1071,5218,1095],{"class":1081},[1071,5220,5221],{"class":1098},"d2",[1071,5223,1233],{"class":1081},[1071,5225,1136],{"class":1081},[1071,5227,5178],{"class":1221},[1071,5229,1225],{"class":1081},[1071,5231,5232],{"class":1565}," 1",[1071,5234,1136],{"class":1081},[1071,5236,5188],{"class":1221},[1071,5238,1225],{"class":1081},[1071,5240,5183],{"class":1565},[1071,5242,5196],{"class":1081},[1071,5244,5245,5248],{"class":1073,"line":1423},[1071,5246,5247],{"class":1221},"    ]",[1071,5249,1236],{"class":1081},[1071,5251,5252,5255,5257,5259,5261,5263,5265,5267],{"class":1073,"line":1453},[1071,5253,5254],{"class":1205},"    invariantsPassed",[1071,5256,1225],{"class":1081},[1071,5258,1431],{"class":1221},[1071,5260,1233],{"class":1081},[1071,5262,1230],{"class":1098},[1071,5264,1233],{"class":1081},[1071,5266,1448],{"class":1221},[1071,5268,1236],{"class":1081},[1071,5270,5271],{"class":1073,"line":1472},[1071,5272,1410],{"class":1081},[1071,5274,5275],{"class":1073,"line":1512},[1071,5276,5277],{"class":1081},"}\n",[946,5279,5280,5281,5284],{},"Visible via ",[949,5282,5283],{},"vault.ledger().entries()"," like every other ledger entry.",[1794,5286,5288],{"id":5287},"not-supported","Not supported",[993,5290,5291,5297,5306,5322,5334],{},[996,5292,5293,5296],{},[953,5294,5295],{},"Per-field amendment."," An amendment opens for a whole record write —\nthere's no way to amend only specific frozen fields while leaving the\nrest of a locked record's rule enforced.",[996,5298,5299,5302,5303,5305],{},[953,5300,5301],{},"Time-limited amendment windows."," An amendment transaction has no\nexpiry of its own; it's an ordinary transaction with the ",[949,5304,963],{}," flag\nset, open for as long as the transaction body runs.",[996,5307,5308,5311,5312,4186,5314,4186,5316,5318,5319,5321],{},[953,5309,5310],{},"Cross-vault guards."," A guard's ",[949,5313,1803],{},[949,5315,2576],{},[949,5317,3171],{}," reads\nonly its own vault through ",[949,5320,4249],{}," — it cannot read a different\nvault's collections.",[996,5323,5324,5333],{},[953,5325,5326,5327,4186,5330,973],{},"Guards on ",[949,5328,5329],{},"loadAll",[949,5331,5332],{},"saveAll"," Bulk load\u002Fsave bypasses the guard\npipeline entirely.",[996,5335,5336,1037,5339,5341],{},[953,5337,5338],{},"Per-guard role lists.",[949,5340,4289],{}," on a guard is documentation\nfor the reader — actual authorization is the single vault-wide keyring\nrole check described above, not a per-guard list.",[941,5343,5345],{"id":5344},"see-also","See also",[993,5347,5348,5357,5362,5367],{},[996,5349,5350,5353,5354],{},[978,5351,876],{"href":5352},".\u002Ftransactions"," — amendment mode's underlying ",[949,5355,5356],{},"db.transaction()",[996,5358,5359,5361],{},[978,5360,697],{"href":4319}," — the ledger that amendment entries append to",[996,5363,5364,5366],{},[978,5365,776],{"href":985}," — the period-close check guards run before",[996,5368,5369,5370,2273,5378,973],{},"Proven by showcases ",[978,5371,5375],{"href":5372,"rel":5373},"https:\u002F\u002Fgithub.com\u002Fnoy-db\u002Fdocs\u002Fblob\u002Fmain\u002Fshowcases\u002Fsrc\u002F79-with-guard.showcase.test.ts",[5374],"nofollow",[949,5376,5377],{},"79-with-guard",[978,5379,5382],{"href":5380,"rel":5381},"https:\u002F\u002Fgithub.com\u002Fnoy-db\u002Fdocs\u002Fblob\u002Fmain\u002Fshowcases\u002Fsrc\u002F101-transition-guard.showcase.test.ts",[5374],[949,5383,5384],{},"101-transition-guard",[5386,5387,5388],"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 .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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":1067,"searchDepth":1126,"depth":1126,"links":5390},[5391,5392,5393,5394,5395,5400,5411,5412,5413,5420],{"id":943,"depth":1105,"text":944},{"id":990,"depth":1105,"text":991},{"id":1018,"depth":1105,"text":1019},{"id":1059,"depth":1105,"text":1060},{"id":1791,"depth":1105,"text":1792,"children":5396},[5397,5398,5399],{"id":1796,"depth":1126,"text":1797},{"id":1927,"depth":1126,"text":1928},{"id":2266,"depth":1126,"text":2267},{"id":2524,"depth":1105,"text":2525,"children":5401},[5402,5404,5405,5407,5408,5409,5410],{"id":2650,"depth":1126,"text":5403},"onDelete bypass paths",{"id":2706,"depth":1126,"text":2707},{"id":3182,"depth":1126,"text":5406},"immutableGuard and amendmentInvariant",{"id":3571,"depth":1126,"text":3574},{"id":4067,"depth":1126,"text":4068},{"id":4079,"depth":1126,"text":4080},{"id":4104,"depth":1126,"text":4105},{"id":4155,"depth":1105,"text":4156},{"id":4203,"depth":1105,"text":4204},{"id":4233,"depth":1105,"text":4234,"children":5414},[5415,5416,5418,5419],{"id":4331,"depth":1126,"text":4332},{"id":4349,"depth":1126,"text":5417},"ReadOnlyVaultFacade surface",{"id":4992,"depth":1126,"text":4993},{"id":5287,"depth":1126,"text":5288},{"id":5344,"depth":1105,"text":5345},null,"Per-record locks, per-field freezes, and an audited amendment override for business rules stricter than a plain write permission.","md",{},"service",{"title":693,"description":5422},"stable","important","2KjkET4NCxgH_B44i7vRP6ki2Q8zzpuxASP-fr_TkyI",{"data":5431,"body":5432},{},{"type":5433,"children":5434},"root",[5435],{"type":5436,"tag":946,"props":5437,"children":5438},"element",{},[5439],{"type":5436,"tag":949,"props":5440,"children":5442},{"className":5441},[],[5443],{"type":4074,"value":1153},{"data":5445,"body":5446},{},{"type":5433,"children":5447},[5448],{"type":5436,"tag":946,"props":5449,"children":5450},{},[5451],{"type":5436,"tag":949,"props":5452,"children":5454},{"className":5453},[],[5455],{"type":4074,"value":5456},"withGuard()",{"data":5458,"body":5459},{},{"type":5433,"children":5460},[5461],{"type":5436,"tag":946,"props":5462,"children":5463},{},[5464],{"type":5436,"tag":949,"props":5465,"children":5467},{"className":5466},[],[5468],{"type":4074,"value":5469},"with-audit",{"data":5471,"body":5472},{},{"type":5433,"children":5473},[5474],{"type":5436,"tag":946,"props":5475,"children":5476},{},[5477],{"type":4074,"value":5478},"E — Time & Audit",{"data":5480,"body":5481},{},{"type":5433,"children":5482},[5483],{"type":5436,"tag":946,"props":5484,"children":5485},{},[5486],{"type":4074,"value":5487},"~700 (off-bundle when not opted in)",1791896587388]