@byok-sdk/core 0.33.0 → 0.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/tenant.ts","../src/principals.ts","../src/time.ts","../src/mailbox.ts","../src/board.ts","../src/truth.ts","../src/presence.ts","../src/blob.ts","../src/quota.ts","../src/capabilities.ts","../src/skill-pack.ts","../src/stores.ts","../src/ports-contract.ts","../src/attestation.ts","../src/device-assertion.ts","../src/webcrypto.ts","../src/hpke.ts","../src/total-parse.ts","../src/sealed-provider-secret.ts","../src/agent-memory-intent.ts","../src/pairing.ts","../src/in-memory/storage-ledger.ts","../src/retention.ts","../src/in-memory/presence.ts","../src/in-memory/board.ts","../src/in-memory/archive-access.ts","../src/in-memory/mailbox.ts","../src/in-memory/blob.ts","../src/in-memory/quota.ts","../src/in-memory/skill-pack.ts","../src/in-memory/truth.ts","../src/in-memory/clock.ts","../src/in-memory/device-assertion-replay.ts","../src/in-memory/index.ts","../src/routine-schedule.ts"],"names":["hex","z","parts","DEFAULT_LIST_LIMIT","pending"],"mappings":";;AA+BO,IAAM,iBAAmB,CAC9B,wBAAA,CAA0B,0BAAA,CAC1B,uBAAA,CAAyB,0BACzB,wBAAA,CAA0B,0BAAA,CAE1B,iBAAA,CAAmB,mBAAA,CACnB,qBAAsB,sBAAA,CAGtB,uBAAA,CAAyB,yBAAA,CAGzB,8BAAA,CAAgC,iCAChC,sBAAA,CAAwB,wBAAA,CAGxB,sBAAA,CAAwB,wBAAA,CACxB,8BAA+B,+BAAA,CAO/B,0BAAA,CAA4B,4BAAA,CAK5B,qBAAA,CAAuB,wBACvB,qBAAA,CAAuB,uBAAA,CACvB,yBAAA,CAA2B,2BAAA,CAC3B,sCAAuC,uCAAA,CAGvC,yBAAA,CAA2B,2BAAA,CAC3B,yBAAA,CAA2B,4BAC3B,gCAAA,CAAkC,kCAAA,CAClC,qBAAA,CAAuB,uBAAA,CAGvB,qBAAsB,sBAAA,CACtB,iBAAA,CAAmB,mBAAA,CACnB,wBAAA,CAA0B,2BAC1B,qBAAA,CAAuB,uBAAA,CACvB,oBAAA,CAAsB,sBAAA,CACtB,eAAgB,gBAAA,CAGhB,sBAAA,CAAwB,wBAAA,CACxB,iBAAA,CAAmB,oBACnB,uBAAA,CAAyB,yBAAA,CAGzB,yBAAA,CAA2B,2BAAA,CAC3B,uBAAwB,wBAAA,CACxB,gBAAA,CAAkB,kBAAA,CAClB,iBAAA,CAAmB,oBAGnB,yBAAA,CAA2B,2BAAA,CAC3B,gBAAA,CAAkB,kBAAA,CAClB,qBAAsB,sBAAA,CAGtB,2BAAA,CAA6B,8BAC7B,oCAAA,CAAsC,sCAAA,CACtC,8BAA+B,+BAAA,CAC/B,wBAAA,CAA0B,0BAAA,CAC1B,sBAAA,CAAwB,yBACxB,2BAAA,CAA6B,6BAAA,CAC7B,0BAAA,CAA4B,4BAAA,CAC5B,wBAAyB,yBAAA,CAGzB,2BAAA,CAA6B,6BAAA,CAC7B,8BAAA,CAAgC,gCAClC,EAKO,IAAM,aAAA,CAAN,cAA4B,KAAM,CACvB,IAAA,CAEhB,WAAA,CAAY,IAAA,CAAqB,QAAiB,OAAA,CAAwB,CACxE,KAAA,CAAM,OAAA,CAAS,OAAO,CAAA,CACtB,IAAA,CAAK,IAAA,CAAO,eAAA,CACZ,KAAK,IAAA,CAAO,KACd,CACF,EAUO,IAAM,kBAAN,cAA0C,aAAc,CAC7C,OAAA,CACA,WAEhB,WAAA,CACE,IAAA,CACA,OAAA,CACA,OAAA,CACA,WACA,OAAA,CACA,CACA,KAAA,CAAM,IAAA,CAAM,QAAS,OAAO,CAAA,CAC5B,IAAA,CAAK,IAAA,CAAO,oBACZ,IAAA,CAAK,OAAA,CAAU,OAAA,CACf,IAAA,CAAK,WAAa,WACpB,CACF,EAGO,SAAS,YAAY,KAAA,CAAgB,IAAA,CAA8C,CACxF,GAAI,EAAE,KAAA,YAAiB,aAAA,CAAA,CAAgB,OAAO,KAAA,CAC9C,OAAO,OAAS,MAAA,EAAa,KAAA,CAAM,IAAA,GAAS,IAC9C,CAGO,SAAS,mBAAA,CACd,KAAA,CACA,IAAA,CACsC,CACtC,GAAI,EAAE,KAAA,YAAiB,iBAAA,CAAA,CAAoB,OAAO,KAAA,CAClD,OAAO,IAAA,GAAS,MAAA,EAAa,MAAM,IAAA,GAAS,IAC9C,CCnIO,IAAM,qBAAuB,IAQ7B,IAAM,oBAAA,CAAuB,KAa7B,SAAS,QAAA,CAAS,KAAA,CAAyB,CAChD,MAAM,UAAqB,KAAA,CAC3B,GAAI,OAAO,SAAA,GAAc,SAAU,CACjC,MAAM,IAAI,aAAA,CACR,oBACA,CAAA,qCAAA,EAAwC,OAAO,SAAS,CAAA,CAAA,CAC1D,CACF,CACA,GAAI,SAAA,CAAU,MAAA,GAAW,EAAG,CAC1B,MAAM,IAAI,aAAA,CAAc,oBAAqB,8BAA8B,CAC7E,CACA,GAAI,UAAU,IAAA,EAAK,GAAM,SAAA,CAAW,CAClC,MAAM,IAAI,aAAA,CACR,mBAAA,CACA,yDACF,CACF,CACA,GAAI,UAAU,MAAA,CAAS,oBAAA,CAAsB,CAC3C,MAAM,IAAI,aAAA,CACR,mBAAA,CACA,6BAA6B,oBAAoB,CAAA,YAAA,CACnD,CACF,CACA,GAAI,SAAA,CAAU,QAAA,CAAS,oBAAoB,CAAA,CAAG,CAC5C,MAAM,IAAI,aAAA,CAAc,mBAAA,CAAqB,6CAA6C,CAC5F,CACA,OAAO,SACT,CAOO,SAAS,UAAA,CAAW,KAAA,CAAmC,CAC5D,GAAI,OAAO,KAAA,GAAU,QAAA,CAAU,aAC/B,OACE,KAAA,CAAM,OAAS,CAAA,EACf,KAAA,CAAM,MAAK,GAAM,KAAA,EACjB,KAAA,CAAM,MAAA,EAAU,sBAChB,CAAC,KAAA,CAAM,QAAA,CAAS,oBAAoB,CAExC,CAQO,SAAS,SAAA,CAAU,MAAA,CAAA,GAAqB,MAAkC,CAC/E,OAAO,CAAC,MAAA,CAAkB,GAAG,KAAK,CAAA,CAAE,IAAA,CAAK,oBAAoB,CAC/D,CCrFO,IAAM,eAAA,CAAkB,CAAC,SAAU,eAAe,EA8BlD,SAAS,iBAAA,CAAkB,UAAoD,CACpF,OAAO,UAAU,IAAA,GAAS,QAC5B,CAEO,SAAS,uBAAA,CACd,SAAA,CACoC,CACpC,OAAO,SAAA,CAAU,IAAA,GAAS,eAC5B,CASO,SAAS,eAAA,CAAgB,SAAA,CAAgC,CAC9D,OAAO,UAAU,QACnB,CChCO,IAAM,2BAAA,CACX,gDASK,SAAS,oBAAA,CAAqB,KAAA,CAAiC,CACpE,GAAI,OAAO,KAAA,GAAU,QAAA,CAAU,aAC/B,GAAI,CAAC,2BAAA,CAA4B,IAAA,CAAK,KAAK,CAAA,CAAG,OAAO,KAAA,CACrD,MAAM,OAAS,IAAA,CAAK,KAAA,CAAM,KAAK,CAAA,CAC/B,GAAI,CAAC,MAAA,CAAO,QAAA,CAAS,MAAM,EAAG,OAAO,KAAA,CACrC,OAAO,IAAI,KAAK,MAAM,CAAA,CAAE,WAAA,EAAY,GAAM,KAC5C,CAWO,SAAS,wBAAA,CAAyB,KAAA,CAAe,MAAuB,CAC7E,GAAI,CAAC,oBAAA,CAAqB,KAAK,CAAA,CAAG,CAChC,MAAM,IAAI,cACR,yBAAA,CACA,CAAA,EAAG,KAAK,CAAA,+EAAA,EAAkF,IAAA,CAAK,UAAU,KAAK,CAAC,CAAA,CAAA,CACjH,CACF,CACA,OAAO,KACT,CC9CO,IAAM,uBAAyB,CAAC,SAAA,CAAW,OAAA,CAAS,SAAS,EA2K7D,IAAM,2BAAA,CAA8B,CAAC,gBAAA,CAAkB,mBAAmB,EAI1E,IAAM,wBAAA,CAAN,cAAuC,aAAc,CAC1C,QAAA,CACA,UAAA,CAEhB,WAAA,CAAY,SAAkB,UAAA,CAAqC,OAAA,CAAwB,CACzF,KAAA,CAAM,wBAAyB,CAAA,6BAAA,EAAgC,QAAQ,eAAe,UAAU,CAAA,EAAA,CAAA,CAAM,OAAO,CAAA,CAC7G,IAAA,CAAK,IAAA,CAAO,0BAAA,CACZ,KAAK,QAAA,CAAW,QAAA,CAChB,IAAA,CAAK,UAAA,CAAa,WACpB,CACF,EC3LO,IAAM,cAAA,CAAiB,CAAC,MAAA,CAAQ,aAAA,CAAe,WAAA,CAAa,MAAA,CAAQ,QAAQ,EAW5E,IAAM,iBAAA,CAA2E,CACtF,KAAM,CAAC,aAAA,CAAe,QAAQ,CAAA,CAC9B,YAAa,CAAC,MAAA,CAAQ,WAAA,CAAa,QAAQ,EAC3C,SAAA,CAAW,CAAC,cAAe,MAAA,CAAQ,QAAQ,EAC3C,IAAA,CAAM,EAAC,CACP,MAAA,CAAQ,EACV,EAEO,SAAS,sBAAA,CAAuB,KAAmB,EAAA,CAA0B,CAClF,OAAO,iBAAA,CAAkB,IAAI,CAAA,CAAE,QAAA,CAAS,EAAE,CAC5C,CCtBO,IAAM,kBAAA,CAAqB,CAAC,eAAA,CAAiB,UAAW,QAAQ,ECHhE,IAAM,eAAA,CAAkB,CAAC,QAAA,CAAU,UAAA,CAAY,SAAA,CAAW,OAAA,CAAS,SAAS,EAgCnF,SAAS,YAAA,CAAkD,MAAA,CAAW,KAAgC,CACpG,MAAM,KAAA,CAA6B,GACnC,IAAA,MAAW,GAAA,IAAO,IAAA,CAAM,GAAI,OAAO,GAAG,CAAA,GAAM,MAAA,CAAW,KAAA,CAAM,GAAG,CAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAC9E,OAAO,KACT,CAGO,SAAS,yBAAA,CAA0B,QAAmD,CAC3F,MAAM,YAAA,CAAe,OAAA,CAAQ,aAC7B,OAAO,MAAA,CAAO,MAAA,CAAO,CACnB,GAAI,OAAA,CAAQ,EAAA,CACZ,GAAI,OAAA,CAAQ,OAAA,GAAY,OAAY,EAAC,CAAI,CAAE,OAAA,CAAS,QAAQ,OAAQ,CAAA,CACpE,GAAI,OAAA,CAAQ,cAAgB,MAAA,CAAY,EAAC,CAAI,CAAE,YAAa,OAAA,CAAQ,WAAY,CAAA,CAChF,GAAI,eAAiB,MAAA,CAAY,EAAC,CAAI,CACpC,aAAc,MAAA,CAAO,MAAA,CAAO,CAC1B,GAAG,aAAa,YAAA,CAAc,CAAC,OAAA,CAAS,QAAA,CAAU,sBAAuB,aAAA,CAAe,cAAA,CAAgB,wBAAyB,WAAA,CAAa,cAAc,CAAC,CAAA,CAC7J,GAAI,YAAA,CAAa,SAAA,GAAc,OAAY,EAAC,CAAI,CAC9C,SAAA,CAAW,OAAO,MAAA,CAAO,YAAA,CAAa,YAAA,CAAa,SAAA,CAAW,CAAC,aAAA,CAAe,gBAAA,CAAkB,oBAAoB,CAAC,CAAC,CACxH,CACF,CAAC,CACH,CACF,CAAC,CACH,CCrDO,IAAM,qBAAuB,wBAc7B,SAAS,WAAA,CAAY,KAAA,CAA4B,CACtD,GAAI,CAAC,qBAAqB,IAAA,CAAK,KAAK,EAAG,CACrC,MAAM,IAAI,aAAA,CACR,uBACA,CAAA,wBAAA,EAA2B,oBAAA,CAAqB,MAAM,CAAA,WAAA,EAAc,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA,CAC3F,CACF,CACA,OAAO,KACT,CAGO,SAAS,aAAA,CAAc,KAAA,CAAsC,CAClE,OAAO,OAAO,KAAA,GAAU,QAAA,EAAY,oBAAA,CAAqB,IAAA,CAAK,KAAK,CACrE,CAeO,IAAM,yBAAA,CAA4B,kDAgBlC,SAAS,eAAA,CAAgB,KAAA,CAAgC,CAC9D,GAAI,CAAC,yBAAA,CAA0B,IAAA,CAAK,KAAK,EAAG,CAC1C,MAAM,IAAI,aAAA,CACR,4BACA,CAAA,6BAAA,EAAgC,yBAAA,CAA0B,MAAM,CAAA,WAAA,EAAc,KAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CAAA,CACrG,CACF,CACA,OAAO,KACT,CAiBO,SAAS,eAAA,CACd,MAAA,CACA,IAAA,CACA,MAAA,CACQ,CACR,MAAMA,IAAAA,CAAM,IAAA,CAAK,KAAA,CAAM,UAAU,MAAM,CAAA,CACvC,MAAM,GAAA,CAAM,CAAA,QAAA,EAAW,MAAgB,CAAA,gBAAA,EAAmBA,IAAG,CAAA,CAAA,CAC7D,OAAO,SAAW,MAAA,CAAY,GAAA,CAAM,CAAA,EAAG,MAAgB,IAAI,GAAG,CAAA,CAChE,CAUO,IAAM,cAAgB,CAAC,SAAA,CAAW,WAAA,CAAa,gBAAA,CAAkB,SAAS,EAI1E,IAAM,wBAAA,CAAkF,CAC7F,QAAS,CAAC,WAAA,CAAa,gBAAgB,CAAA,CACvC,UAAW,CAAC,gBAAgB,CAAA,CAC5B,cAAA,CAAgB,CAAC,SAAA,CAAW,WAAW,EACvC,OAAA,CAAS,EACX,EAEO,SAAS,uBAAA,CAAwB,IAAA,CAAmB,GAA0B,CACnF,OAAO,wBAAA,CAAyB,IAAI,EAAE,QAAA,CAAS,EAAE,CACnD,KCxDa,mBAAA,CAAsB,CAAC,QAAA,CAAU,QAAQ,EAG/C,IAAM,0BAAA,CAA6B,CACxC,UAAA,CACA,YACA,SAAA,CACA,SACF,EAsDO,IAAM,uBAAyB,CAAC,QAAA,CAAU,SAAA,CAAW,SAAA,CAAW,WAAW,EAgB3E,IAAM,oBAAsB,CACjC,0BAAA,CACA,yBACA,6BAAA,CACA,4BAAA,CACA,yBACF,MAKa,yBAAA,CAA4B,CACvC,wBAAA,CAA0B,GAAA,CAC1B,uBAAwB,GAAA,CACxB,2BAAA,CAA6B,GAAA,CAC7B,0BAAA,CAA4B,IAC5B,uBAAA,CAAyB,GAC3B,EC7JO,IAAM,gCAAA,CAAmC,2BAGnC,uBAAA,CAA0B,iCAEhC,IAAM,2BAAA,CAA8B,EACxC,MAAA,CAAO,CACN,MAAA,CAAQ,CAAA,CAAE,QAAQ,gCAAgC,CAAA,CAElD,OAAA,CAAS,CAAA,CAAE,QAAO,CAAE,GAAA,EAAI,CAAE,WAAA,GAC1B,YAAA,CAAc,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,QAAO,CAAE,KAAA,CAAM,uBAAuB,CAAC,CACjE,CAAC,CAAA,CACA,WAAA,CAAY,CAAC,YAAa,GAAA,GAAQ,CACjC,MAAM,IAAA,CAAO,IAAI,GAAA,CACjB,IAAA,KAAW,CAAC,KAAA,CAAO,IAAI,CAAA,GAAK,WAAA,CAAY,YAAA,CAAa,OAAA,GAAW,CAC9D,GAAI,KAAK,GAAA,CAAI,IAAI,EAAG,CAClB,GAAA,CAAI,QAAA,CAAS,CACX,KAAM,QAAA,CACN,IAAA,CAAM,CAAC,cAAA,CAAgB,KAAK,CAAA,CAC5B,OAAA,CAAS,CAAA,qBAAA,EAAwB,IAAA,CAAK,UAAU,IAAI,CAAC,CAAA,CAAA,CACvD,CAAC,EACH,CACA,IAAA,CAAK,GAAA,CAAI,IAAI,EACf,CACF,CAAC,EASI,SAAS,2BAA2B,KAAA,CAAuC,CAChF,MAAM,MAAA,CAAS,4BAA4B,SAAA,CAAU,KAAK,EAC1D,GAAI,CAAC,OAAO,OAAA,CAAS,CACnB,MAAM,IAAI,cACR,gCAAA,CACA,CAAA,gCAAA,EAAmC,MAAA,CAAO,KAAA,CAAM,OAC7C,GAAA,CAAK,KAAA,EAAU,CAAA,EAAG,KAAA,CAAM,KAAK,IAAA,CAAK,GAAG,CAAA,EAAK,QAAQ,KAAK,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA,CACtE,KAAK,IAAI,CAAC,CAAA,CAAA,CACb,CAAE,MAAO,MAAA,CAAO,KAAM,CACxB,CACF,CACA,OAAO,MAAA,CAAO,IAChB,CAEO,SAAS,cACd,WAAA,CACA,UAAA,CACS,CACT,OAAO,YAAY,YAAA,CAAa,QAAA,CAAS,UAAU,CACrD,CASO,SAAS,gBAAA,CACd,WAAA,CACA,UAAA,CACM,CACN,GAAI,CAAC,aAAA,CAAc,WAAA,CAAa,UAAU,CAAA,CAAG,CAC3C,MAAM,IAAI,cACR,wBAAA,CACA,CAAA,WAAA,EAAc,IAAA,CAAK,SAAA,CAAU,UAAU,CAAC,CAAA,oCAAA,CAC1C,CACF,CACF,KChDa,6BAAA,CAAgC,qBAStC,IAAM,uBAAA,CAA0B,yBAChC,IAAM,0BAAA,CAA6B,GACnC,IAAM,kCAAoC,KAG1C,IAAM,0BAAA,CAA6B,iDAc7B,4BAAA,CAA+B,8DACrC,IAAM,+BAAA,CAAkC,IAGxC,IAAM,qBAAA,CAAwB,WAG9B,IAAM,0BAA4B,OAElC,IAAM,oBAAA,CAAuB,YACvB,oBAAA,CAAuB,GAa7B,IAAM,2BAAA,CAA8B,CACzC,MAAA,CACA,SAAA,CACA,aACA,KAAA,CACA,QAAA,CACA,QACA,KAAA,CACA,aAAA,CACA,YAAA,CACA,aAAA,CACA,SACA,SAAA,CACA,OAAA,CACA,QAAA,CACA,SAAA,CACA,eACA,eAAA,CACA,OAAA,CACA,YAAA,CACA,aACF,EAEA,IAAM,iBAAA,CAAoBC,CAAAA,CACvB,MAAA,GACA,KAAA,CAAM,oBAAoB,CAAA,CAC1B,SAAA,CAAW,OAAU,WAAA,CAAY,KAAK,CAAC,CAAA,KAG7B,mBAAA,CAAsBA,CAAAA,CAAE,YAAA,CAAa,CAChD,KAAMA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAAE,GAAA,CAAI,+BAA+B,CAAA,CAAE,KAAA,CAAM,4BAA4B,CAAA,CAC/F,WAAA,CAAa,iBAAA,CACb,QAAA,CAAUA,EAAE,MAAA,EAAO,CAAE,GAAA,EAAI,CAAE,aAAY,CAAE,GAAA,CAAI,yBAAyB,CACxE,CAAC,EAaM,IAAM,uBAAA,CAA0BA,CAAAA,CAAE,aAAa,CACpD,MAAA,CAAQA,CAAAA,CAAE,OAAA,CAAQ,6BAA6B,CAAA,CAC/C,IAAA,CAAMA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAAE,GAAA,CAAI,0BAA0B,EAAE,KAAA,CAAM,uBAAuB,CAAA,CACrF,OAAA,CAASA,EAAE,MAAA,EAAO,CAAE,KAAA,CAAM,0BAA0B,EACpD,WAAA,CAAaA,CAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,GAAA,CAAI,iCAAiC,EACpE,KAAA,CAAOA,CAAAA,CAAE,KAAA,CAAM,mBAAmB,EAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,oBAAoB,CAAA,CACnE,WAAA,CAAa,iBACf,CAAC,EASM,SAAS,sBAAA,CAAuB,KAAA,CAAmC,CACxE,GAAI,OAAO,KAAA,GAAU,QAAA,EAAY,KAAA,GAAU,KAAM,CAC/C,MAAM,OAAA,CAAU,2BAAA,CAA4B,OAAQ,KAAA,EAClD,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,KAAK,KAAA,CAAO,KAAK,CACnD,CAAA,CACA,GAAI,OAAA,CAAQ,MAAA,CAAS,CAAA,CAAG,CACtB,MAAM,IAAI,aAAA,CACR,6BAAA,CACA,CAAA,4EAAA,EAA+E,QAC5E,GAAA,CAAK,KAAA,EAAU,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA,CACpC,KAAK,IAAI,CAAC,GACf,CACF,CACF,CACA,MAAM,OAAS,uBAAA,CAAwB,SAAA,CAAU,KAAK,CAAA,CACtD,GAAI,CAAC,MAAA,CAAO,OAAA,CAAS,CACnB,MAAM,IAAI,aAAA,CACR,6BAAA,CACA,CAAA,6BAAA,EAAgC,OAAO,KAAA,CAAM,MAAA,CAC1C,GAAA,CAAK,KAAA,EAAU,GAAG,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,GAAG,GAAK,QAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,EAAE,CAAA,CACtE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CACb,CAAE,KAAA,CAAO,MAAA,CAAO,KAAM,CACxB,CACF,CACA,OAAO,MAAA,CAAO,IAChB,CAcO,SAAS,yBAAA,CAA0B,QAAA,CAK/B,CACT,MAAM,IAAA,CAAO,CAAC,GAAG,QAAA,CAAS,KAAK,CAAA,CAC5B,IAAA,CAAK,CAAC,IAAA,CAAM,QAAW,IAAA,CAAK,IAAA,CAAO,KAAA,CAAM,IAAA,CAAO,GAAK,IAAA,CAAK,IAAA,CAAO,KAAA,CAAM,IAAA,CAAO,EAAI,CAAE,CAAA,CACpF,IAAK,IAAA,EAAS,CAAA,EAAG,KAAK,IAAI;AAAA,EAAK,KAAK,WAAqB;AAAA,EAAK,KAAK,QAAQ;AAAA,CAAI,CAAA,CAClF,OAAO,CACL,CAAA,EAAG,6BAA6B;AAAA,CAAA,CAChC,CAAA,EAAG,SAAS,IAAI;AAAA,CAAA,CAChB,CAAA,EAAG,SAAS,OAAO;AAAA,CAAA,CACnB,CAAA,EAAG,QAAA,CAAS,WAAA,CAAY,MAAM;AAAA,CAAA,CAC9B,CAAA,EAAG,SAAS,WAAW;AAAA,CAAA,CACvB,CAAA,EAAG,QAAA,CAAS,KAAA,CAAM,MAAM;AAAA,CAAA,CACxB,GAAG,IACL,CAAA,CAAE,IAAA,CAAK,EAAE,CACX,KAGa,qBAAA,CAAwB,CACnC,cACA,gBAAA,CACA,eAAA,CACA,sBACA,eAAA,CACA,eAAA,CACA,gBACA,eAAA,CACA,eACF,EAaO,SAAS,mBAAA,CAAoB,KAAuB,CACzD,OACE,KAAK,MAAA,CAAS,CAAA,EACd,KAAK,MAAA,EAAU,+BAAA,EACf,6BAA6B,IAAA,CAAK,IAAI,CAE1C,CAUO,SAAS,uBAAuB,QAAA,CAA6C,CAClF,GAAI,QAAA,CAAS,KAAA,CAAM,MAAA,CAAS,oBAAA,CAAsB,CAChD,OAAO,CACL,EAAA,CAAI,KAAA,CACJ,OAAQ,qBAAA,CACR,MAAA,CAAQ,GAAG,QAAA,CAAS,KAAA,CAAM,MAAM,CAAA,mBAAA,EAAsB,oBAAoB,cAC5E,CACF,CAEA,MAAM,IAAA,CAAO,IAAI,IACjB,IAAI,KAAA,CAAQ,EACZ,IAAA,MAAW,IAAA,IAAQ,SAAS,KAAA,CAAO,CACjC,GAAI,CAAC,mBAAA,CAAoB,KAAK,IAAI,CAAA,CAAG,CACnC,OAAO,CAAE,GAAI,KAAA,CAAO,MAAA,CAAQ,cAAe,MAAA,CAAQ,CAAA,EAAG,KAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAC,CAAA,6BAAA,CAAgC,CACjH,CACA,GAAI,IAAA,CAAK,IAAI,IAAA,CAAK,IAAI,EAAG,CACvB,OAAO,CAAE,EAAA,CAAI,KAAA,CAAO,OAAQ,gBAAA,CAAkB,MAAA,CAAQ,GAAG,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAC,qBAAsB,CAC1G,CACA,KAAK,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,CAClB,GAAI,KAAK,QAAA,CAAW,yBAAA,CAA2B,CAC7C,OAAO,CACL,GAAI,KAAA,CACJ,MAAA,CAAQ,gBACR,MAAA,CAAQ,CAAA,EAAG,KAAK,SAAA,CAAU,IAAA,CAAK,IAAI,CAAC,CAAA,UAAA,EAAa,IAAA,CAAK,QAAQ,CAAA,iBAAA,EAAoB,yBAAyB,uBAC7G,CACF,CACA,OAAS,IAAA,CAAK,SAChB,CAEA,GAAI,CAAC,KAAK,GAAA,CAAI,qBAAqB,EAAG,CACpC,OAAO,CACL,EAAA,CAAI,KAAA,CACJ,OAAQ,eAAA,CACR,MAAA,CAAQ,2BAA2B,qBAAqB,CAAA,CAAA,CAC1D,CACF,CACA,GAAI,MAAQ,oBAAA,CAAsB,CAChC,OAAO,CACL,EAAA,CAAI,MACJ,MAAA,CAAQ,eAAA,CACR,OAAQ,CAAA,EAAG,KAAK,+BAA+B,oBAAoB,CAAA,iBAAA,CACrE,CACF,CACA,OAAO,CAAE,GAAI,IAAA,CAAM,KAAM,CAC3B,CAiBO,SAAS,0BACd,QAAA,CACA,QAAA,CACgB,CAChB,GAAI,CAAC,oBAAoB,QAAA,CAAS,IAAI,EAAG,CACvC,OAAO,CAAE,EAAA,CAAI,KAAA,CAAO,OAAQ,aAAA,CAAe,MAAA,CAAQ,GAAG,IAAA,CAAK,SAAA,CAAU,SAAS,IAAI,CAAC,+BAAgC,CACrH,CACA,GAAI,QAAA,CAAS,QAAA,CAAW,0BAA2B,CACjD,OAAO,CACL,EAAA,CAAI,KAAA,CACJ,OAAQ,eAAA,CACR,MAAA,CAAQ,CAAA,EAAG,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,IAAI,CAAC,CAAA,WAAA,EAAc,SAAS,QAAQ,CAAA,iBAAA,EAAoB,yBAAyB,CAAA,qBAAA,CACtH,CACF,CACA,GAAI,QAAA,CAAS,WAAa,QAAA,CAAS,QAAA,CAAU,CAC3C,OAAO,CACL,GAAI,KAAA,CACJ,MAAA,CAAQ,gBACR,MAAA,CAAQ,CAAA,EAAG,KAAK,SAAA,CAAU,QAAA,CAAS,IAAI,CAAC,CAAA,UAAA,EAAa,SAAS,QAAQ,CAAA,qBAAA,EAAwB,SAAS,QAAQ,CAAA,CAAA,CACjH,CACF,CACA,GAAK,SAAS,WAAA,GAA4B,QAAA,CAAS,YAAwB,CACzE,OAAO,CACL,EAAA,CAAI,KAAA,CACJ,MAAA,CAAQ,gBACR,MAAA,CAAQ,CAAA,EAAG,KAAK,SAAA,CAAU,QAAA,CAAS,IAAI,CAAC,CAAA,UAAA,EAAa,SAAS,WAAqB,CAAA,eAAA,EAAkB,SAAS,WAAqB,CAAA,CAAA,CACrI,CACF,CACA,OAAO,CAAE,EAAA,CAAI,IAAA,CAAM,MAAO,QAAA,CAAS,QAAS,CAC9C,CAiBO,IAAM,yBAA2B,CAAC,MAAA,CAAQ,aAAa,EAE9D,IAAM,sBAAwB,KAAA,CAC9B,IAAM,yBAA2B,uCAAA,CAEjC,SAAS,QAAQ,KAAA,CAAmC,CAClD,MAAM,OAAA,CAAU,KAAA,CAAM,IAAA,EAAK,CAC3B,GAAI,OAAA,CAAQ,QAAU,CAAA,CAAG,CACvB,MAAM,KAAA,CAAQ,OAAA,CAAQ,CAAC,CAAA,CACvB,MAAM,KAAO,OAAA,CAAQ,OAAA,CAAQ,OAAS,CAAC,CAAA,CACvC,GAAK,KAAA,GAAU,GAAA,EAAO,OAAS,GAAA,EAAS,KAAA,GAAU,GAAA,EAAO,IAAA,GAAS,GAAA,CAAM,CACtE,MAAM,KAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,CAAG,EAAE,EACjC,OAAO,KAAA,CAAM,SAAS,KAAK,CAAA,CAAI,OAAY,KAC7C,CACF,CACA,OAAO,OACT,CAaO,SAAS,qBAAA,CAAsB,IAAA,CAAgC,CACpE,MAAM,MAAA,CAAU,SAA2B,CACzC,MAAM,IAAI,aAAA,CAAc,gCAAA,CAAkC,OAAO,CACnE,CAAA,CAEA,MAAM,KAAA,CAAQ,IAAA,CAAK,MAAM,IAAI,CAAA,CAC7B,GAAI,KAAA,CAAM,CAAC,GAAG,OAAA,EAAQ,GAAM,sBAAuB,CACjD,MAAA,CAAO,iCAAiC,qBAAqB,CAAA,uBAAA,CAAyB,EACxF,CACA,MAAM,QAAU,KAAA,CAAM,SAAA,CAAU,CAAC,IAAA,CAAM,KAAA,GAAU,MAAQ,CAAA,EAAK,IAAA,CAAK,SAAQ,GAAM,qBAAqB,EACtG,GAAI,OAAA,CAAU,CAAA,CAAG,MAAA,CAAO,CAAA,yCAAA,EAA4C,qBAAqB,QAAQ,CAAA,CAEjG,MAAM,OAAS,IAAI,GAAA,CACnB,UAAW,IAAA,IAAQ,KAAA,CAAM,MAAM,CAAA,CAAG,OAAO,EAAG,CAC1C,GAAI,KAAK,IAAA,EAAK,CAAE,SAAW,CAAA,CAAG,SAC9B,MAAM,KAAA,CAAQ,wBAAA,CAAyB,KAAK,IAAI,CAAA,CAChD,GAAI,KAAA,GAAU,IAAA,CAAM,OAAO,CAAA,iBAAA,EAAoB,IAAA,CAAK,UAAU,IAAI,CAAC,gCAAgC,CAAA,CACnG,MAAM,IAAM,KAAA,CAAO,CAAC,EACpB,GAAI,CAAE,wBAAA,CAA+C,QAAA,CAAS,GAAG,CAAA,CAAG,CAClE,MAAA,CACE,CAAA,gBAAA,EAAmB,KAAK,SAAA,CAAU,GAAG,CAAC,CAAA,eAAA,EAAkB,wBAAA,CAAyB,KAAK,IAAI,CAAC,qDAC7F,EACF,CACA,GAAI,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,CAAG,MAAA,CAAO,mBAAmB,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA,mBAAA,CAAqB,EACvF,MAAM,KAAA,CAAQ,QAAQ,KAAA,CAAO,CAAC,CAAE,CAAA,CAChC,GAAI,QAAU,MAAA,EAAa,KAAA,CAAM,SAAW,CAAA,CAAG,CAC7C,OAAO,CAAA,gBAAA,EAAmB,IAAA,CAAK,SAAA,CAAU,GAAG,CAAC,CAAA,qBAAA,CAAuB,EACtE,CACA,MAAA,CAAO,IAAI,GAAA,CAAK,KAAM,EACxB,CAEA,MAAM,KAAO,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA,CAC9B,MAAM,YAAc,MAAA,CAAO,GAAA,CAAI,aAAa,CAAA,CAC5C,GAAI,IAAA,GAAS,MAAA,CAAW,MAAA,CAAO,gCAAgC,EAC/D,GAAI,WAAA,GAAgB,OAAW,MAAA,CAAO,uCAAuC,EAC7E,GAAI,IAAA,CAAM,OAAS,0BAAA,EAA8B,CAAC,wBAAwB,IAAA,CAAK,IAAK,EAAG,CACrF,MAAA,CACE,mCAAmC,uBAAA,CAAwB,MAAM,CAAA,gBAAA,EAAmB,0BAA0B,CAAA,YAAA,CAChH,EACF,CACA,GAAI,WAAA,CAAa,OAAS,iCAAA,CAAmC,CAC3D,OAAO,CAAA,oCAAA,EAAuC,iCAAiC,cAAc,EAC/F,CACA,OAAO,CAAE,IAAA,CAAa,WAA0B,CAClD,CASO,SAAS,mBAAA,CAAoB,QAAA,CAA6B,UAAmC,CAClG,MAAM,YAAc,qBAAA,CAAsB,SAAS,EACnD,GAAI,WAAA,CAAY,OAAS,QAAA,CAAS,IAAA,CAAM,CACtC,OAAO,CACL,GAAI,KAAA,CACJ,MAAA,CAAQ,gBACR,MAAA,CAAQ,CAAA,EAAG,qBAAqB,CAAA,UAAA,EAAa,IAAA,CAAK,SAAA,CAAU,WAAA,CAAY,IAAI,CAAC,8BAA8B,IAAA,CAAK,SAAA,CAAU,SAAS,IAAI,CAAC,GAC1I,CACF,CACA,OAAO,CAAE,EAAA,CAAI,KAAM,KAAA,CAAO,IAAI,aAAY,CAAE,MAAA,CAAO,SAAS,CAAA,CAAE,MAAO,CACvE,CCjYO,IAAM,iBAAmB,CAC9B,SAAA,CACA,QACA,OAAA,CACA,UAAA,CACA,UACA,OAAA,CACA,YACF,ECjCO,IAAM,+BAAA,CAAkC,GAExC,IAAM,kBAAwE,CACnF,OAAA,CAAS,CACP,QAAA,CACA,WAAA,CACA,WAAA,CACA,gBAAA,CACA,eAAA,CACA,YAAA,CACA,iBACA,eAAA,CACA,aAAA,CACA,cACF,CAAA,CACA,KAAA,CAAO,CAAC,QAAA,CAAU,KAAA,CAAO,OAAQ,OAAA,CAAS,SAAA,CAAW,eAAgB,QAAQ,CAAA,CAC7E,MAAO,CAAC,eAAA,CAAiB,gBAAiB,WAAA,CAAa,cAAc,EACrE,QAAA,CAAU,CAAC,UAAW,MAAA,CAAQ,MAAA,CAAQ,gBAAgB,CAAA,CACtD,OAAA,CAAS,CACP,aAAA,CACA,QAAA,CACA,MACA,MAAA,CACA,cAAA,CACA,kBACA,mBAAA,CACA,aAAA,CACA,gBACF,CAAA,CACA,KAAA,CAAO,CACL,iBAAA,CACA,kBAAA,CACA,WAAA,CACA,YAAA,CACA,iBAAA,CACA,SAAA,CACA,sBACA,kBAAA,CACA,gBACF,EACA,UAAA,CAAY,CAAC,UAAW,KAAA,CAAO,MAAA,CAAQ,UAAU,CACnD,MAGa,oBAAA,CAAgE,CAC3E,QAAS,cAAA,CACT,KAAA,CAAO,aACP,KAAA,CAAO,YAAA,CACP,QAAA,CAAU,eAAA,CACV,OAAA,CAAS,aAAA,CACT,MAAO,YAAA,CACP,UAAA,CAAY,gBACd,MC5Da,sBAAA,CAAyB,2BAOzB,0BAAA,CAA6B,6BAE7B,oBAAA,CAAuB,MAGvB,uBAAA,CAA0B,CAAC,SAAS,EAS1C,IAAM,mBAAA,CAAsB,sBAEnC,IAAM,iBAAA,CAAoB,mBAC1B,IAAM,mBAAA,CAAsB,WAU5B,SAAS,uBAAA,CAAwB,KAAc,MAAA,CAA+B,CAC5E,OAAO,IAAI,aAAA,CACT,gCACA,CAAA,oBAAA,EAAuB,IAAI,KAAK,MAAM,CAAA,CACxC,CACF,CAEA,SAAS,cAAc,KAAA,CAAwB,CAC7C,MAAM,SAAA,CAAqB,MAAA,CAAO,eAAe,KAAK,CAAA,CACtD,OAAO,SAAA,GAAc,MAAA,CAAO,WAAa,SAAA,GAAc,IACzD,CAEA,SAAS,iBAAA,CAAkB,MAAgB,IAAA,CAAc,IAAA,CAA2B,CAClF,GAAI,KAAA,GAAU,IAAA,CAAM,OAAO,MAAA,CAE3B,OAAQ,OAAO,KAAA,EACb,KAAK,SAAA,CACH,OAAO,MAAQ,MAAA,CAAS,OAAA,CAC1B,KAAK,QAAA,CAGH,OAAO,KAAK,SAAA,CAAU,KAAK,EAC7B,KAAK,QAAA,CAAU,CACb,GAAI,CAAC,OAAO,aAAA,CAAc,KAAK,EAAG,CAChC,MAAM,wBACJ,IAAA,CACA,CAAA,iDAAA,EAAoD,OAAO,KAAK,CAAC,EACnE,CACF,CAEA,OAAO,MAAA,CAAO,KAAA,GAAU,EAAI,CAAA,CAAI,KAAK,CACvC,CACA,KAAK,WAAA,CACH,MAAM,uBAAA,CAAwB,IAAA,CAAM,iCAAiC,CAAA,CACvE,KAAK,SACH,MAAM,uBAAA,CAAwB,KAAM,2BAA2B,CAAA,CACjE,KAAK,UAAA,CACL,KAAK,SACH,MAAM,uBAAA,CAAwB,KAAM,CAAA,EAAG,OAAO,KAAK,CAAA,mBAAA,CAAqB,CAAA,CAC1E,KAAK,QAAA,CACH,MACF,QACE,MAAM,uBAAA,CAAwB,KAAM,CAAA,iBAAA,EAAoB,OAAO,KAAK,CAAA,CAAE,CAC1E,CAEA,MAAM,WAAA,CAAc,MACpB,GAAI,IAAA,CAAK,IAAI,WAAW,CAAA,CAAG,CACzB,MAAM,uBAAA,CAAwB,IAAA,CAAM,oBAAoB,CAC1D,CACA,KAAK,GAAA,CAAI,WAAW,EACpB,GAAI,CACF,GAAI,KAAA,CAAM,OAAA,CAAQ,WAAW,CAAA,CAAG,CAC9B,MAAMC,MAAAA,CAAQ,WAAA,CAAY,IAAI,CAAC,KAAA,CAAO,QACpC,iBAAA,CAAkB,KAAA,CAAO,GAAG,IAAI,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,CAAA,CAAK,IAAI,CACpD,CAAA,CACA,OAAO,IAAIA,MAAAA,CAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAC5B,CACA,GAAI,CAAC,cAAc,WAAW,CAAA,CAAG,CAC/B,MAAM,uBAAA,CACJ,IAAA,CACA,mDACF,CACF,CAGA,MAAM,IAAA,CAAO,MAAA,CAAO,KAAK,WAAW,CAAA,CAAE,MAAK,CAC3C,MAAM,OAAS,WAAA,CACf,MAAM,MAAQ,IAAA,CAAK,GAAA,CAAK,KAAQ,CAC9B,MAAM,WAAa,IAAA,CAAK,SAAA,CAAU,GAAG,CAAA,CACrC,MAAM,aAAe,iBAAA,CAAkB,MAAA,CAAO,GAAG,CAAA,CAAG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,GAAG,GAAI,IAAI,CAAA,CAC1E,OAAO,CAAA,EAAG,UAAU,IAAI,YAAY,CAAA,CACtC,CAAC,CAAA,CACD,OAAO,CAAA,CAAA,EAAI,MAAM,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,CAC5B,CAAA,OAAE,CACA,IAAA,CAAK,MAAA,CAAO,WAAW,EACzB,CACF,CAOO,SAAS,gBAAA,CAAiB,MAA0B,CACzD,OAAO,kBAAkB,KAAA,CAAO,QAAA,CAAU,IAAI,GAAK,CACrD,CAGO,SAAS,qBAAA,CAAsB,MAA8B,CAClE,OAAO,IAAI,WAAA,EAAY,CAAE,OAAO,gBAAA,CAAiB,KAAK,CAAC,CACzD,KAca,gCAAA,CAAmCD,CAAAA,CAC7C,aAAa,CACZ,OAAA,CAASA,CAAAA,CAAE,OAAA,CAAQ,oBAAoB,CAAA,CACvC,SAAUA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAC1B,SAAA,CAAWA,CAAAA,CAAE,QAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAC3B,QAAA,CAAUA,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAE1B,MAAOA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAEvB,QAAA,CAAUA,CAAAA,CAAE,QAAO,CAAE,GAAA,GAAM,WAAA,EAAY,CAEvC,UAAWA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAE3B,SAAA,CAAWA,CAAAA,CAAE,MAAA,EAAO,CAAE,GAAA,CAAI,CAAC,EAE3B,QAAA,CAAUA,CAAAA,CAAE,QAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAC1B,MAAA,CAAQA,EAAE,MAAA,EAAO,CAAE,MAAM,mBAAmB,CAAA,CAAE,UAAS,CACvD,IAAA,CAAMA,EAAE,MAAA,EAAO,CAAE,UAAA,CAAW,GAAG,CAAA,CAAE,QAAA,GACjC,WAAA,CAAaA,CAAAA,CAAE,QAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,QAAA,GAC/B,UAAA,CAAYA,CAAAA,CAAE,QAAO,CAAE,KAAA,CAAM,oBAAoB,CAAA,CAEjD,QAAA,CAAUA,EAAE,MAAA,EAAO,CAAE,GAAA,EAAI,CAAE,WAAA,EAAY,CACvC,SAAUA,CAAAA,CAAE,GAAA,CAAI,UAAS,CACzB,SAAA,CAAWA,EAAE,GAAA,CAAI,QAAA,GAAW,QAAA,EAAS,CACrC,MAAOA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAAE,QAAA,EAC3B,CAAC,CAAA,CACA,WAAA,CAAY,CAAC,MAAA,CAAQ,GAAA,GAAQ,CAC5B,MAAM,cAAA,CAAiB,OAAO,MAAA,GAAW,MAAA,EAAa,OAAO,IAAA,GAAS,MAAA,CACtE,MAAM,cAAA,CAAiB,MAAA,CAAO,cAAgB,MAAA,CAC9C,GAAI,iBAAmB,cAAA,CAAgB,CACrC,GAAA,CAAI,QAAA,CAAS,CACX,IAAA,CAAM,SACN,OAAA,CACE,4FACJ,CAAC,EACH,CACA,GAAI,CAAC,cAAA,GAAmB,OAAO,MAAA,GAAW,MAAA,EAAa,OAAO,IAAA,GAAS,MAAA,CAAA,CAAY,CACjF,GAAA,CAAI,QAAA,CAAS,CACX,IAAA,CAAM,QAAA,CACN,QAAS,gDACX,CAAC,EACH,CACF,CAAC,EAII,IAAM,2BAAA,CAA8BA,EAAE,YAAA,CAAa,CACxD,OAAQA,CAAAA,CAAE,OAAA,CAAQ,sBAAsB,CAAA,CACxC,SAAA,CAAWA,EAAE,IAAA,CAAK,uBAAuB,EACzC,SAAA,CAAW,gCAAA,CAEX,SAAA,CAAWA,CAAAA,CAAE,MAAA,EAAO,CAAE,MAAM,iBAAiB,CAC/C,CAAC,EASM,SAAS,yBAAyB,KAAA,CAAuC,CAC9E,MAAM,MAAA,CAAS,2BAAA,CAA4B,UAAU,KAAK,CAAA,CAC1D,GAAI,CAAC,MAAA,CAAO,QAAS,CACnB,MAAM,IAAI,aAAA,CACR,wBAAA,CACA,kCAAkC,MAAA,CAAO,KAAA,CAAM,OAC5C,GAAA,CAAK,KAAA,EAAU,GAAG,KAAA,CAAM,IAAA,CAAK,KAAK,GAAG,CAAA,EAAK,QAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA,CACtE,KAAK,IAAI,CAAC,CAAA,CAAA,CACb,CAAE,KAAA,CAAO,MAAA,CAAO,KAAM,CACxB,CACF,CACA,OAAO,MAAA,CAAO,IAChB,CAWO,SAAS,2BAA2B,MAAA,CAAgD,CACzF,MAAM,SAAA,CAAuC,CAC3C,QAAS,MAAA,CAAO,OAAA,CAChB,SAAU,MAAA,CAAO,QAAA,CACjB,SAAA,CAAW,MAAA,CAAO,SAAA,CAClB,QAAA,CAAU,OAAO,QAAA,CACjB,KAAA,CAAO,OAAO,KAAA,CACd,QAAA,CAAU,OAAO,QAAA,CACjB,SAAA,CAAW,OAAO,SAAA,CAClB,SAAA,CAAW,OAAO,SAAA,CAClB,QAAA,CAAU,OAAO,QAAA,CACjB,UAAA,CAAY,OAAO,UAAA,CACnB,QAAA,CAAU,MAAA,CAAO,QAAA,CACjB,QAAA,CAAU,MAAA,CAAO,QACnB,CAAA,CACA,GAAI,OAAO,MAAA,GAAW,MAAA,CAAW,UAAU,QAAQ,CAAA,CAAI,OAAO,MAAA,CAC9D,GAAI,OAAO,IAAA,GAAS,MAAA,CAAW,UAAU,MAAM,CAAA,CAAI,OAAO,IAAA,CAC1D,GAAI,OAAO,WAAA,GAAgB,MAAA,CAAW,UAAU,aAAa,CAAA,CAAI,OAAO,WAAA,CACxE,GAAI,OAAO,SAAA,GAAc,MAAA,CAAW,UAAU,WAAW,CAAA,CAAI,OAAO,SAAA,CACpE,GAAI,OAAO,KAAA,GAAU,MAAA,CAAW,UAAU,OAAO,CAAA,CAAI,MAAA,CAAO,KAAA,CAC5D,OAAO,SACT,CAGO,SAAS,wBAAA,CAAyB,OAA4C,CACnF,OAAO,iBAAiB,0BAAA,CAA2B,MAAM,CAAC,CAC5D,CAQO,SAAS,uBAAA,CAAwB,MAAA,CAAgD,CACtF,OAAO,IAAI,aAAY,CAAE,MAAA,CACvB,2BAA6B,wBAAA,CAAyB,MAAM,CAC9D,CACF,CChPO,IAAM,0BAAA,CAA6B,2BAiBnC,IAAM,8BAAA,CAAiC,6BAEvC,IAAM,wBAAA,CAA2B,EAMjC,IAAM,wBAAA,CAA2B,yBAgBjC,IAAM,4BAAA,CAA+B,2BAErC,IAAM,sBAAA,CAAyB,MAGzB,2BAAA,CAA8B,CAAC,SAAS,EAS9C,IAAM,gCAAkC,KAOxC,IAAM,4BAA8B,IAGpC,IAAM,oCAAsC,IAGnD,IAAM,YAAc,qBAAA,CAGpB,IAAM,kBAAoB,qBAAA,CAE1B,SAAS,eAAe,KAAA,CAAuB,CAC7C,OAAO,IAAI,WAAA,GAAc,MAAA,CAAO,KAAK,EAAE,MACzC,CASA,IAAM,kBAAA,CAAqBA,CAAAA,CACxB,QAAO,CACP,GAAA,CAAI,CAAC,CAAA,CACL,MAAA,CAAQ,OAAU,cAAA,CAAe,KAAK,CAAA,EAAK,mCAAA,CAAqC,CAC/E,OAAA,CAAS,4BAA4B,mCAAmC,CAAA,YAAA,CAC1E,CAAC,CAAA,CAgBI,IAAM,4BAA8BA,CAAAA,CAAE,YAAA,CAAa,CACxD,OAAA,CAASA,CAAAA,CAAE,QAAQ,wBAAwB,CAAA,CAE3C,OAAQA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,CAAA,CACxB,SAAA,CAAWA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAE3B,QAAA,CAAUA,CAAAA,CAAE,QAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAE1B,QAAA,CAAU,mBAEV,GAAA,CAAKA,CAAAA,CAAE,QAAO,CAAE,KAAA,CAAM,WAAW,CAAA,CACjC,QAAA,CAAUA,CAAAA,CAAE,GAAA,CAAI,QAAA,EAAS,CACzB,UAAWA,CAAAA,CAAE,GAAA,CAAI,UACnB,CAAC,EAIM,IAAM,+BAAA,CAAkCA,EAAE,YAAA,CAAa,CAC5D,OAAQA,CAAAA,CAAE,OAAA,CAAQ,0BAA0B,CAAA,CAC5C,SAAA,CAAWA,EAAE,IAAA,CAAK,2BAA2B,EAC7C,SAAA,CAAW,2BAAA,CAEX,UAAWA,CAAAA,CAAE,MAAA,GAAS,KAAA,CAAM,iBAAiB,CAC/C,CAAC,EASM,SAAS,4BAAA,CAA6B,KAAA,CAA2C,CACtF,MAAM,MAAA,CAAS,gCAAgC,SAAA,CAAU,KAAK,EAC9D,GAAI,CAAC,MAAA,CAAO,OAAA,CAAS,CACnB,MAAM,IAAI,aAAA,CACR,4BAAA,CACA,sCAAsC,MAAA,CAAO,KAAA,CAAM,OAChD,GAAA,CAAK,KAAA,EAAU,GAAG,KAAA,CAAM,IAAA,CAAK,KAAK,GAAG,CAAA,EAAK,QAAQ,CAAA,EAAA,EAAK,KAAA,CAAM,OAAO,CAAA,CAAE,CAAA,CACtE,KAAK,IAAI,CAAC,GACb,CAAE,KAAA,CAAO,OAAO,KAAM,CACxB,CACF,CACA,OAAO,OAAO,IAChB,CAUO,SAAS,8BAAA,CAA+B,MAAA,CAA2C,CACxF,MAAM,SAAA,CAAuC,CAC3C,OAAA,CAAS,MAAA,CAAO,OAAA,CAChB,MAAA,CAAQ,MAAA,CAAO,MAAA,CACf,UAAW,MAAA,CAAO,SAAA,CAClB,SAAU,MAAA,CAAO,QAAA,CACjB,SAAU,MAAA,CAAO,QAAA,CACjB,IAAK,MAAA,CAAO,GAAA,CACZ,SAAU,MAAA,CAAO,QAAA,CACjB,UAAW,MAAA,CAAO,SACpB,EACA,OAAO,SACT,CAGO,SAAS,4BAAA,CAA6B,OAAuC,CAClF,OAAO,iBAAiB,8BAAA,CAA+B,MAAM,CAAC,CAChE,CASO,SAAS,2BAAA,CAA4B,MAAA,CAA2C,CACrF,OAAO,IAAI,aAAY,CAAE,MAAA,CACvB,+BAAiC,4BAAA,CAA6B,MAAM,CACtE,CACF,CA0EA,SAAS,aAAa,KAAA,CAAmC,CACvD,MAAM,MAAA,CAAS,IAAA,CAAK,MAAM,KAAK,CAAA,CAC/B,OAAO,MAAA,CAAO,QAAA,CAAS,MAAM,CAAA,CAAI,MAAA,CAAS,MAC5C,CAOA,IAAM,oBAAsB,qBAAA,CAgB5B,SAAS,kBAAkB,GAAA,CAA+C,CACxE,GAAI,GAAA,GAAQ,IAAA,EAAQ,OAAO,GAAA,GAAQ,QAAA,CAAU,OAAO,KAAA,CACpD,GAAK,IAA8B,OAAA,GAAY,KAAA,CAAO,OAAO,KAAA,CAC7D,MAAM,IAAO,GAAA,CAAoC,aAAA,CACjD,OAAO,OAAO,GAAA,GAAQ,QAAA,EAAY,mBAAA,CAAoB,IAAA,CAAK,GAAG,CAChE,CAWA,SAAS,qBAAqB,SAAA,CAAmD,CAC/E,MAAM,aAAA,CAAgB,SAAA,EAAa,4BACnC,GACE,CAAC,OAAO,aAAA,CAAc,aAAa,GACnC,aAAA,EAAiB,CAAA,EACjB,cAAgB,2BAAA,CAChB,CACA,OAAO,MACT,CACA,OAAO,aACT,CAOA,SAAS,qBAAA,CACP,MAAA,CACA,IACA,aAAA,CACS,CACT,MAAM,QAAA,CAAW,YAAA,CAAa,OAAO,QAAQ,CAAA,CAC7C,MAAM,SAAA,CAAY,YAAA,CAAa,OAAO,SAAS,CAAA,CAC/C,GAAI,QAAA,GAAa,MAAA,EAAa,SAAA,GAAc,OAAW,OAAO,KAAA,CAC9D,GAAI,SAAA,EAAa,QAAA,CAAU,OAAO,KAAA,CAClC,GAAI,UAAY,QAAA,CAAW,aAAA,CAAe,OAAO,KAAA,CAEjD,MAAM,QAAU,GAAA,CAAI,OAAA,GACpB,GAAI,CAAC,OAAO,QAAA,CAAS,OAAO,EAAG,OAAO,KAAA,CACtC,OAAO,OAAA,EAAW,QAAA,EAAY,QAAU,SAC1C,CAmBA,eAAsB,qBAAA,CACpB,KAAA,CACA,KAC4C,CAC5C,MAAM,cAAgB,oBAAA,CAAqB,IAAA,CAAK,aAAa,CAAA,CAC7D,GAAI,aAAA,GAAkB,MAAA,CAAW,OAAO,MAAA,CAExC,IAAI,QAAA,CACJ,GAAI,CACF,QAAA,CAAW,4BAAA,CAA6B,KAAK,EAC/C,CAAA,KAAQ,CACN,OAAO,MACT,CACA,MAAM,MAAA,CAAS,SAAS,SAAA,CAQxB,MAAM,IAAM,MAAM,IAAA,CAAK,aAAa,MAAA,CAAO,QAAQ,EACnD,GAAI,CAAC,kBAAkB,GAAG,CAAA,CAAG,OAAO,MAAA,CASpC,GAAI,CAAC,qBAAA,CAAsB,MAAA,CAAQ,KAAK,GAAA,CAAK,aAAa,EAAG,OAAO,MAAA,CAEpE,MAAM,QAAA,CAAW,MAAM,IAAA,CAAK,QAAA,CAAS,MAAA,CAAO,CAC1C,UAAW,QAAA,CAAS,SAAA,CAEpB,UAAW,GAAA,CAAI,aAAA,CACf,UAAW,QAAA,CAAS,SAAA,CACpB,aAAc,2BAAA,CAA4B,MAAM,CAClD,CAAC,CAAA,CACD,GAAI,CAAC,QAAA,CAAU,OAAO,MAAA,CAEtB,OAAO,MACT,CAkGA,SAAS,qBAAA,CAAsB,MAAiC,CAC9D,OAAO,OAAO,KAAA,GAAU,QAAA,EAAY,MAAM,MAAA,CAAS,CAAA,EAAK,MAAM,IAAA,EAAK,GAAM,KAC3E,CAEA,SAAS,eAAe,GAAA,CAAc,iBAAA,CAA+D,CACnG,GAAI,GAAA,GAAQ,IAAA,EAAQ,OAAO,GAAA,GAAQ,QAAA,CAAU,OAAO,KAAA,CACpD,MAAM,UAAY,GAAA,CAClB,OACE,WAAW,SAAA,CAAU,QAAQ,GAC7B,qBAAA,CAAsB,SAAA,CAAU,SAAS,CAAA,EACzC,SAAA,CAAU,WAAa,iBAE3B,CASA,eAAsB,2BAAA,CACpB,KAAA,CACA,KACmD,CACnD,GACE,CAAC,qBAAA,CAAsB,IAAA,CAAK,SAAS,MAAM,CAAA,EAC3C,CAAC,qBAAA,CAAsB,IAAA,CAAK,SAAS,SAAS,CAAA,EAC9C,CAAC,qBAAA,CAAsB,IAAA,CAAK,SAAS,QAAQ,CAAA,EAC7C,eAAe,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,CAAI,mCAAA,CACzC,CACA,OAAO,MACT,CAEA,IAAI,YAAA,CACJ,MAAM,OAAS,MAAM,qBAAA,CAAsB,MAAO,CAChD,QAAA,CAAU,KAAK,QAAA,CACf,YAAA,CAAc,MAAO,QAAA,EAAa,CAChC,MAAM,GAAA,CAAM,MAAM,KAAK,YAAA,CAAa,QAAQ,EAC5C,GAAI,CAAC,eAAe,GAAA,CAAK,QAAQ,EAAG,OAAO,MAAA,CAC3C,aAAe,GAAA,CACf,OAAO,CAAE,aAAA,CAAe,GAAA,CAAI,cAAe,OAAA,CAAS,GAAA,CAAI,OAAQ,CAClE,CAAA,CACA,GAAA,CAAK,IAAA,CAAK,GAAA,CACV,GAAI,KAAK,aAAA,GAAkB,MAAA,CAAY,EAAC,CAAI,CAAE,cAAe,IAAA,CAAK,aAAc,CAClF,CAAC,CAAA,CACD,GAAI,MAAA,GAAW,MAAA,EAAa,eAAiB,MAAA,CAAW,OAAO,OAE/D,GACE,MAAA,CAAO,SAAW,IAAA,CAAK,QAAA,CAAS,QAChC,MAAA,CAAO,SAAA,GAAc,KAAK,QAAA,CAAS,SAAA,EACnC,OAAO,QAAA,GAAa,IAAA,CAAK,SAAS,QAAA,EAClC,YAAA,CAAa,YAAc,IAAA,CAAK,QAAA,CAAS,WACzC,YAAA,CAAa,QAAA,GAAa,OAAO,QAAA,CACjC,CACA,OAAO,MACT,CAEA,MAAM,SAAW,MAAM,IAAA,CAAK,OAAO,OAAA,CAAQ,CACzC,OAAQ,0BAAA,CACR,QAAA,CAAU,aAAa,QAAA,CACvB,MAAA,CAAQ,OAAO,MAAA,CACf,SAAA,CAAW,aAAa,SAAA,CACxB,QAAA,CAAU,aAAa,QAAA,CACvB,QAAA,CAAU,MAAA,CAAO,QAAA,CACjB,GAAA,CAAK,MAAA,CAAO,IACZ,SAAA,CAAW,MAAA,CAAO,SACpB,CAAC,CAAA,CACD,GAAI,CAAC,QAAA,CAAU,OAAO,MAAA,CAEtB,OAAO,CACL,IAAA,CAAM,QAAA,CACN,OAAQ,CACN,IAAA,CAAM,SACN,QAAA,CAAU,YAAA,CAAa,QAAA,CACvB,SAAA,CAAW,YAAA,CAAa,SAAA,CACxB,SAAU,YAAA,CAAa,QACzB,EACA,MAAA,CAAQ,MAAA,CAAO,OACf,QAAA,CAAU,MAAA,CAAO,SACjB,GAAA,CAAK,MAAA,CAAO,IACZ,QAAA,CAAU,MAAA,CAAO,SACjB,SAAA,CAAW,MAAA,CAAO,SACpB,CACF,KAyCa,kCAAA,CAAqC,QAGrC,oCAAA,CAAuC,IAepD,IAAM,eAAA,CAAkBA,CAAAA,CACrB,QAAO,CACP,GAAA,CAAI,CAAC,CAAA,CACL,GAAA,CAAI,kCAAkC,CAAA,CACtC,MAAA,CAAQ,OAAU,cAAA,CAAe,KAAK,GAAK,kCAAA,CAAoC,CAC9E,OAAA,CAAS,CAAA,gCAAA,EAAmC,kCAAkC,CAAA,YAAA,CAChF,CAAC,CAAA,CACA,KAAA,CAAM,iCAAkC,qDAAqD,CAAA,CAEhG,IAAM,8BAAA,CAAiC,oDAAA,KAG1B,2BAAA,CAA8BA,CAAAA,CACxC,OAAO,CACN,OAAA,CAAS,gBAAgB,KAAA,CAAM,mBAAA,CAAqB,+CAA+C,CAAA,CAChG,MAAA,CAAQ,OAAU,KAAA,GAAU,GAAA,EAAO,QAAU,IAAA,CAAM,mCAAmC,EACtF,MAAA,CACE,KAAA,EAAU,CAAC,QAAA,CAAS,IAAA,CAAK,KAAK,CAAA,EAAK,CAAC,+BAA+B,IAAA,CAAK,KAAK,EAC9E,0DACF,CAAA,CAMF,gBAAiB,eACnB,CAAC,CAAA,CACA,MAAA,GAKH,IAAM,iBAAmBA,CAAAA,CACtB,MAAA,GACA,GAAA,CAAI,CAAC,EACL,GAAA,CAAI,oCAAoC,EACxC,KAAA,CAAM,iCAAA,CAAmC,mDAAmD,CAAA,CAQ/F,IAAM,cAAgBA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAO/B,IAAM,yBAAA,CAA4BA,EAAE,YAAA,CAAa,CACtD,QAASA,CAAAA,CAAE,OAAA,CAAQ,sBAAsB,CAAA,CAEzC,MAAA,CAAQA,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CACxB,UAAWA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,CAAA,CAE3B,QAAA,CAAUA,CAAAA,CAAE,MAAA,GAAS,GAAA,CAAI,CAAC,EAE1B,QAAA,CAAU,kBAAA,CAEV,IAAKA,CAAAA,CAAE,MAAA,GAAS,KAAA,CAAM,WAAW,EACjC,QAAA,CAAUA,CAAAA,CAAE,IAAI,QAAA,EAAS,CACzB,UAAWA,CAAAA,CAAE,GAAA,CAAI,QAAA,EAAS,CAE1B,MAAA,CAAQ,aAAA,CAER,SAAU,2BAAA,CAEV,SAAA,CAAW,gBACb,CAAC,MAIY,6BAAA,CAAgCA,CAAAA,CAAE,aAAa,CAC1D,MAAA,CAAQA,EAAE,OAAA,CAAQ,wBAAwB,EAC1C,SAAA,CAAWA,CAAAA,CAAE,KAAK,2BAA2B,CAAA,CAC7C,SAAA,CAAW,yBAAA,CAEX,SAAA,CAAWA,CAAAA,CAAE,QAAO,CAAE,KAAA,CAAM,iBAAiB,CAC/C,CAAC,EAUM,SAAS,0BAAA,CAA2B,MAAyC,CAClF,MAAM,OAAS,6BAAA,CAA8B,SAAA,CAAU,KAAK,CAAA,CAC5D,GAAI,CAAC,MAAA,CAAO,OAAA,CAAS,CACnB,MAAM,IAAI,cACR,4BAAA,CACA,CAAA,iCAAA,EAAoC,OAAO,KAAA,CAAM,MAAA,CAC9C,IAAK,KAAA,EAAU,CAAA,EAAG,MAAM,IAAA,CAAK,IAAA,CAAK,GAAG,CAAA,EAAK,QAAQ,KAAK,KAAA,CAAM,OAAO,EAAE,CAAA,CACtE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CACb,CAAE,MAAO,MAAA,CAAO,KAAM,CACxB,CACF,CACA,OAAO,MAAA,CAAO,IAChB,CAUO,SAAS,4BAAA,CAA6B,OAAyC,CACpF,MAAM,UAAuC,CAC3C,OAAA,CAAS,OAAO,OAAA,CAChB,MAAA,CAAQ,OAAO,MAAA,CACf,SAAA,CAAW,OAAO,SAAA,CAClB,QAAA,CAAU,OAAO,QAAA,CACjB,QAAA,CAAU,OAAO,QAAA,CACjB,GAAA,CAAK,OAAO,GAAA,CACZ,QAAA,CAAU,OAAO,QAAA,CACjB,SAAA,CAAW,OAAO,SAAA,CAClB,MAAA,CAAQ,OAAO,MAAA,CACf,QAAA,CAAU,CACR,OAAA,CAAS,MAAA,CAAO,QAAA,CAAS,QACzB,eAAA,CAAiB,MAAA,CAAO,SAAS,eACnC,CAAA,CACA,UAAW,MAAA,CAAO,SACpB,EACA,OAAO,SACT,CAGO,SAAS,0BAAA,CAA2B,OAAqC,CAC9E,OAAO,iBAAiB,4BAAA,CAA6B,MAAM,CAAC,CAC9D,CASO,SAAS,yBAAA,CAA0B,MAAA,CAAyC,CACjF,OAAO,IAAI,aAAY,CAAE,MAAA,CACvB,6BAA+B,0BAAA,CAA2B,MAAM,CAClE,CACF,CAiBA,eAAsB,mBAAA,CACpB,KAAA,CACA,KAC0C,CAC1C,MAAM,aAAA,CAAgB,oBAAA,CAAqB,IAAA,CAAK,aAAa,EAC7D,GAAI,aAAA,GAAkB,OAAW,OAAO,MAAA,CAExC,IAAI,QAAA,CACJ,GAAI,CACF,QAAA,CAAW,0BAAA,CAA2B,KAAK,EAC7C,CAAA,KAAQ,CACN,OAAO,MACT,CACA,MAAM,MAAA,CAAS,QAAA,CAAS,SAAA,CAExB,MAAM,GAAA,CAAM,MAAM,IAAA,CAAK,YAAA,CAAa,OAAO,QAAQ,CAAA,CACnD,GAAI,CAAC,iBAAA,CAAkB,GAAG,CAAA,CAAG,OAAO,OAEpC,GAAI,CAAC,sBAAsB,MAAA,CAAQ,IAAA,CAAK,IAAK,aAAa,CAAA,CAAG,OAAO,MAAA,CAEpE,MAAM,QAAA,CAAW,MAAM,IAAA,CAAK,QAAA,CAAS,OAAO,CAC1C,SAAA,CAAW,SAAS,SAAA,CACpB,SAAA,CAAW,IAAI,aAAA,CACf,SAAA,CAAW,SAAS,SAAA,CACpB,YAAA,CAAc,0BAA0B,MAAM,CAChD,CAAC,CAAA,CACD,GAAI,CAAC,QAAA,CAAU,OAAO,OAEtB,OAAO,MACT,CAgDA,eAAsB,yBAAA,CACpB,MACA,IAAA,CACiD,CACjD,GACE,CAAC,qBAAA,CAAsB,KAAK,QAAA,CAAS,MAAM,GAC3C,CAAC,qBAAA,CAAsB,KAAK,QAAA,CAAS,SAAS,CAAA,EAC9C,CAAC,qBAAA,CAAsB,IAAA,CAAK,SAAS,QAAQ,CAAA,EAC7C,eAAe,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,CAAI,mCAAA,CACzC,CACA,OAAO,MACT,CAEA,IAAI,YAAA,CACJ,MAAM,MAAA,CAAS,MAAM,oBAAoB,KAAA,CAAO,CAC9C,SAAU,IAAA,CAAK,QAAA,CACf,aAAc,MAAO,QAAA,EAAa,CAChC,MAAM,GAAA,CAAM,MAAM,IAAA,CAAK,YAAA,CAAa,QAAQ,CAAA,CAC5C,GAAI,CAAC,cAAA,CAAe,GAAA,CAAK,QAAQ,CAAA,CAAG,OAAO,OAC3C,YAAA,CAAe,GAAA,CACf,OAAO,CAAE,aAAA,CAAe,GAAA,CAAI,cAAe,OAAA,CAAS,GAAA,CAAI,OAAQ,CAClE,CAAA,CACA,IAAK,IAAA,CAAK,GAAA,CACV,GAAI,IAAA,CAAK,aAAA,GAAkB,OAAY,EAAC,CAAI,CAAE,aAAA,CAAe,IAAA,CAAK,aAAc,CAClF,CAAC,EACD,GAAI,MAAA,GAAW,QAAa,YAAA,GAAiB,MAAA,CAAW,OAAO,MAAA,CAE/D,GACE,OAAO,MAAA,GAAW,IAAA,CAAK,SAAS,MAAA,EAChC,MAAA,CAAO,YAAc,IAAA,CAAK,QAAA,CAAS,WACnC,MAAA,CAAO,QAAA,GAAa,KAAK,QAAA,CAAS,QAAA,EAClC,YAAA,CAAa,SAAA,GAAc,IAAA,CAAK,QAAA,CAAS,WACzC,YAAA,CAAa,QAAA,GAAa,OAAO,QAAA,CACjC,CACA,OAAO,MACT,CAEA,MAAM,QAAA,CAAW,MAAM,KAAK,MAAA,CAAO,OAAA,CAAQ,CACzC,MAAA,CAAQ,wBAAA,CACR,SAAU,YAAA,CAAa,QAAA,CACvB,MAAA,CAAQ,MAAA,CAAO,MAAA,CACf,SAAA,CAAW,aAAa,SAAA,CACxB,QAAA,CAAU,aAAa,QAAA,CACvB,QAAA,CAAU,OAAO,QAAA,CACjB,GAAA,CAAK,OAAO,GAAA,CACZ,SAAA,CAAW,OAAO,SACpB,CAAC,EACD,GAAI,CAAC,SAAU,OAAO,MAAA,CAEtB,OAAO,CACL,IAAA,CAAM,MAAA,CACN,OAAQ,CACN,IAAA,CAAM,SACN,QAAA,CAAU,YAAA,CAAa,SACvB,SAAA,CAAW,YAAA,CAAa,UACxB,QAAA,CAAU,YAAA,CAAa,QACzB,CAAA,CACA,MAAA,CAAQ,OAAO,MAAA,CACf,QAAA,CAAU,OAAO,QAAA,CACjB,GAAA,CAAK,OAAO,GAAA,CACZ,QAAA,CAAU,OAAO,QAAA,CACjB,SAAA,CAAW,OAAO,SAAA,CAClB,MAAA,CAAQ,OAAO,MAAA,CACf,QAAA,CAAU,OAAO,QAAA,CACjB,SAAA,CAAW,OAAO,SACpB,CACF,CCt8BO,SAAS,eAAA,EAAmC,CACjD,MAAM,MAAA,CAAU,WAAyD,MAAA,EAAQ,MAAA,CACjF,GAAI,MAAA,GAAW,MAAA,CAAW,CACxB,MAAM,IAAI,cAAc,uBAAA,CAAyB,iDAAiD,CACpG,CACA,OAAO,MACT,CCbA,IAAM,OAAS,EAAA,CACf,IAAM,OAAS,CAAA,CACf,IAAM,QAAU,CAAA,CAGT,IAAM,2BAA6B,EAAA,CAC1C,IAAM,SAAW,EAAA,CACjB,IAAM,IAAM,EAAA,CACZ,IAAM,IAAM,EAAA,CACZ,IAAM,IAAM,EAAA,CAEL,IAAM,oBAAsB,EAAA,CAEnC,IAAM,SAAA,CAAY,CAAA,CAClB,IAAM,OAAA,CAAU,KAAK,SAAS,CAAA,CAC9B,IAAM,YAAA,CAAe,MAAA,CAAO,KAAK,KAAK,CAAA,CAAG,MAAM,MAAA,CAAQ,CAAC,CAAC,CAAA,CACzD,IAAM,cAAgB,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAG,KAAA,CAAM,OAAQ,CAAC,CAAA,CAAG,MAAM,MAAA,CAAQ,CAAC,EAAG,KAAA,CAAM,OAAA,CAAS,CAAC,CAAC,CAAA,CAChG,IAAM,KAAA,CAAQ,IAAI,WAAW,CAAC,CAAA,CAE9B,IAAM,SAAA,CAAY,IAAI,WAAW,GAAG,CAAA,CAIpC,SAAS,IAAA,CAAK,KAAA,CAAsB,CAClC,OAAO,IAAI,WAAA,GAAc,MAAA,CAAO,KAAK,CACvC,CAEA,SAAS,UAAU,KAAA,CAAqC,CACtD,MAAM,MAAA,CAAS,KAAA,CAAM,OAAO,CAAC,KAAA,CAAO,OAAS,KAAA,CAAQ,IAAA,CAAK,UAAA,CAAY,CAAC,CAAA,CACvE,MAAM,IAAM,IAAI,UAAA,CAAW,MAAM,CAAA,CACjC,IAAI,OAAS,CAAA,CACb,IAAA,MAAW,QAAQ,KAAA,CAAO,CACxB,IAAI,GAAA,CAAI,IAAA,CAAM,MAAM,CAAA,CACpB,MAAA,EAAU,KAAK,WACjB,CACA,OAAO,GACT,CAEA,SAAS,MAAM,KAAA,CAAe,MAAA,CAAuB,CACnD,GAAI,CAAC,OAAO,aAAA,CAAc,KAAK,GAAK,KAAA,CAAQ,CAAA,CAAG,CAC7C,MAAM,IAAI,cAAc,uBAAA,CAAyB,4DAA4D,CAC/G,CACA,MAAM,IAAM,IAAI,UAAA,CAAW,MAAM,CAAA,CACjC,IAAI,UAAY,KAAA,CAChB,IAAA,IAAS,MAAQ,MAAA,CAAS,CAAA,CAAG,OAAS,CAAA,CAAG,KAAA,EAAS,EAAG,CACnD,GAAA,CAAI,KAAK,CAAA,CAAI,SAAA,CAAY,IACzB,SAAA,CAAY,IAAA,CAAK,KAAA,CAAM,SAAA,CAAY,GAAG,EACxC,CACA,GAAI,SAAA,GAAc,EAAG,CACnB,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,+CAA+C,CAClG,CACA,OAAO,GACT,CAEA,SAAS,IAAA,CAAK,KAAA,CAA0B,CACtC,OAAO,IAAI,WAAW,KAAK,CAC7B,CAEA,eAAe,UAAA,CAAW,IAAiB,IAAA,CAAkC,CAC3E,MAAM,MAAA,CAAS,eAAA,GACf,MAAM,OAAA,CAAU,MAAM,MAAA,CAAO,SAAA,CAAU,MAAO,IAAA,CAAK,GAAG,EAAG,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,SAAU,CAAA,CAAG,MAAO,CAAC,MAAM,CAAC,CAAA,CAC3G,OAAO,IAAI,UAAA,CAAW,MAAM,OAAO,IAAA,CAAK,MAAA,CAAQ,QAAS,IAAA,CAAK,IAAI,CAAC,CAAC,CACtE,CAEA,eAAe,UAAA,CAAW,IAAiB,IAAA,CAAkB,MAAA,CAAgC,CAC3F,GAAI,MAAA,CAAS,IAAM,GAAA,CAAK,CACtB,MAAM,IAAI,aAAA,CAAc,wBAAyB,sCAAsC,CACzF,CACA,MAAM,GAAA,CAAM,IAAI,UAAA,CAAW,MAAM,EACjC,IAAI,QAAA,CAAuB,KAAA,CAC3B,IAAI,MAAA,CAAS,CAAA,CACb,QAAS,OAAA,CAAU,CAAA,CAAG,OAAS,MAAA,CAAQ,OAAA,EAAW,EAAG,CACnD,QAAA,CAAW,MAAM,UAAA,CAAW,GAAA,CAAK,OAAO,QAAA,CAAU,IAAA,CAAM,WAAW,EAAA,CAAG,OAAO,CAAC,CAAC,CAAA,CAC/E,MAAM,IAAA,CAAO,IAAA,CAAK,GAAA,CAAI,SAAS,UAAA,CAAY,MAAA,CAAS,MAAM,CAAA,CAC1D,GAAA,CAAI,IAAI,QAAA,CAAS,QAAA,CAAS,EAAG,IAAI,CAAA,CAAG,MAAM,CAAA,CAC1C,MAAA,EAAU,KACZ,CACA,OAAO,GACT,CAEA,eAAe,cAAA,CAAe,OAAA,CAAqB,IAAA,CAAkB,KAAA,CAAe,IAAiC,CACnH,OAAO,WAAW,IAAA,CAAK,UAAA,GAAe,EAAI,SAAA,CAAY,IAAA,CAAM,OAAO,OAAA,CAAS,OAAA,CAAS,KAAK,KAAK,CAAA,CAAG,GAAG,CAAC,CACxG,CAEA,eAAe,aAAA,CACb,QACA,GAAA,CACA,KAAA,CACA,KACA,MAAA,CACgB,CAChB,OAAO,UAAA,CAAW,GAAA,CAAK,OAAO,KAAA,CAAM,MAAA,CAAQ,CAAC,CAAA,CAAG,OAAA,CAAS,QAAS,IAAA,CAAK,KAAK,EAAG,IAAI,CAAA,CAAG,MAAM,CAC9F,CAQA,eAAsB,mBAAA,CAAoB,GAAA,CAAwC,CAChF,GAAI,GAAA,CAAI,UAAA,GAAe,4BAA8B,GAAA,CAAI,CAAC,IAAM,CAAA,CAAM,CACpE,MAAM,IAAI,aAAA,CAAc,wBAAyB,uDAAuD,CAC1G,CACA,GAAI,CACF,OAAO,MAAM,eAAA,GAAkB,SAAA,CAAU,KAAA,CAAO,KAAK,GAAG,CAAA,CAAG,CAAE,IAAA,CAAM,MAAA,CAAQ,WAAY,OAAQ,CAAA,CAAG,KAAM,EAAE,CAC5G,CAAA,MAAS,KAAA,CAAO,CACd,MAAM,IAAI,cAAc,uBAAA,CAAyB,6CAAA,CAA+C,CAAE,KAAM,CAAC,CAC3G,CACF,CAEA,eAAe,SAAS,UAAA,CAA0B,SAAA,CAAyC,CACzF,MAAM,IAAA,CAAO,MAAM,eAAA,EAAgB,CAAE,WAAW,CAAE,IAAA,CAAM,OAAQ,MAAA,CAAQ,SAAU,EAAG,UAAA,CAAY,QAAA,CAAW,CAAC,CAAA,CAC7G,OAAO,IAAI,UAAA,CAAW,IAAI,CAC5B,CAEA,eAAe,iBAAiB,EAAA,CAAgB,UAAA,CAAwC,CACtF,MAAM,MAAA,CAAS,MAAM,cAAA,CAAe,YAAA,CAAc,MAAO,SAAA,CAAW,EAAE,EACtE,OAAO,aAAA,CAAc,YAAA,CAAc,MAAA,CAAQ,eAAA,CAAiB,UAAA,CAAY,QAAQ,CAClF,CAUA,eAAe,eAAA,CAAgB,YAAA,CAA0B,KAAgD,CACvG,MAAM,UAAY,MAAM,cAAA,CAAe,cAAe,KAAA,CAAO,aAAA,CAAe,KAAK,CAAA,CACjF,MAAM,SAAW,MAAM,cAAA,CAAe,cAAe,KAAA,CAAO,WAAA,CAAa,IAAI,CAAA,CAC7E,MAAM,QAAU,MAAA,CAAO,UAAA,CAAW,GAAG,SAAS,CAAA,CAAG,UAAW,QAAQ,CAAA,CACpE,MAAM,MAAA,CAAS,MAAM,eAAe,aAAA,CAAe,YAAA,CAAc,SAAU,KAAK,CAAA,CAChF,OAAO,CACL,YAAA,CACA,GAAA,CAAK,MAAM,aAAA,CAAc,aAAA,CAAe,OAAQ,KAAA,CAAO,OAAA,CAAS,GAAG,CAAA,CACnE,SAAA,CAAW,MAAM,aAAA,CAAc,aAAA,CAAe,OAAQ,YAAA,CAAc,OAAA,CAAS,GAAG,CAAA,CAChF,cAAA,CAAgB,MAAM,aAAA,CAAc,aAAA,CAAe,OAAQ,KAAA,CAAO,OAAA,CAAS,GAAG,CAChF,CACF,CASA,eAAsB,eAAA,CACpB,mBACA,IAAA,CACA,SAAA,CAC6D,CAC7D,MAAM,GAAA,CAAM,MAAM,mBAAA,CAAoB,kBAAkB,EACxD,IAAI,IAAA,CAAO,UACX,GAAI,IAAA,GAAS,MAAA,CAAW,CACtB,MAAM,MAAA,CAAS,iBAAgB,CAC/B,MAAM,UAAY,MAAM,MAAA,CAAO,YAAY,CAAE,IAAA,CAAM,OAAQ,UAAA,CAAY,OAAQ,EAAG,IAAA,CAAM,CAAC,YAAY,CAAC,CAAA,CACtG,KAAO,CACL,UAAA,CAAY,UAAU,UAAA,CACtB,SAAA,CAAW,IAAI,UAAA,CAAW,MAAM,OAAO,SAAA,CAAU,KAAA,CAAO,UAAU,SAAS,CAAC,CAC9E,EACF,CACA,MAAM,GAAA,CAAM,IAAA,CAAK,KAAK,SAAS,CAAA,CAC/B,MAAM,EAAA,CAAK,MAAM,QAAA,CAAS,IAAA,CAAK,UAAA,CAAY,GAAG,EAC9C,MAAM,YAAA,CAAe,MAAM,gBAAA,CAAiB,EAAA,CAAI,OAAO,GAAA,CAAK,kBAAkB,CAAC,CAAA,CAC/E,OAAO,CAAE,GAAA,CAAK,QAAA,CAAU,MAAM,eAAA,CAAgB,YAAA,CAAc,IAAI,CAAE,CACpE,CAGA,eAAsB,kBAAA,CACpB,IACA,mBAAA,CACA,kBAAA,CACA,KAC8B,CAC9B,GAAI,mBAAmB,UAAA,GAAe,0BAAA,EAA8B,mBAAmB,CAAC,CAAA,GAAM,EAAM,CAClG,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,iEAAiE,CACpH,CACA,MAAM,GAAA,CAAM,MAAM,mBAAA,CAAoB,GAAG,CAAA,CACzC,IAAI,GACJ,GAAI,CACF,GAAK,MAAM,QAAA,CAAS,oBAAqB,GAAG,EAC9C,OAAS,KAAA,CAAO,CACd,MAAM,IAAI,aAAA,CAAc,4BAA6B,2BAAA,CAA6B,CAAE,KAAM,CAAC,CAC7F,CACA,MAAM,YAAA,CAAe,MAAM,iBAAiB,EAAA,CAAI,MAAA,CAAO,IAAK,kBAAkB,CAAC,EAC/E,OAAO,eAAA,CAAgB,aAAc,IAAI,CAC3C,CAGO,SAAS,SAAA,CAAU,UAAuB,QAAA,CAAyB,CACxE,MAAM,GAAA,CAAM,KAAA,CAAM,QAAA,CAAU,GAAG,CAAA,CAC/B,MAAM,IAAM,IAAI,UAAA,CAAW,GAAG,CAAA,CAC9B,IAAA,IAAS,MAAQ,CAAA,CAAG,KAAA,CAAQ,IAAK,KAAA,EAAS,CAAA,CAAG,IAAI,KAAK,CAAA,CAAI,UAAU,KAAK,CAAA,CAAK,IAAI,KAAK,CAAA,CACvF,OAAO,GACT,CAEA,eAAe,SAAA,CAAU,GAAA,CAAiB,MAAqD,CAC7F,OAAO,iBAAgB,CAAE,SAAA,CAAU,MAAO,IAAA,CAAK,GAAG,EAAG,CAAE,IAAA,CAAM,SAAU,CAAA,CAAG,KAAA,CAAO,CAAC,KAAK,CAAC,CAC1F,CAGA,eAAsB,YAAA,CACpB,SACA,QAAA,CACA,GAAA,CACA,UACgB,CAChB,MAAM,WAAa,MAAM,eAAA,GAAkB,OAAA,CACzC,CAAE,KAAM,SAAA,CAAW,EAAA,CAAI,UAAU,QAAA,CAAS,SAAA,CAAW,QAAQ,CAAA,CAAG,cAAA,CAAgB,KAAK,GAAG,CAAA,CAAG,UAAW,GAAI,CAAA,CAC1G,MAAM,SAAA,CAAU,QAAA,CAAS,IAAK,SAAS,CAAA,CACvC,KAAK,SAAS,CAChB,EACA,OAAO,IAAI,WAAW,UAAU,CAClC,CAGA,eAAsB,YAAA,CACpB,QAAA,CACA,SACA,GAAA,CACA,UAAA,CACgB,CAChB,GAAI,UAAA,CAAW,WAAa,mBAAA,CAAqB,CAC/C,MAAM,IAAI,aAAA,CAAc,wBAAyB,wDAAwD,CAC3G,CACA,GAAI,CACF,MAAM,SAAA,CAAY,MAAM,iBAAgB,CAAE,OAAA,CACxC,CAAE,IAAA,CAAM,SAAA,CAAW,GAAI,SAAA,CAAU,QAAA,CAAS,UAAW,QAAQ,CAAA,CAAG,eAAgB,IAAA,CAAK,GAAG,EAAG,SAAA,CAAW,GAAI,EAC1G,MAAM,SAAA,CAAU,SAAS,GAAA,CAAK,SAAS,CAAA,CACvC,IAAA,CAAK,UAAU,CACjB,EACA,OAAO,IAAI,WAAW,SAAS,CACjC,OAAS,KAAA,CAAO,CACd,MAAM,IAAI,aAAA,CAAc,4BAA6B,uCAAA,CAAyC,CAAE,KAAM,CAAC,CACzG,CACF,CAGA,eAAsB,YAAA,CAAa,KAAA,CAKsB,CACvD,KAAM,CAAE,GAAA,CAAK,QAAS,EAAI,MAAM,eAAA,CAAgB,MAAM,kBAAA,CAAoB,KAAA,CAAM,IAAI,CAAA,CACpF,OAAO,CAAE,GAAA,CAAK,UAAA,CAAY,MAAM,YAAA,CAAa,QAAA,CAAU,EAAG,KAAA,CAAM,GAAA,CAAK,KAAA,CAAM,SAAS,CAAE,CACxF,CAGA,eAAsB,YAAA,CAAa,MAOX,CACtB,MAAM,SAAW,MAAM,kBAAA,CAAmB,MAAM,GAAA,CAAK,KAAA,CAAM,oBAAqB,KAAA,CAAM,kBAAA,CAAoB,MAAM,IAAI,CAAA,CACpH,OAAO,YAAA,CAAa,QAAA,CAAU,EAAG,KAAA,CAAM,GAAA,CAAK,MAAM,UAAU,CAC9D,CC/QO,SAAS,cAAA,CAAoC,OAAW,KAAA,CAA+C,CAC5G,GAAI,CACF,OAAO,OAAO,SAAA,CAAU,KAAK,CAC/B,CAAA,KAAQ,CACN,OAAO,CAAE,OAAA,CAAS,KAAM,CAC1B,CACF,KCgBa,0BAAA,CAA6B,+DAG7B,yBAAA,CAA4B,kCAE5B,qCAAA,CAAwC,MAExC,gCAAA,CAAmC,CAAC,YAAa,cAAA,CAAgB,gBAAA,CAAkB,QAAQ,EAIjG,IAAM,wCAA0C,CAAC,WAAA,CAAa,gBAAgB,EAG9E,IAAM,iCAAmC,EAAA,CAAK,EAAA,CAAK,IAGnD,IAAM,+BAAA,CAAkC,IAGxC,IAAM,gCAAA,CAAmC,KAEzC,IAAM,yBAAA,CAA4B,iCAAmC,EAGrE,IAAM,sBAAwB,GAMrC,IAAM,gBAAkB,kEAAA,CACxB,IAAM,cAAA,CAAiB,kBAAA,CAEhB,SAAS,eAAA,CAAgB,MAA2B,CACzD,IAAI,IAAM,EAAA,CACV,IAAI,MAAQ,CAAA,CACZ,KAAO,MAAQ,CAAA,EAAK,KAAA,CAAM,OAAQ,KAAA,EAAS,CAAA,CAAG,CAC5C,MAAM,KAAA,CAAS,MAAM,KAAK,CAAA,EAAM,GAAO,KAAA,CAAM,KAAA,CAAQ,CAAC,CAAA,EAAM,CAAA,CAAK,MAAM,KAAA,CAAQ,CAAC,EAChF,GAAA,EAAO,eAAA,CAAiB,OAAS,EAAA,CAAM,EAAE,EAAK,eAAA,CAAiB,KAAA,EAAS,GAAM,EAAE,CAAA,CAC5E,gBAAiB,KAAA,EAAS,CAAA,CAAK,EAAE,CAAA,CAAK,eAAA,CAAgB,KAAA,CAAQ,EAAE,EACtE,CACA,MAAM,IAAA,CAAO,KAAA,CAAM,OAAS,KAAA,CAC5B,GAAI,OAAS,CAAA,CAAG,CACd,MAAM,KAAA,CAAQ,KAAA,CAAM,KAAK,CAAA,EAAM,EAAA,CAC/B,KAAO,eAAA,CAAiB,KAAA,EAAS,EAAA,CAAM,EAAE,CAAA,CAAK,eAAA,CAAiB,OAAS,EAAA,CAAM,EAAE,EAClF,CAAA,KAAA,GAAW,IAAA,GAAS,EAAG,CACrB,MAAM,MAAS,KAAA,CAAM,KAAK,GAAM,EAAA,CAAO,KAAA,CAAM,MAAQ,CAAC,CAAA,EAAM,EAC5D,GAAA,EAAO,eAAA,CAAiB,KAAA,EAAS,EAAA,CAAM,EAAE,CAAA,CAAK,gBAAiB,KAAA,EAAS,EAAA,CAAM,EAAE,CAAA,CAC5E,eAAA,CAAiB,OAAS,CAAA,CAAK,EAAE,EACvC,CACA,OAAO,GACT,CAGO,SAAS,gBAAgB,KAAA,CAAe,KAAA,CAAwC,CACrF,GAAI,CAAC,eAAe,IAAA,CAAK,KAAK,GAAK,KAAA,CAAM,MAAA,CAAS,IAAM,CAAA,CAAG,CACzD,MAAM,IAAI,aAAA,CAAc,wBAAyB,CAAA,EAAG,KAAK,6BAA6B,CACxF,CACA,MAAM,GAAA,CAAM,IAAI,WAAW,IAAA,CAAK,KAAA,CAAO,KAAA,CAAM,MAAA,CAAS,CAAA,CAAK,CAAC,CAAC,CAAA,CAC7D,IAAI,OAAS,CAAA,CACb,IAAI,KAAO,CAAA,CACX,IAAI,OAAS,CAAA,CACb,IAAA,MAAW,QAAQ,KAAA,CAAO,CACxB,OAAU,MAAA,EAAU,CAAA,CAAK,gBAAgB,OAAA,CAAQ,IAAI,EACrD,IAAA,EAAQ,CAAA,CACR,GAAI,IAAA,EAAQ,CAAA,CAAG,CACb,IAAA,EAAQ,CAAA,CACR,IAAI,MAAM,CAAA,CAAK,QAAU,IAAA,CAAQ,GAAA,CACjC,QAAU,EACZ,CACF,CACA,GAAI,eAAA,CAAgB,GAAG,CAAA,GAAM,KAAA,CAAO,CAClC,MAAM,IAAI,aAAA,CAAc,wBAAyB,CAAA,EAAG,KAAK,6BAA6B,CACxF,CACA,OAAO,GACT,CAEA,SAAS,cAAA,CAAe,KAAA,CAAyC,CAC/D,OAAOA,CAAAA,CAAE,QAAO,CAAE,WAAA,CAAY,CAAC,KAAA,CAAO,GAAA,GAAQ,CAC5C,GAAI,CACF,MAAM,OAAA,CAAU,eAAA,CAAgB,MAAO,OAAO,CAAA,CAC9C,GAAI,KAAA,CAAM,KAAA,GAAU,QAAa,OAAA,CAAQ,UAAA,GAAe,MAAM,KAAA,CAAO,CACnE,IAAI,QAAA,CAAS,CAAE,KAAM,QAAA,CAAU,OAAA,CAAS,CAAA,uBAAA,EAA0B,KAAA,CAAM,KAAK,CAAA,MAAA,CAAS,CAAC,EACzF,CACA,GAAI,KAAA,CAAM,GAAA,GAAQ,QAAa,OAAA,CAAQ,UAAA,CAAa,MAAM,GAAA,CAAK,CAC7D,IAAI,QAAA,CAAS,CAAE,KAAM,QAAA,CAAU,OAAA,CAAS,0BAA0B,KAAA,CAAM,GAAG,CAAA,MAAA,CAAS,CAAC,EACvF,CACF,MAAQ,CACN,GAAA,CAAI,SAAS,CAAE,IAAA,CAAM,SAAU,OAAA,CAAS,sCAAuC,CAAC,EAClF,CACF,CAAC,CACH,CAMA,eAAe,MAAA,CAAO,KAAA,CAAwC,CAC5D,OAAO,IAAI,UAAA,CAAW,MAAM,eAAA,EAAgB,CAAE,OAAO,SAAA,CAAW,IAAI,WAAW,KAAK,CAAC,CAAC,CACxF,CAEA,SAAS,GAAA,CAAI,KAAA,CAA2B,CACtC,IAAI,GAAA,CAAM,GACV,IAAA,MAAW,IAAA,IAAQ,MAAO,GAAA,EAAO,IAAA,CAAK,SAAS,EAAE,CAAA,CAAE,SAAS,CAAA,CAAG,GAAG,EAClE,OAAO,GACT,CAEA,eAAe,aAAA,CAAc,MAAmC,CAC9D,OAAO,UAAU,GAAA,CAAI,MAAM,OAAO,qBAAA,CAAsB,KAAK,CAAC,CAAC,CAAC,CAAA,CAClE,CAWO,IAAM,sBAAA,CAAyBA,EAAE,YAAA,CAAa,CACnD,IAAKA,CAAAA,CAAE,OAAA,CAAQ,IAAI,CAAA,CACnB,GAAA,CAAKA,EAAE,OAAA,CAAQ,OAAO,EACtB,CAAA,CAAG,cAAA,CAAe,CAAE,KAAA,CAAO,EAAG,CAAC,CAAA,CAC/B,CAAA,CAAG,eAAe,CAAE,KAAA,CAAO,EAAG,CAAC,CACjC,CAAC,EAGM,IAAM,mBAAqBA,CAAAA,CAAE,MAAA,GAAS,KAAA,CAAM,IAAI,OAAO,CAAA,eAAA,EAAkB,qBAAqB,IAAI,CAAC,EAE1G,SAAS,qBAAA,CAAsB,KAAA,CAAkC,CAC/D,MAAM,MAAA,CAAS,cAAA,CAAe,uBAAwB,KAAK,CAAA,CAC3D,GAAI,CAAC,MAAA,CAAO,QAAS,CACnB,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,yDAAyD,CAC5G,CACA,OAAO,MAAA,CAAO,IAChB,CAGO,SAAS,qBAAA,CAAsB,UAAsD,CAC1F,MAAM,IAAM,qBAAA,CAAsB,SAAS,EAC3C,MAAM,GAAA,CAAM,IAAI,UAAA,CAAW,0BAA0B,EACrD,GAAA,CAAI,CAAC,EAAI,CAAA,CACT,GAAA,CAAI,IAAI,eAAA,CAAgB,GAAA,CAAI,EAAG,GAAG,CAAA,CAAG,CAAC,CAAA,CACtC,GAAA,CAAI,GAAA,CAAI,gBAAgB,GAAA,CAAI,CAAA,CAAG,GAAG,CAAA,CAAG,EAAE,EACvC,OAAO,GACT,CAGA,eAAsB,kBAAA,CAAmB,UAA8C,CACrF,MAAM,IAAM,qBAAA,CAAsB,SAAS,EAC3C,MAAM,mBAAA,CAAoB,GAAG,CAAA,CAC7B,OAAO,eAAA,CAAgB,MAAM,MAAA,CAAO,GAAG,CAAC,CAAA,CAAE,KAAA,CAAM,EAAG,qBAAqB,CAC1E,CAMO,IAAM,uBAAA,CAA0BA,EAAE,YAAA,CAAa,CACpD,QAASA,CAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,CACpB,KAAA,CAAO,kBAAA,CACP,KAAA,CAAOA,CAAAA,CAAE,MAAA,GAAS,GAAA,EAAI,CAAE,UAAS,CAAE,GAAA,CAAI,OAAO,gBAAgB,CAAA,CAC9D,UAAW,sBACb,CAAC,EAIM,SAAS,6BAAA,CAA8B,MAAsC,CAClF,MAAM,OAAS,cAAA,CAAe,uBAAA,CAAyB,KAAK,CAAA,CAC5D,GAAI,CAAC,MAAA,CAAO,OAAA,CAAS,CACnB,MAAM,IAAI,cAAc,uBAAA,CAAyB,8BAA8B,CACjF,CACA,MAAM,OAAS,MAAA,CAAO,IAAA,CACtB,OAAO,qBAAA,CAAsB,CAC3B,QAAS,MAAA,CAAO,OAAA,CAChB,KAAA,CAAO,MAAA,CAAO,KAAA,CACd,KAAA,CAAO,OAAO,KAAA,CACd,SAAA,CAAW,CAAE,GAAA,CAAK,MAAA,CAAO,UAAU,GAAA,CAAK,GAAA,CAAK,OAAO,SAAA,CAAU,GAAA,CAAK,EAAG,MAAA,CAAO,SAAA,CAAU,EAAG,CAAA,CAAG,MAAA,CAAO,UAAU,CAAE,CAClH,CAAC,CACH,CAOA,IAAM,cAAA,CAAiBA,CAAAA,CAAE,QAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,GAAG,CAAA,CAAE,WAAA,CAAY,CAAC,KAAA,CAAO,GAAA,GAAQ,CAC5E,GAAI,KAAA,CAAM,MAAK,GAAM,KAAA,EAAS,wBAAA,CAAyB,IAAA,CAAK,KAAK,CAAA,CAAG,CAClE,GAAA,CAAI,QAAA,CAAS,CAAE,IAAA,CAAM,QAAA,CAAU,QAAS,6DAA8D,CAAC,EACzG,CACF,CAAC,EAED,IAAM,wBAAA,CAA2BA,EAAE,MAAA,EAAO,CAAE,OAAO,oBAAA,CAAsB,0CAA0C,EAEnH,IAAM,gBAAA,CAAmBA,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,EAAE,CAAA,CAAE,MAAM,gCAAgC,CAAA,CACzF,IAAM,kBAAA,CAAqBA,CAAAA,CAAE,QAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,EAAE,CAAA,CAAE,KAAA,CAAM,gCAAgC,EAC3F,IAAM,aAAA,CAAgBA,EAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,GAAG,CAAA,CAAE,OAAQ,KAAA,EAAU,KAAA,CAAM,MAAK,GAAM,KAAA,EAAS,CAAC,wBAAA,CAAyB,IAAA,CAAK,KAAK,CAAA,CAAG,qBAAqB,CAAA,CACzJ,IAAM,gBAAA,CAAmBA,CAAAA,CAAE,QAAO,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,GAAA,CAAI,EAAE,CAAA,CAAE,KAAA,CAAM,6BAA6B,CAAA,CAOtF,IAAM,kBAAoBA,CAAAA,CAAE,MAAA,CAAoB,OAAU,CACxD,GAAI,KAAA,GAAU,IAAA,EAAQ,OAAO,KAAA,GAAU,UAAY,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,CAAG,aACzE,GAAI,CACF,iBAAiB,KAAmB,CAAA,CACpC,OAAO,IACT,CAAA,KAAQ,CACN,OAAO,KACT,CACF,CAAA,CAAG,yCAAyC,EAE5C,IAAM,iBAAA,CAAoB,CACxB,OAAA,CAAS,cAAA,CACT,aAAc,kBAAA,CACd,OAAA,CAAS,cACT,OAAA,CAAS,iBAAA,CACT,aAAcA,CAAAA,CAAE,KAAA,CAAM,gBAAgB,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAE,MAAA,CAAQ,QAAW,IAAI,GAAA,CAAI,MAAM,CAAA,CAAE,IAAA,GAAS,MAAA,CAAO,OAAQ,6BAA6B,CACzI,EAQO,IAAM,kCAAA,CAAqCA,EAAE,kBAAA,CAAmB,WAAA,CAAa,CAClFA,CAAAA,CAAE,YAAA,CAAa,CAAE,SAAA,CAAWA,CAAAA,CAAE,QAAQ,WAAW,CAAA,CAAG,GAAG,iBAAkB,CAAC,EAC1EA,CAAAA,CAAE,YAAA,CAAa,CAAE,SAAA,CAAWA,CAAAA,CAAE,QAAQ,cAAc,CAAA,CAAG,GAAG,iBAAkB,CAAC,EAC7EA,CAAAA,CAAE,YAAA,CAAa,CAAE,SAAA,CAAWA,CAAAA,CAAE,QAAQ,gBAAgB,CAAA,CAAG,QAAS,cAAA,CAAgB,YAAA,CAAc,kBAAmB,CAAC,CAAA,CACpHA,CAAAA,CAAE,aAAa,CAAE,SAAA,CAAWA,EAAE,OAAA,CAAQ,QAAQ,EAAG,OAAA,CAAS,cAAe,CAAC,CAC5E,CAAC,EAIM,IAAM,yCAAA,CAA4CA,EAAE,KAAA,CAAM,CAC/DA,EAAE,IAAA,EAAK,CACPA,EAAE,YAAA,CAAa,CACb,WAAY,gBAAA,CACZ,eAAA,CAAiBA,EAAE,MAAA,EAAO,CAAE,MAAM,2BAA2B,CAAA,CAC7D,YAAaA,CAAAA,CAAE,MAAA,GAAS,KAAA,CAAM,oBAAoB,CACpD,CAAC,CACH,CAAC,EAQM,IAAM,0CAAA,CAA6CA,CAAAA,CAAE,MAAA,EAAO,CAAE,IAAI,CAAC,CAAA,CAAE,IAAI,GAAG,CAAA,CAAE,MAAM,qBAAqB,MAEnG,kCAAA,CAAqCA,CAAAA,CAAE,aAAa,CAC/D,QAAA,CAAU,eACV,QAAA,CAAU,cAAA,CACV,QAAS,cAAA,CACT,SAAA,CAAW,cAAA,CACX,SAAA,CAAWA,CAAAA,CAAE,IAAA,CAAK,gCAAgC,CAAA,CAElD,mBAAA,CAAqBA,EAAE,MAAA,EAAO,CAAE,KAAI,CAAE,QAAA,GAAW,GAAA,CAAI,MAAA,CAAO,gBAAgB,CAAA,CAC5E,eAAA,CAAiB,0CAEjB,0BAAA,CAA4B,0CAAA,CAE5B,0BAA2B,0CAAA,CAC3B,YAAA,CAAcA,CAAAA,CAAE,MAAA,EAAO,CAAE,KAAA,CAAM,oBAAoB,CAAA,CACnD,QAAA,CAAU,yBACV,SAAA,CAAW,wBACb,CAAC,EAID,IAAM,qBAAuB,gCAAA,CAAmC,mBAAA,KAEnD,4BAAA,CAA+BA,CAAAA,CAAE,aAAa,CACzD,KAAA,CAAOA,EAAE,OAAA,CAAQ,0BAA0B,EAC3C,KAAA,CAAO,kBAAA,CACP,IAAK,cAAA,CAAe,CAAE,MAAO,0BAA2B,CAAC,EACzD,UAAA,CAAY,cAAA,CAAe,CAAE,GAAA,CAAK,oBAAqB,CAAC,CAC1D,CAAC,EAGD,SAAS,iBAAA,CAAkB,UAAmD,CAC5E,OAAQ,uCAAA,CAA8D,QAAA,CAAS,SAAS,CAC1F,CAEO,IAAM,mCAAA,CAAsCA,EAChD,YAAA,CAAa,CACZ,QAASA,CAAAA,CAAE,OAAA,CAAQ,qCAAqC,CAAA,CACxD,MAAA,CAAQ,mCACR,MAAA,CAAQ,kCAAA,CACR,OAAQ,4BAAA,CAA6B,QAAA,EACvC,CAAC,CAAA,CACA,YAAY,CAAC,OAAA,CAAS,MAAQ,CAC7B,GAAI,QAAQ,MAAA,CAAO,SAAA,GAAc,QAAQ,MAAA,CAAO,SAAA,CAAW,CACzD,GAAA,CAAI,QAAA,CAAS,CAAE,IAAA,CAAM,QAAA,CAAU,KAAM,CAAC,QAAA,CAAU,WAAW,CAAA,CAAG,OAAA,CAAS,8CAA+C,CAAC,EACzH,CACA,GAAI,OAAA,CAAQ,MAAA,CAAO,UAAY,OAAA,CAAQ,MAAA,CAAO,QAAS,CACrD,GAAA,CAAI,SAAS,CAAE,IAAA,CAAM,SAAU,IAAA,CAAM,CAAC,SAAU,SAAS,CAAA,CAAG,QAAS,0CAA2C,CAAC,EACnH,CACA,GAAI,kBAAkB,OAAA,CAAQ,MAAA,CAAO,SAAS,CAAA,IAAO,OAAA,CAAQ,SAAW,MAAA,CAAA,CAAY,CAClF,IAAI,QAAA,CAAS,CAAE,KAAM,QAAA,CAAU,IAAA,CAAM,CAAC,QAAQ,CAAA,CAAG,QAAS,sEAAuE,CAAC,EACpI,CACF,CAAC,EAII,SAAS,gCAAA,CAAiC,KAAA,CAA+C,CAC9F,MAAM,MAAA,CAAS,eAAe,mCAAA,CAAqC,KAAK,EACxE,GAAI,CAAC,OAAO,OAAA,CAAS,CACnB,MAAM,IAAI,aAAA,CACR,wCACA,CAAA,uCAAA,EAAA,CAA2C,MAAA,CAAO,OAAO,MAAA,EAAU,CAAC,CAAE,IAAA,CAAM,GAAI,OAAA,CAAS,iBAAkB,CAAC,CAAA,EACzG,GAAA,CAAK,OAAU,CAAA,EAAG,KAAA,CAAM,KAAK,IAAA,CAAK,GAAG,GAAK,QAAQ,CAAA,EAAA,EAAK,MAAM,OAAO,CAAA,CAAE,CAAA,CACtE,IAAA,CAAK,IAAI,CAAC,EACf,CACF,CACA,OAAO,MAAA,CAAO,IAChB,CAMA,SAAS,UAAA,CAAW,OAAkD,CACpE,OAAO,MACT,CAGA,eAAsB,iCAAiC,MAAA,CAAuD,CAC5G,MAAM,MAAA,CAAS,cAAA,CAAe,mCAAoC,MAAM,CAAA,CACxE,GAAI,CAAC,MAAA,CAAO,QAAS,CACnB,MAAM,IAAI,aAAA,CAAc,uCAAA,CAAyC,yCAAyC,CAC5G,CACA,OAAO,aAAA,CAAc,UAAA,CAAW,OAAO,IAAI,CAAC,CAC9C,CAQO,SAAS,sBAAA,CAAuB,MAAA,CAAsC,KAAA,CAA2B,CACtG,MAAM,MAAA,CAAS,cAAA,CAAe,mCAAoC,MAAM,CAAA,CACxE,GAAI,CAAC,MAAA,CAAO,SAAW,CAAC,cAAA,CAAe,mBAAoB,KAAK,CAAA,CAAE,QAAS,CACzE,MAAM,IAAI,aAAA,CAAc,uCAAA,CAAyC,4CAA4C,CAC/G,CACA,MAAM,KAAA,CAAQ,MAAA,CAAO,KACrB,OAAO,qBAAA,CAAsB,CAC3B,CAAA,CAAG,qCAAA,CACH,SAAU,KAAA,CAAM,QAAA,CAChB,SAAU,KAAA,CAAM,QAAA,CAChB,MACA,SAAA,CAAW,KAAA,CAAM,UACjB,OAAA,CAAS,KAAA,CAAM,OAAA,CACf,SAAA,CAAW,KAAA,CAAM,SAAA,CACjB,oBAAqB,KAAA,CAAM,mBAAA,CAC3B,gBAAiB,KAAA,CAAM,eAAA,GAAoB,KACvC,IAAA,CACA,CACA,WAAY,KAAA,CAAM,eAAA,CAAgB,WAClC,eAAA,CAAiB,KAAA,CAAM,gBAAgB,eAAA,CACvC,WAAA,CAAa,MAAM,eAAA,CAAgB,WACrC,EACF,0BAAA,CAA4B,KAAA,CAAM,2BAClC,yBAAA,CAA2B,KAAA,CAAM,0BACjC,YAAA,CAAc,KAAA,CAAM,aACpB,QAAA,CAAU,KAAA,CAAM,SAChB,SAAA,CAAW,KAAA,CAAM,SACnB,CAAC,CACH,CAOA,eAAsB,iCAAA,CAAkC,QAAyD,CAC/G,MAAM,MAAA,CAAS,gCAAA,CAAiC,OAAO,CAAA,CACvD,OAAO,aAAA,CAAc,MAA+B,CACtD,CAGA,eAAsB,uCAAuC,OAAA,CAAuD,CAClH,MAAM,MAAA,CAAS,gCAAA,CAAiC,OAAO,CAAA,CACvD,GAAK,MAAM,gCAAA,CAAiC,MAAA,CAAO,MAAM,CAAA,GAAO,MAAA,CAAO,MAAA,CAAO,YAAA,CAAc,CAC1F,MAAM,IAAI,aAAA,CAAc,uCAAA,CAAyC,+DAA+D,CAClI,CACF,CAOO,SAAS,iBAAA,CAAkB,OAAyC,CACzE,MAAM,MAAQ,IAAI,WAAA,GAAc,MAAA,CAAO,MAAM,EAC7C,GAAI,KAAA,CAAM,UAAA,GAAe,CAAA,EAAK,KAAA,CAAM,UAAA,CAAa,0BAA2B,CAC1E,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,gCAAgC,yBAAyB,CAAA,YAAA,CAAc,CAC1H,CACA,MAAM,MAAQ,IAAA,CAAK,IAAA,CAAA,CAAM,MAAM,UAAA,CAAa,CAAA,EAAK,+BAA+B,CAAA,CAAI,+BAAA,CACpF,MAAM,GAAA,CAAM,IAAI,WAAW,KAAK,CAAA,CAChC,IAAI,CAAC,CAAA,CAAI,MAAM,UAAA,EAAc,CAAA,CAC7B,IAAI,CAAC,CAAA,CAAI,MAAM,UAAA,CAAa,GAAA,CAC5B,IAAI,GAAA,CAAI,KAAA,CAAO,CAAC,CAAA,CAChB,OAAO,GACT,CAGO,SAAS,mBAAA,CAAoB,OAA4B,CAC9D,GACE,OAAO,UAAA,CAAa,+BAAA,EACjB,OAAO,UAAA,CAAa,gCAAA,EACpB,OAAO,UAAA,CAAa,+BAAA,GAAoC,EAC3D,CACA,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,8CAA8C,CACjG,CACA,MAAM,MAAA,CAAU,MAAA,CAAO,CAAC,CAAA,EAAM,CAAA,CAAK,OAAO,CAAC,CAAA,CAC3C,GAAI,MAAA,GAAW,CAAA,EAAK,OAAS,CAAA,CAAI,MAAA,CAAO,YAAc,MAAA,CAAO,UAAA,EAAc,OAAS,CAAA,CAAA,EAAM,+BAAA,CAAiC,CACzH,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,qDAAqD,CACxG,CACA,IAAA,IAAS,KAAA,CAAQ,OAAS,CAAA,CAAG,KAAA,CAAQ,OAAO,UAAA,CAAY,KAAA,EAAS,EAAG,CAClE,GAAI,OAAO,KAAK,CAAA,GAAM,EAAG,CACvB,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,6CAA6C,CAChG,CACF,CACA,GAAI,CACF,OAAO,IAAI,WAAA,CAAY,QAAS,CAAE,KAAA,CAAO,KAAM,SAAA,CAAW,IAAK,CAAC,CAAA,CAAE,MAAA,CAAO,OAAO,QAAA,CAAS,CAAA,CAAG,OAAS,CAAC,CAAC,CACzG,CAAA,KAAQ,CACN,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,oCAAoC,CACvF,CACF,CAMA,IAAM,UAAA,CAAa,IAAkB,IAAI,WAAA,GAAc,MAAA,CAAO,yBAAyB,EAkBvF,eAAsB,+BAAA,CACpB,MACwC,CACxC,MAAM,YAAA,CAAe,cAAA,CAAe,kCAAA,CAAoC,KAAA,CAAM,MAAM,CAAA,CACpF,GAAI,CAAC,YAAA,CAAa,OAAA,CAAS,CACzB,MAAM,IAAI,cAAc,uCAAA,CAAyC,yCAAyC,CAC5G,CACA,MAAM,OAAS,YAAA,CAAa,IAAA,CAC5B,MAAM,YAAA,CAAe,cAAA,CAAe,kCAAA,CAAoC,CACtE,GAAG,KAAA,CAAM,OACT,YAAA,CAAc,MAAM,iCAAiC,MAAM,CAC7D,CAAC,CAAA,CACD,GAAI,CAAC,YAAA,CAAa,OAAA,CAAS,CACzB,MAAM,IAAI,cAAc,uCAAA,CAAyC,yCAAyC,CAC5G,CACA,MAAM,OAAS,YAAA,CAAa,IAAA,CAC5B,MAAM,WAAA,CAAc,iBAAA,CAAkB,OAAO,SAAS,CAAA,CACtD,GAAI,WAAA,IAAiB,KAAA,CAAM,SAAW,MAAA,CAAA,EAAc,WAAA,IAAiB,MAAM,SAAA,GAAc,MAAA,CAAA,CAAY,CACnG,MAAM,IAAI,cACR,uCAAA,CACA,8EACF,CACF,CACA,IAAI,MAAA,CACJ,GAAI,WAAA,CAAa,CACf,MAAM,SAAA,CAAY,KAAA,CAAM,UACxB,MAAM,SAAA,CAAY,sBAAsB,SAAA,CAAU,SAAS,EAC3D,GAAK,MAAM,mBAAmB,SAAS,CAAA,GAAO,UAAU,KAAA,CAAO,CAC7D,MAAM,IAAI,aAAA,CAAc,wBAAyB,8CAA8C,CACjG,CACA,KAAM,CAAE,IAAK,UAAW,CAAA,CAAI,MAAM,YAAA,CAAa,CAC7C,mBAAoB,qBAAA,CAAsB,SAAS,EACnD,IAAA,CAAM,UAAA,GACN,GAAA,CAAK,sBAAA,CAAuB,MAAA,CAAQ,SAAA,CAAU,KAAK,CAAA,CACnD,UAAW,iBAAA,CAAkB,KAAA,CAAM,MAAO,CAC5C,CAAC,EACD,MAAA,CAAS,CACP,MAAO,0BAAA,CACP,KAAA,CAAO,UAAU,KAAA,CACjB,GAAA,CAAK,gBAAgB,GAAG,CAAA,CACxB,WAAY,eAAA,CAAgB,UAAU,CACxC,EACF,CACA,OAAO,gCAAA,CAAiC,CACtC,QAAS,qCAAA,CACT,MAAA,CACA,OACA,GAAI,MAAA,GAAW,OAAY,EAAC,CAAI,CAAE,MAAO,CAC3C,CAAC,CACH,CAgBA,eAAsB,8BAAA,CAA+B,KAAA,CAGjC,CAClB,MAAM,OAAA,CAAU,gCAAA,CAAiC,MAAM,OAAO,CAAA,CAC9D,MAAM,MAAA,CAAS,OAAA,CAAQ,OACvB,GAAI,MAAA,GAAW,OAAW,CACxB,MAAM,IAAI,aAAA,CAAc,uCAAA,CAAyC,wDAAwD,CAC3H,CACA,MAAM,SAAA,CAAY,qBAAA,CAAsB,KAAA,CAAM,SAAA,CAAU,SAAS,CAAA,CACjE,GAAI,MAAA,CAAO,KAAA,GAAU,MAAM,SAAA,CAAU,KAAA,EAAU,MAAM,kBAAA,CAAmB,SAAS,IAAO,KAAA,CAAM,SAAA,CAAU,MAAO,CAC7G,MAAM,IAAI,aAAA,CAAc,uBAAA,CAAyB,oDAAoD,CACvG,CACA,MAAM,sCAAA,CAAuC,OAAO,CAAA,CACpD,MAAM,UAAA,CAAa,eAAA,CAAgB,OAAO,UAAA,CAAY,YAAY,EAClE,MAAM,YAAA,CAAe,WAAW,UAAA,CAAa,mBAAA,CAC7C,GACE,YAAA,CAAe,+BAAA,EACZ,aAAe,gCAAA,EACf,YAAA,CAAe,kCAAoC,CAAA,CACtD,CACA,MAAM,IAAI,aAAA,CAAc,wBAAyB,gDAAgD,CACnG,CACA,MAAM,MAAA,CAAS,MAAM,YAAA,CAAa,CAChC,oBAAqB,KAAA,CAAM,SAAA,CAAU,WACrC,kBAAA,CAAoB,qBAAA,CAAsB,SAAS,CAAA,CACnD,GAAA,CAAK,gBAAgB,MAAA,CAAO,GAAA,CAAK,KAAK,CAAA,CACtC,IAAA,CAAM,UAAA,GACN,GAAA,CAAK,sBAAA,CAAuB,QAAQ,MAAA,CAAQ,MAAA,CAAO,KAAK,CAAA,CACxD,UACF,CAAC,CAAA,CACD,GAAI,CACF,OAAO,mBAAA,CAAoB,MAAM,CACnC,CAAA,OAAE,CACA,MAAA,CAAO,IAAA,CAAK,CAAC,EACf,CACF,CCvkBO,IAAM,kCAAA,CAAqC,8BAsBlD,eAAsB,gCAAA,CAAiC,MAAsD,CAC3G,MAAM,UAAwB,CAC5B,CAAA,CAAG,mCACH,QAAA,CAAU,KAAA,CAAM,SAChB,QAAA,CAAU,KAAA,CAAM,SAChB,QAAA,CAAU,KAAA,CAAM,QAAA,CAChB,QAAA,CAAU,CAAE,OAAA,CAAS,MAAM,QAAA,CAAS,OAAA,CAAS,gBAAiB,KAAA,CAAM,QAAA,CAAS,eAAgB,CAAA,CAC7F,IAAA,CAAM,MAAM,IAAA,CACZ,SAAA,CAAW,MAAM,SAAA,CACjB,YAAA,CAAc,MAAM,YAAA,CACpB,cAAA,CAAgB,MAAM,cAAA,CACtB,WAAA,CAAa,MAAM,WACrB,CAAA,CACA,MAAM,MAAA,CAAS,IAAI,WACjB,MAAM,eAAA,GAAkB,MAAA,CAAO,SAAA,CAAW,IAAI,UAAA,CAAW,qBAAA,CAAsB,SAAS,CAAC,CAAC,CAC5F,CAAA,CACA,IAAID,KAAM,EAAA,CACV,IAAA,MAAW,IAAA,IAAQ,MAAA,CAAQA,IAAAA,EAAO,IAAA,CAAK,SAAS,EAAE,CAAA,CAAE,SAAS,CAAA,CAAG,GAAG,EACnE,OAAO,CAAA,OAAA,EAAUA,IAAG,CAAA,CACtB,KC7Ba,oBAAA,CAAuB,kBAU7B,SAAS,iBAAA,CAAkB,KAAA,CAA2B,CAC3D,OAAO,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,oBAAA,CAAuB,KAAK,CAC9D,KC9Ba,qBAAA,CAAN,KAA4B,CAIjC,WAAA,CAA6B,KAAA,CAAc,CAAd,IAAA,CAAA,KAAA,CAAA,MAAe,CAAf,MAHpB,MAAA,CAAS,IAAI,IACb,aAAA,CAAgB,IAAI,IACpB,UAAA,CAAa,IAAI,GAAA,CAE1B,eAAA,CAAgB,GAAA,CAA4C,CAAE,OAAO,IAAA,CAAK,aAAA,CAAc,IAAI,GAAG,CAAG,CAClG,gBAAA,CAAiB,GAAA,CAAa,OAAiC,CAAE,IAAA,CAAK,cAAc,GAAA,CAAI,GAAA,CAAK,MAAM,EAAG,CACtG,kBAAkB,GAAA,CAAmB,CAAE,KAAK,aAAA,CAAc,MAAA,CAAO,GAAG,EAAG,CACvE,cAA8D,CAAE,OAAO,KAAK,aAAA,CAAc,OAAA,EAAW,CACrG,SAAA,CAAU,OAAsC,CAC9C,IAAI,MAAQ,IAAA,CAAK,MAAA,CAAO,IAAI,MAAM,CAAA,CAClC,GAAI,KAAA,GAAU,MAAA,CAAW,CACvB,MAAQ,CAAE,oBAAA,CAAsB,GAAI,oBAAA,CAAsB,EAAA,CAAI,cAAe,EAAA,CAAI,WAAA,CAAa,GAAI,SAAA,CAAW,IAAA,CAAK,MAAM,GAAA,EAAI,CAAE,aAAc,CAAA,CAC5I,KAAK,MAAA,CAAO,GAAA,CAAI,OAAQ,KAAK,EAC/B,CACA,OAAO,KACT,CACA,UAAA,CAAW,MAAA,CAAkB,MAAiC,CAAE,IAAA,CAAK,OAAO,GAAA,CAAI,MAAA,CAAQ,KAAK,EAAG,CAChG,UAAU,MAAA,CAAkB,IAAA,CAAuB,CAAE,OAAO,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA,EAAG,IAAI,IAAI,CAAA,GAAM,IAAM,CAC7G,eAAA,CAAgB,OAAkB,WAAA,CAAuC,CACvE,IAAI,MAAA,CAAS,IAAA,CAAK,WAAW,GAAA,CAAI,MAAM,EACvC,GAAI,MAAA,GAAW,OAAW,CAAE,MAAA,CAAS,IAAI,GAAA,CAAO,IAAA,CAAK,WAAW,GAAA,CAAI,MAAA,CAAQ,MAAM,EAAG,CACrF,OAAO,GAAA,CAAI,WAAA,CAAY,YAAa,CAAE,IAAA,CAAM,YAAY,IAAA,CAAM,KAAA,CAAO,YAAY,aAAc,CAAC,EAClG,CACA,iBAAA,CAAkB,MAAA,CAAkB,IAAA,CAA4B,CAC9D,IAAA,KAAW,CAAE,WAAY,CAAA,GAAK,KAAK,aAAA,CAAc,MAAA,GAAU,CACzD,GAAI,YAAY,QAAA,GAAa,MAAA,EAAU,YAAY,IAAA,GAAS,QAAA,EACvD,YAAY,WAAA,GAAgB,IAAA,EAAQ,YAAY,KAAA,GAAU,UAAA,CAAY,OAAO,IACpF,CACA,YACF,CACA,oBAAA,CAAqB,OAAqC,CACxD,OAAO,CAAC,GAAG,IAAA,CAAK,cAAc,MAAA,EAAQ,EAAE,MAAA,CAAO,CAAC,CAAE,WAAY,CAAA,GAAM,YAAY,QAAA,GAAa,MAAA,EAAU,WAAA,CAAY,IAAA,GAAS,QAAA,EAAY,WAAA,CAAY,QAAU,UAAU,CAAA,CAAE,IAAI,CAAC,CAAE,WAAY,CAAA,GAAM,WAAA,CAAY,WAAW,CAC5N,CACA,8BAA8B,MAAA,CAAkB,IAAA,CAAmB,SAAkB,GAAA,CAA8E,CACjK,MAAM,MAAA,CAAS,IAAA,CAAK,WAAW,GAAA,CAAI,MAAM,EACzC,MAAM,SAAA,CAAY,QAAQ,GAAA,CAAI,IAAI,EAGlC,GAAI,SAAA,GAAc,QAAa,SAAA,CAAU,IAAA,GAAS,SAAU,OAAO,CAAE,cAAe,EAAA,CAAI,MAAA,CAAQ,IAAM,CAAC,CAAE,CAAA,CACzG,MAAM,KAAA,CAAQ,IAAA,CAAK,OAAO,GAAA,CAAI,MAAM,EACpC,GAAI,KAAA,GAAU,QAAa,SAAA,CAAU,KAAA,GAAU,UAAY,KAAA,CAAM,oBAAA,CAAuB,UAAU,KAAA,EAAS,KAAA,CAAM,YAAc,EAAA,CAAI,CACjI,MAAM,IAAI,aAAA,CAAc,6BAA8B,gEAAgE,CACxH,CACA,OAAO,CAAE,cAAe,SAAA,CAAU,KAAA,CAAO,OAAQ,IAAM,CACrD,OAAQ,MAAA,CAAO,IAAI,EACnB,IAAA,CAAK,UAAA,CAAW,OAAQ,CAAE,GAAG,MAAO,oBAAA,CAAsB,KAAA,CAAM,oBAAA,CAAuB,SAAA,CAAU,KAAA,CAAO,WAAA,CAAa,MAAM,WAAA,CAAc,EAAA,CAAI,UAAW,GAAI,CAAC,EAC/J,CAAE,CACJ,CACA,sBAAA,CAAuB,MAAA,CAAkB,KAAmB,QAAA,CAAkB,GAAA,CAAqB,CACjG,MAAM,OAAA,CAAU,KAAK,6BAAA,CAA8B,MAAA,CAAQ,KAAM,QAAA,CAAU,GAAG,EAC9E,OAAA,CAAQ,MAAA,GACR,OAAO,OAAA,CAAQ,aACjB,CACF,EClDO,SAAS,yBAAA,CAA0B,KAAA,CAAkC,CAC1E,wBAAA,CAAyB,KAAA,CAAM,IAAK,KAAK,CAAA,CACzC,GAAI,CAAC,MAAA,CAAO,aAAA,CAAc,KAAA,CAAM,KAAK,CAAA,EAAK,MAAM,KAAA,EAAS,CAAA,CAAG,CAC1D,MAAM,IAAI,cAAc,yBAAA,CAA2B,uDAAuD,CAC5G,CACF,KAEa,qBAAA,CAAN,cAAoC,aAAc,CACvD,WAAA,CACW,UACA,UAAA,CACA,IAAA,CACT,OAAA,CACA,CACA,KAAA,CAAM,0BAAA,CAA4B,yCAA0C,OAAO,CAAA,CAL1E,yBACA,IAAA,CAAA,UAAA,CAAA,UAAA,CACA,IAAA,CAAA,IAAA,CAAA,KAIX,CANW,SAAA,CACA,UAAA,CACA,IAKb,ECZA,SAAS,UAAU,KAAA,CAAqB,CACtC,GAAI,CAAC,MAAA,CAAO,SAAS,KAAK,CAAA,EAAK,KAAA,EAAS,CAAA,CAAG,CACzC,MAAM,IAAI,aAAA,CACR,kBAAA,CACA,gEAAgE,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,CAC/E,CACF,CACF,CAEA,SAAS,sBAAsB,iBAAA,CAAiC,CAC9D,GAAI,CAAC,MAAA,CAAO,SAAS,iBAAiB,CAAA,EAAK,kBAAoB,CAAA,CAAG,CAChE,MAAM,IAAI,aAAA,CACR,mBACA,CAAA,8EAAA,EAAiF,MAAA,CAAO,iBAAiB,CAAC,CAAA,CAAA,CAC5G,CACF,CACF,KAEa,qBAAA,CAAN,KAAqD,CACjD,MAAA,CAAS,IAAI,IACb,MAAA,CAET,WAAA,CAAY,KAAA,CAAc,CACxB,IAAA,CAAK,MAAA,CAAS,MAChB,CAEA,MAAM,QAAQ,MAAA,CAAkB,KAAA,CAAiD,CAC/E,SAAA,CAAU,KAAA,CAAM,KAAK,CAAA,CACrB,qBAAA,CAAsB,MAAM,iBAAiB,CAAA,CAC7C,MAAM,GAAA,CAAM,IAAA,CAAK,OAAO,GAAA,EAAI,CAC5B,MAAM,GAAA,CAAM,SAAA,CAAU,OAAQ,KAAA,CAAM,QAAQ,EAC5C,MAAM,QAAA,CAAW,KAAK,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,CAEpC,GACE,UACA,GAAA,CAAI,WAAA,GAAgB,QAAA,CAAS,SAAA,EAC7B,KAAK,GAAA,CAAI,CAAA,CAAG,MAAA,CAAO,GAAG,CAAA,CAAI,IAAA,CAAK,MAAM,QAAA,CAAS,UAAU,CAAC,CAAA,CAAI,KAAA,CAAM,kBACnE,CACA,MAAM,IAAI,aAAA,CACR,mBAAA,CACA,gBAAgB,KAAA,CAAM,QAAQ,oEAChC,CACF,CACA,MAAM,IAAA,CAAqB,CACzB,SAAU,MAAA,CACV,QAAA,CAAU,MAAM,QAAA,CAChB,KAAA,CAAO,MAAM,KAAA,CACb,GAAI,MAAM,MAAA,GAAW,MAAA,CAAY,EAAC,CAAI,CAAE,OAAQ,KAAA,CAAM,MAAO,EAC7D,GAAI,KAAA,CAAM,qBAAuB,MAAA,CAC7B,EAAC,CACD,CAAE,kBAAA,CAAoB,MAAA,CAAO,OAAO,CAAC,GAAG,MAAM,kBAAkB,CAAC,CAAE,CAAA,CACvE,GAAI,MAAM,aAAA,GAAkB,MAAA,CAAY,EAAC,CAAI,CAAE,cAAe,KAAA,CAAM,aAAc,EAClF,GAAI,KAAA,CAAM,gBAAA,GAAqB,MAAA,CAC3B,EAAC,CACD,CAAE,gBAAA,CAAkB,MAAA,CAAO,OAAO,CAAC,GAAG,MAAM,gBAAgB,CAAC,CAAE,CAAA,CACnE,GAAI,MAAM,QAAA,GAAa,MAAA,CACnB,EAAC,CACD,CACE,SAAU,MAAA,CAAO,MAAA,CAAO,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,yBAAyB,CAAC,CACvE,CAAA,CACJ,WAAY,GAAA,CAAI,WAAA,GAChB,SAAA,CAAW,IAAI,KAAK,GAAA,CAAI,OAAA,GAAY,KAAA,CAAM,KAAK,EAAE,WAAA,EACnD,EACA,IAAA,CAAK,MAAA,CAAO,IAAI,GAAA,CAAK,IAAI,EACzB,OAAO,IACT,CAEA,MAAM,IAAA,CAAK,OAAkB,QAAA,CAAqD,CAChF,MAAM,GAAA,CAAM,SAAA,CAAU,OAAQ,QAAQ,CAAA,CACtC,MAAM,IAAA,CAAO,IAAA,CAAK,OAAO,GAAA,CAAI,GAAG,CAAA,CAChC,GAAI,IAAA,GAAS,MAAA,CAAW,OAAO,MAAA,CAC/B,GAAI,KAAK,UAAA,CAAW,IAAA,CAAK,SAAS,CAAA,CAAG,CACnC,KAAK,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,CACtB,OAAO,MACT,CACA,OAAO,IACT,CAEA,MAAM,KAAK,MAAA,CAAoD,CAC7D,MAAM,MAAA,CAAS,SAAA,CAAU,OAAQ,EAAE,CAAA,CACnC,MAAM,IAAA,CAAuB,GAC7B,IAAA,KAAW,CAAC,IAAK,IAAI,CAAA,GAAK,CAAC,GAAG,IAAA,CAAK,OAAO,OAAA,EAAS,CAAA,CAAG,CACpD,GAAI,CAAC,IAAI,UAAA,CAAW,MAAM,EAAG,SAC7B,GAAI,KAAK,UAAA,CAAW,IAAA,CAAK,SAAS,CAAA,CAAG,CACnC,KAAK,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,CACtB,QACF,CACA,IAAA,CAAK,IAAA,CAAK,IAAI,EAChB,CACA,KAAK,IAAA,CAAK,CAAC,KAAM,KAAA,GAAU,IAAA,CAAK,SAAS,aAAA,CAAc,KAAA,CAAM,QAAQ,CAAC,CAAA,CACtE,OAAO,IACT,CAEA,MAAM,cAAA,CAAe,MAAA,CAAkB,MAA2D,CAChG,yBAAA,CAA0B,KAAK,CAAA,CAC/B,IAAI,OAAA,CAAU,EAAG,IAAA,CAAO,KAAA,CACxB,SAAW,CAAC,GAAA,CAAK,IAAI,CAAA,GAAK,IAAA,CAAK,OAAQ,CACrC,GAAI,KAAK,QAAA,GAAa,MAAA,EAAU,KAAK,SAAA,CAAY,KAAA,CAAM,IAAK,SAC5D,GAAI,UAAY,KAAA,CAAM,KAAA,CAAO,CAAE,IAAA,CAAO,IAAA,CAAM,KAAO,CACnD,IAAA,CAAK,OAAO,MAAA,CAAO,GAAG,EAAG,OAAA,GAC3B,CACA,OAAO,CAAE,OAAA,CAAS,QAAS,CAAA,CAAG,aAAA,CAAe,GAAI,IAAK,CACxD,CAEA,UAAA,CAAW,SAAA,CAA4B,CACrC,OAAO,IAAA,CAAK,MAAA,CAAO,KAAI,CAAE,WAAA,IAAiB,SAC5C,CACF,EClGA,IAAM,kBAAA,CAAqB,GAEpB,IAAM,kBAAA,CAAN,KAA+C,CAC3C,MAAA,CAAS,IAAI,GAAA,CACb,YAAA,CAAe,IAAI,GAAA,CACnB,MAAA,CAET,YAAY,KAAA,CAAc,CACxB,KAAK,MAAA,CAAS,MAChB,CAEA,MAAM,MAAA,CAAO,OAAkB,KAAA,CAA2C,CACxE,MAAM,GAAA,CAAM,SAAA,CAAU,OAAQ,KAAA,CAAM,MAAM,EAC1C,GAAI,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,CAAG,CACxB,MAAM,IAAI,cACR,mBAAA,CACA,CAAA,WAAA,EAAc,MAAM,MAAM,CAAA,+BAAA,CAC5B,CACF,CACA,MAAM,IAAM,IAAA,CAAK,IAAA,GACjB,MAAM,IAAA,CAAkB,CACtB,QAAA,CAAU,MAAA,CACV,OAAQ,KAAA,CAAM,MAAA,CACd,QAAS,KAAA,CAAM,OAAA,CACf,MAAO,KAAA,CAAM,KAAA,CACb,OAAQ,KAAA,CAAM,MAAA,EAAU,OACxB,QAAA,CAAU,IAAA,CAAK,SAAS,MAAM,CAAA,CAC9B,UAAW,GAAA,CACX,SAAA,CAAW,GACb,CAAA,CACA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,GAAA,CAAK,IAAI,EACzB,OAAO,IACT,CAEA,MAAM,GAAA,CAAI,OAAkB,MAAA,CAAgD,CAC1E,OAAO,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,CAAU,MAAA,CAAQ,MAAM,CAAC,CAClD,CAEA,MAAM,IAAA,CAAK,OAAkB,KAAA,CAA2C,CACtE,MAAM,QAAA,CAAW,KAAA,CAAM,UAAY,CAAA,CACnC,MAAM,MAAQ,KAAA,CAAM,KAAA,EAAS,mBAC7B,MAAM,MAAA,CAAS,UAAU,MAAA,CAAQ,EAAE,EACnC,MAAM,OAAA,CAAuB,EAAC,CAC9B,IAAA,KAAW,CAAC,GAAA,CAAK,IAAI,CAAA,GAAK,KAAK,MAAA,CAAO,OAAA,GAAW,CAC/C,GAAI,CAAC,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,CAAG,SAC7B,GAAI,IAAA,CAAK,QAAA,EAAY,SAAU,SAC/B,GAAI,MAAM,OAAA,GAAY,MAAA,EAAa,IAAA,CAAK,OAAA,GAAY,KAAA,CAAM,OAAA,CAAS,SACnE,GAAI,KAAA,CAAM,SAAW,MAAA,EAAa,IAAA,CAAK,SAAW,KAAA,CAAM,MAAA,CAAQ,SAChE,OAAA,CAAQ,IAAA,CAAK,IAAI,EACnB,CACA,QAAQ,IAAA,CAAK,CAAC,KAAM,KAAA,GAAU,IAAA,CAAK,QAAA,CAAW,KAAA,CAAM,QAAQ,CAAA,CAC5D,MAAM,IAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAG,KAAK,EACnC,OAAO,CACL,MAAO,IAAA,CACP,OAAA,CAAS,KAAK,EAAA,CAAG,EAAE,GAAG,QAAA,EAAY,QAAA,CAClC,QAAS,OAAA,CAAQ,MAAA,CAAS,KAAK,MACjC,CACF,CAEA,MAAM,MAAA,CAAO,OAAkB,MAAA,CAA+B,CAC5D,KAAK,MAAA,CAAO,MAAA,CAAO,UAAU,MAAA,CAAQ,MAAM,CAAC,EAC9C,CAEA,MAAM,KAAA,CAAM,MAAA,CAAkB,MAA4C,CACxE,MAAM,IAAA,CAAO,IAAA,CAAK,QAAA,CAAS,MAAA,CAAQ,MAAM,MAAM,CAAA,CAC/C,MAAM,cAAA,CAAiB,KAAA,CAAM,gBAAkB,MAAA,CAE/C,GAAI,KAAK,QAAA,GAAa,MAAA,CAAW,CAC/B,GAAI,IAAA,CAAK,SAAS,QAAA,GAAa,KAAA,CAAM,SAAU,CAM7C,GAAI,MAAM,cAAA,GAAmB,MAAA,EAAa,KAAK,MAAA,GAAW,KAAA,CAAM,eAAgB,CAC9E,MAAM,IAAI,iBAAA,CACR,uBAAA,CACA,cAAc,KAAA,CAAM,MAAM,OAAO,IAAA,CAAK,MAAM,SAAS,KAAA,CAAM,cAAc,IACzE,IAAA,CACA,IAAA,CAAK,IAAA,EACP,CACF,CACA,OAAO,IACT,CACA,MAAM,IAAI,iBAAA,CACR,uBACA,CAAA,WAAA,EAAc,KAAA,CAAM,MAAM,CAAA,YAAA,EAAe,IAAA,CAAK,SAAS,QAAQ,CAAA,CAAA,CAAA,CAC/D,KACA,IAAA,CAAK,IAAA,EACP,CACF,CACA,GAAI,IAAA,CAAK,MAAA,GAAW,eAAgB,CAClC,MAAM,IAAI,iBAAA,CACR,uBAAA,CACA,cAAc,KAAA,CAAM,MAAM,OAAO,IAAA,CAAK,MAAM,SAAS,cAAc,CAAA,CAAA,CAAA,CACnE,KACA,IAAA,CAAK,IAAA,EACP,CACF,CACA,GAAI,IAAA,CAAK,MAAA,GAAW,MAAA,EAAU,KAAK,MAAA,GAAW,aAAA,CAAe,CAC3D,MAAM,IAAI,kBACR,0BAAA,CACA,CAAA,WAAA,EAAc,MAAM,MAAM,CAAA,wBAAA,EAA2B,KAAK,MAAM,CAAA,CAAA,CAAA,CAChE,KACA,IAAA,CAAK,IAAA,EACP,CACF,CAEA,MAAM,GAAA,CAAM,IAAA,CAAK,IAAA,GACjB,MAAM,OAAA,CAAqB,CACzB,GAAG,IAAA,CACH,OAAQ,IAAA,CAAK,MAAA,GAAW,OAAS,aAAA,CAAgB,IAAA,CAAK,OACtD,QAAA,CAAU,CAAE,SAAU,KAAA,CAAM,QAAA,CAAU,UAAW,GAAI,CAAA,CACrD,QAAA,CAAU,IAAA,CAAK,QAAA,CAAS,MAAM,EAC9B,SAAA,CAAW,GACb,EACA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,CAAU,MAAA,CAAQ,MAAM,MAAM,CAAA,CAAG,OAAO,CAAA,CACxD,OAAO,OACT,CAEA,MAAM,QAAQ,MAAA,CAAkB,KAAA,CAA8C,CAC5E,MAAM,IAAA,CAAO,KAAK,QAAA,CAAS,MAAA,CAAQ,MAAM,MAAM,CAAA,CAC/C,GAAI,IAAA,CAAK,QAAA,GAAa,OAAW,CAC/B,MAAM,IAAI,aAAA,CACR,gBAAA,CACA,cAAc,KAAA,CAAM,MAAM,yBAC5B,CACF,CACA,GAAI,IAAA,CAAK,QAAA,CAAS,QAAA,GAAa,MAAM,QAAA,CAAU,CAC7C,MAAM,IAAI,iBAAA,CACR,uBACA,CAAA,WAAA,EAAc,KAAA,CAAM,MAAM,CAAA,YAAA,EAAe,IAAA,CAAK,SAAS,QAAQ,CAAA,MAAA,EAAS,MAAM,QAAQ,CAAA,CAAA,CAAA,CACtF,KACA,IAAA,CAAK,IAAA,EACP,CACF,CACA,MAAM,GAAA,CAAM,IAAA,CAAK,MAAK,CACtB,MAAM,SAAsB,CAC1B,QAAA,CAAU,KAAK,QAAA,CACf,MAAA,CAAQ,KAAK,MAAA,CACb,OAAA,CAAS,KAAK,OAAA,CACd,KAAA,CAAO,KAAK,KAAA,CACZ,MAAA,CAAQ,IAAA,CAAK,MAAA,GAAW,aAAA,CAAgB,MAAA,CAAS,KAAK,MAAA,CACtD,QAAA,CAAU,KAAK,QAAA,CAAS,MAAM,EAC9B,SAAA,CAAW,IAAA,CAAK,UAChB,SAAA,CAAW,GACb,EACA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,CAAU,MAAA,CAAQ,MAAM,MAAM,CAAA,CAAG,QAAQ,CAAA,CACzD,OAAO,QACT,CAEA,MAAM,aAAa,MAAA,CAAkB,KAAA,CAAmD,CACtF,MAAM,IAAA,CAAO,KAAK,QAAA,CAAS,MAAA,CAAQ,MAAM,MAAM,CAAA,CAC/C,GAAI,IAAA,CAAK,MAAA,GAAW,MAAM,cAAA,CAAgB,CACxC,MAAM,IAAI,iBAAA,CACR,uBAAA,CACA,cAAc,KAAA,CAAM,MAAM,OAAO,IAAA,CAAK,MAAM,SAAS,KAAA,CAAM,cAAc,IACzE,IAAA,CACA,IAAA,CAAK,MACP,CACF,CACA,GAAI,KAAA,CAAM,WAAa,MAAA,EAAa,IAAA,CAAK,QAAA,EAAU,QAAA,GAAa,KAAA,CAAM,QAAA,CAAU,CAC9E,MAAM,IAAI,kBACR,sBAAA,CACA,CAAA,WAAA,EAAc,MAAM,MAAM,CAAA,gBAAA,EAAmB,MAAM,QAAQ,CAAA,CAAA,CAAA,CAC3D,KACA,IAAA,CAAK,IAAA,EACP,CACF,CACA,GAAI,CAAC,sBAAA,CAAuB,KAAA,CAAM,cAAA,CAAgB,KAAA,CAAM,MAAM,EAAG,CAC/D,MAAM,IAAI,iBAAA,CACR,0BAAA,CACA,GAAG,KAAA,CAAM,cAAc,OAAO,KAAA,CAAM,MAAM,oCAC1C,IAAA,CACA,IAAA,CAAK,MACP,CACF,CACA,MAAM,GAAA,CAAM,KAAK,IAAA,EAAK,CACtB,MAAM,OAAA,CAAqB,CACzB,GAAG,IAAA,CACH,MAAA,CAAQ,MAAM,MAAA,CACd,QAAA,CAAU,KAAK,QAAA,CAAS,MAAM,EAC9B,SAAA,CAAW,GACb,EACA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,CAAU,MAAA,CAAQ,KAAA,CAAM,MAAM,CAAA,CAAG,OAAO,EACxD,OAAO,OACT,CAEA,QAAA,CAAS,MAAA,CAAkB,OAA2B,CACpD,MAAM,KAAO,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,CAAU,MAAA,CAAQ,MAAM,CAAC,CAAA,CACtD,GAAI,IAAA,GAAS,MAAA,CAAW,CACtB,MAAM,IAAI,cACR,sBAAA,CACA,CAAA,WAAA,EAAc,MAAM,CAAA,+BAAA,CACtB,CACF,CACA,OAAO,IACT,CAEA,QAAA,CAAS,MAAA,CAA0B,CACjC,MAAM,IAAA,CAAA,CAAQ,KAAK,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA,EAAK,CAAA,EAAK,CAAA,CACpD,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,OAAQ,IAAI,CAAA,CAClC,OAAO,IACT,CAEA,MAAe,CACb,OAAO,KAAK,MAAA,CAAO,GAAA,GAAM,WAAA,EAC3B,CACF,EChNA,IAAM,aAAe,MAAA,CAAO,GAAA,CAAI,oCAAoC,CAAA,CAEpE,SAAS,UAAqC,CAC5C,MAAM,OAAS,UAAA,CACf,OAAQ,OAAO,YAAY,CAAA,GAAM,IAAI,OACvC,CAEO,SAAS,qBAAA,CAAsB,KAAA,CAAe,OAA0E,CAC7H,QAAA,GAAW,GAAA,CAAI,KAAA,CAAO,MAAM,EAC9B,CCEA,IAAM,mBAAqB,EAAA,CAapB,IAAM,qBAAN,KAAmD,CAC/C,SAAW,IAAI,GAAA,CACf,OACA,MAAA,CAGT,WAAA,CAAY,MAAc,KAAA,CAA4C,CACpE,KAAK,MAAA,CAAS,KAAA,CACd,KAAK,MAAA,CAAS,KAAA,CACd,sBAAsB,IAAA,CAAM,CAC1B,WAAY,CAAC,MAAA,CAAQ,WAAa,IAAA,CAAK,QAAA,CAAS,IAAI,SAAA,CAAU,MAAA,CAAQ,QAAQ,CAAC,CAAA,EAAG,UAAY,EAAC,CAC/F,YAAa,CAAC,MAAA,CAAQ,SAAU,GAAA,CAAK,IAAA,GAAS,CAC5C,MAAM,MAAA,CAAS,IAAA,CAAK,SAAS,GAAA,CAAI,SAAA,CAAU,OAAQ,QAAQ,CAAC,EAC5D,MAAM,KAAA,CAAQ,QAAQ,QAAA,CAAS,SAAA,CAAW,SAAY,OAAA,CAAQ,GAAA,GAAQ,GAAG,CAAA,EAAK,EAAA,CAC9E,GAAI,MAAA,GAAW,MAAA,EAAa,MAAQ,CAAA,CAAG,OACvC,MAAM,QAAA,CAA2B,CAAE,GAAG,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,CAAI,GAAG,IAAK,CAAA,CACvE,MAAA,CAAO,SAAS,KAAK,CAAA,CAAI,SACzB,MAAA,CAAO,WAAA,CAAY,IAAI,QAAA,CAAS,SAAA,CAAW,QAAQ,EACrD,CACF,CAAC,EACH,CAEA,MAAM,OAAO,MAAA,CAAkB,KAAA,CAAoD,CACjF,MAAM,MAAA,CAAS,KAAK,OAAA,CAAQ,MAAA,CAAQ,MAAM,QAAQ,CAAA,CAClD,MAAM,QAAA,CAAW,MAAA,CAAO,aAAa,IAAA,CAAK,SAAY,CACpD,GAAI,MAAA,CAAO,SAAW,MAAA,CAAW,MAAM,IAAI,wBAAA,CAAyB,KAAA,CAAM,SAAU,MAAA,CAAO,MAAA,CAAO,KAAK,CAAA,CACvG,MAAM,SAAW,MAAA,CAAO,WAAA,CAAY,IAAI,KAAA,CAAM,SAAS,EACvD,GAAI,QAAA,GAAa,MAAA,CAAW,OAAO,QAAA,CAInC,MAAM,MACJ,KAAA,CAAM,SAAA,GAAc,eAAiB,MAAA,CAAY,MAAM,KAAK,aAAA,CAAc,MAAM,EAClF,MAAM,GAAA,CAAM,OAAO,OAAA,CACnB,MAAM,aAAe,MAAM,KAAA,CAAM,YAAY,GAAG,CAAA,CAGhD,GAAI,KAAA,GAAU,MAAA,CAAW,CACvB,MAAM,IAAA,CAAO,KAAK,UAAA,CAAW,MAAM,EACnC,GAAI,IAAA,CAAO,aAAa,QAAA,CAAW,KAAA,CAAO,CACxC,MAAM,IAAI,cACR,wBAAA,CACA,CAAA,oBAAA,EAAuB,OAAO,IAAA,CAAO,YAAA,CAAa,QAAQ,CAAC,CAAA,0BAAA,EAA6B,MAAA,CAAO,KAAK,CAAC,CAAA,OAAA,CACvG,CACF,CACF,CACA,MAAM,OAAA,CAA0B,CAC9B,SAAU,MAAA,CACV,QAAA,CAAU,MAAM,QAAA,CAChB,GAAA,CACA,UAAW,KAAA,CAAM,SAAA,CACjB,GAAG,YAAA,CACH,KAAA,CAAO,SAAA,CACP,UAAA,CAAY,IAAA,CAAK,IAAA,EACnB,CAAA,CACA,MAAA,CAAO,SAAW,CAAA,CAClB,MAAA,CAAO,SAAS,IAAA,CAAK,OAAO,EAC5B,MAAA,CAAO,WAAA,CAAY,IAAI,OAAA,CAAQ,SAAA,CAAW,OAAO,CAAA,CACjD,OAAO,OACT,CAAC,CAAA,CAGD,MAAA,CAAO,YAAA,CAAe,QAAA,CAAS,IAAA,CAC7B,IAAM,MAAA,CACN,IAAM,MACR,CAAA,CACA,OAAO,QACT,CAEA,MAAM,UAAU,MAAA,CAAyC,CACvD,OAAO,CAAE,KAAA,CAAO,KAAK,UAAA,CAAW,MAAM,CAAE,CAC1C,CAEA,MAAM,SAAA,CAAU,MAAA,CAAkB,MAA+C,CAC/E,MAAM,OAAS,IAAA,CAAK,QAAA,CAAS,IAAI,SAAA,CAAU,MAAA,CAAQ,MAAM,QAAQ,CAAC,EAClE,MAAM,KAAA,CAAQ,MAAM,KAAA,EAAS,kBAAA,CAC7B,GAAI,MAAA,GAAW,MAAA,CAAW,CAGxB,OAAO,CAAE,QAAA,CAAU,EAAC,CAAG,OAAA,CAAS,MAAM,QAAA,CAAU,OAAA,CAAS,MAAO,eAAA,CAAiB,CAAE,CACrF,CACA,MAAM,QAAU,MAAA,CAAO,QAAA,CACpB,OAAQ,OAAA,EAAY,OAAA,CAAQ,QAAU,SAAA,EAAa,OAAA,CAAQ,IAAM,KAAA,CAAM,QAAQ,EAC/E,IAAA,CAAK,CAAC,KAAM,KAAA,GAAU,IAAA,CAAK,IAAM,KAAA,CAAM,GAAG,EAC7C,MAAM,IAAA,CAAO,QAAQ,KAAA,CAAM,CAAA,CAAG,KAAK,CAAA,CACnC,MAAM,KAAO,IAAA,CAAK,EAAA,CAAG,EAAE,CAAA,CACvB,OAAO,CACL,SAAU,IAAA,CAGV,OAAA,CAAS,MAAM,GAAA,EAAO,KAAA,CAAM,SAC5B,OAAA,CAAS,OAAA,CAAQ,OAAS,IAAA,CAAK,MAAA,CAI/B,gBAAiB,IAAA,CAAK,gBAAA,CAAiB,MAAM,CAC/C,CACF,CAEA,MAAM,aAAA,CACJ,OACA,KAAA,CAC6B,CAC7B,MAAM,MAAA,CAAS,IAAA,CAAK,QAAQ,MAAA,CAAQ,KAAA,CAAM,QAAQ,CAAA,CAClD,MAAM,SAAW,MAAA,CAAO,YAAA,CAAa,KAAK,IAAM,CAC9C,GAAI,KAAA,CAAM,QAAA,CAAW,OAAO,QAAA,CAAU,CACpC,MAAM,IAAI,iBAAA,CACR,2BAAA,CACA,qBAAqB,KAAA,CAAM,QAAQ,UAAU,MAAA,CAAO,QAAQ,iCAAiC,KAAA,CAAM,QAAQ,IAC3G,IAAA,CAAK,YAAA,CAAa,OAAQ,KAAA,CAAM,QAAA,CAAU,MAAM,CAAA,CAChD,IAAA,CAAK,MACP,CACF,CACA,GAAI,KAAA,CAAM,QAAA,CAAW,OAAO,YAAA,CAAc,CACxC,MAAM,IAAI,iBAAA,CACR,mCACA,CAAA,kBAAA,EAAqB,KAAA,CAAM,QAAQ,CAAA,uBAAA,EAA0B,MAAA,CAAO,YAAY,CAAA,wCAAA,EAA2C,KAAA,CAAM,QAAQ,CAAA,CAAA,CAAA,CACzI,IAAA,CAAK,aAAa,MAAA,CAAQ,KAAA,CAAM,QAAA,CAAU,MAAM,CAAA,CAChD,IAAA,CAAK,MACP,CACF,CACA,MAAA,CAAO,QAAA,CAAW,MAAM,QAAA,CACxB,MAAA,CAAO,gBAAkB,IAAA,CAAK,IAAA,GAC9B,IAAA,KAAW,CAAC,MAAO,OAAO,CAAA,GAAK,OAAO,QAAA,CAAS,OAAA,GAAW,CACxD,GAAI,QAAQ,KAAA,GAAU,SAAA,EAAa,QAAQ,GAAA,EAAO,KAAA,CAAM,SAAU,CAChE,MAAA,CAAO,SAAS,KAAK,CAAA,CAAI,CAAE,GAAG,OAAA,CAAS,MAAO,OAAQ,CAAA,CACtD,OAAO,WAAA,CAAY,GAAA,CAAI,OAAA,CAAQ,SAAA,CAAW,MAAA,CAAO,QAAA,CAAS,KAAK,CAAE,EACnE,CACF,CACA,OAAO,KAAK,YAAA,CAAa,MAAA,CAAQ,MAAM,QAAA,CAAU,MAAM,CACzD,CAAC,CAAA,CACD,OAAO,YAAA,CAAe,QAAA,CAAS,KAC7B,IAAM,MAAA,CACN,IAAM,MACR,CAAA,CACA,OAAO,QACT,CAEA,MAAM,cAAA,CACJ,MAAA,CACA,MAC6B,CAC7B,MAAM,OAAS,IAAA,CAAK,OAAA,CAAQ,OAAQ,KAAA,CAAM,QAAQ,EAClD,MAAM,QAAA,CAAW,OAAO,YAAA,CAAa,IAAA,CAAK,IAAM,CAC9C,GAAI,KAAA,CAAM,aAAe,MAAA,CAAO,YAAA,CAAc,CAC5C,MAAA,CAAO,YAAA,CAAe,MAAM,aAC9B,CACA,OAAO,IAAA,CAAK,YAAA,CAAa,OAAQ,KAAA,CAAM,QAAA,CAAU,MAAM,CACzD,CAAC,EACD,MAAA,CAAO,YAAA,CAAe,SAAS,IAAA,CAC7B,IAAM,OACN,IAAM,MACR,EACA,OAAO,QACT,CAEA,MAAM,UAAA,CAAW,OAAkB,QAAA,CAA+C,CAChF,MAAM,MAAA,CAAS,IAAA,CAAK,SAAS,GAAA,CAAI,SAAA,CAAU,OAAQ,QAAQ,CAAC,CAAA,CAC5D,GAAI,MAAA,GAAW,MAAA,CAAW,CACxB,OAAO,CAAE,SAAU,MAAA,CAAQ,QAAA,CAAU,aAAc,CAAA,CAAG,QAAA,CAAU,EAAG,SAAA,CAAW,IAAA,CAAK,MAAO,CAC5F,CACA,OAAO,IAAA,CAAK,aAAa,MAAA,CAAQ,QAAA,CAAU,MAAM,CACnD,CAEA,MAAM,eAAe,MAAA,CAAkB,KAAA,CAAkE,CACvG,yBAAA,CAA0B,KAAK,EAC/B,wBAAA,CAAyB,KAAA,CAAM,YAAa,aAAa,CAAA,CACzD,yBAAyB,KAAA,CAAM,mBAAA,CAAqB,qBAAqB,CAAA,CACzE,wBAAA,CAAyB,MAAM,qBAAA,CAAuB,uBAAuB,CAAA,CAC7E,IAAI,OAAA,CAAU,CAAA,CAAG,QAAU,CAAA,CAAG,IAAA,CAAO,MAIrC,MAAM,QAAA,CAAW,CAAC,MAAA,CAAuB,OAAA,GACvC,QAAQ,KAAA,GAAU,SAAA,EAAa,QAAQ,UAAA,CAAa,KAAA,CAAM,uBACvD,MAAA,CAAO,QAAA,CAAS,KAAM,KAAA,EAAU,KAAA,CAAM,QAAU,SAAA,EAAa,KAAA,CAAM,IAAM,OAAA,CAAQ,GAAG,EACzF,GAAI,CACF,OAAQ,IAAA,MAAW,KAAA,IAAS,CAAC,OAAA,CAAS,MAAA,CAAQ,SAAS,CAAA,CAAY,CACjE,SAAW,CAAC,GAAA,CAAK,MAAM,CAAA,GAAK,IAAA,CAAK,QAAA,CAAU,CACzC,GAAI,CAAC,IAAI,UAAA,CAAW,SAAA,CAAU,OAAQ,EAAE,CAAC,EAAG,SAC5C,MAAM,UAAY,MAAA,CAAO,YAAA,CAAa,KAAK,IAAM,CAC/C,QAAS,KAAA,CAAQ,CAAA,CAAG,MAAQ,MAAA,CAAO,QAAA,CAAS,QAAS,CACnD,MAAM,QAAU,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,CACrC,MAAM,SAAW,KAAA,GAAU,MAAA,CACvB,SAAS,MAAA,CAAQ,OAAO,EACxB,OAAA,CAAQ,KAAA,GAAU,OACf,OAAA,CAAQ,UAAA,EAAc,QAAU,OAAA,CAAU,KAAA,CAAM,WAAA,CAAc,KAAA,CAAM,mBAAA,CAAA,CAC3E,GAAI,CAAC,QAAA,CAAU,CAAE,QAAS,QAAU,CACpC,GAAI,OAAA,CAAU,OAAA,GAAY,MAAM,KAAA,CAAO,CAAE,KAAO,IAAA,CAAM,MAAQ,CAC9D,GAAI,KAAA,GAAU,UAAW,CACvB,MAAM,QAA0B,CAAE,GAAG,QAAS,KAAA,CAAO,SAAU,EAC/D,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,CAAI,OAAA,CACzB,OAAO,WAAA,CAAY,GAAA,CAAI,QAAQ,SAAA,CAAW,OAAO,EACjD,OAAA,EAAA,CAAW,KAAA,GACb,MAAO,CACL,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,KAAA,CAAO,CAAC,EAC/B,MAAA,CAAO,WAAA,CAAY,OAAO,OAAA,CAAQ,SAAS,EAC3C,OAAA,GACF,CACF,CACF,CAAC,CAAA,CACD,OAAO,YAAA,CAAe,SAAA,CAAU,KAAK,IAAM,KAAA,CAAA,CAAW,IAAM,KAAA,CAAS,CAAA,CACrE,MAAM,SAAA,CACN,GAAI,KAAM,MAAM,MAClB,CACF,CAEA,GAAI,CAAC,IAAA,CAAM,CACT,KAAO,CAAC,GAAG,KAAK,QAAQ,CAAA,CAAE,KAAK,CAAC,CAAC,IAAK,MAAM,CAAA,GAAM,GAAA,CAAI,UAAA,CAAW,SAAA,CAAU,MAAA,CAAQ,EAAE,CAAC,CAAA,EACjF,OAAO,QAAA,CAAS,IAAA,CAAM,SAAY,QAAA,CAAS,MAAA,CAAQ,OAAO,CAAC,CAAC,EACnE,CACF,CAAA,MAAS,MAAO,CACd,MAAM,IAAI,qBAAA,CAAsB,CAAE,QAAS,OAAA,CAAS,aAAA,CAAe,EAAG,CAAA,CAAG,CAAA,CAAG,OAAW,CAAE,KAAM,CAAC,CAClG,CAEA,OAAO,CAAE,OAAA,CAAS,QAAS,aAAA,CAAe,EAAA,CAAI,IAAK,CACrD,CAEA,MAAM,aAAA,CAAc,MAAA,CAAkB,KAAA,CAAyE,CAC7G,MAAM,MAAA,CAAS,KAAK,QAAA,CAAS,GAAA,CAAI,UAAU,MAAA,CAAQ,KAAA,CAAM,QAAQ,CAAC,CAAA,CAClE,GAAI,MAAA,GAAW,MAAA,CAAW,OAAO,CAAE,OAAA,CAAS,CAAE,CAAA,CAC9C,MAAM,SAAW,IAAI,GAAA,CAAI,MAAM,IAAI,CAAA,CACnC,OAAO,IAAA,CAAK,UAAA,CAAW,OAAQ,IAAM,qBAAA,CAAsB,OAAS,OAAA,EAAY,QAAA,CAAS,IAAI,OAAA,CAAQ,GAAG,CAAC,CAAC,CAC5G,CAEA,MAAM,WAAA,CAAY,OAAkB,KAAA,CAAuE,CACzG,MAAM,MAAA,CAAS,IAAA,CAAK,OAAA,CAAQ,OAAQ,KAAA,CAAM,QAAQ,EAClD,OAAO,IAAA,CAAK,WAAW,MAAA,CAAQ,IAAM,CACnC,MAAA,CAAO,MAAA,CAAS,CAAE,EAAA,CAAI,MAAA,CAAO,QAAQ,EAAA,EAAM,IAAA,CAAK,MAAK,CAAG,KAAA,CAAO,MAAM,KAAM,CAAA,CAC3E,OAAO,qBAAA,CAAsB,MAAA,CAAQ,IAAM,IAAI,CACjD,CAAC,CACH,CAEA,MAAM,YAAA,CAAa,MAAA,CAAkB,MAAgD,CACnF,MAAM,OAAS,IAAA,CAAK,QAAA,CAAS,IAAI,SAAA,CAAU,MAAA,CAAQ,KAAA,CAAM,QAAQ,CAAC,CAAA,CAClE,GAAI,MAAA,GAAW,MAAA,CAAW,OAC1B,MAAM,IAAA,CAAK,WAAW,MAAA,CAAQ,IAAM,CAClC,MAAA,CAAO,MAAA,CAAS,OAClB,CAAC,EACH,CAGA,UAAA,CAAc,MAAA,CAAuB,KAA2B,CAC9D,MAAM,GAAA,CAAM,MAAA,CAAO,YAAA,CAAa,IAAA,CAAK,IAAI,CAAA,CACzC,MAAA,CAAO,aAAe,GAAA,CAAI,IAAA,CAAK,IAAM,MAAA,CAAW,IAAM,MAAS,CAAA,CAC/D,OAAO,GACT,CAEA,KAAM,cAAc,MAAA,CAAmC,CACrD,MAAM,WAAA,CAAc,MAAM,IAAA,CAAK,MAAA,CAAO,eAAA,CAAgB,MAAM,EAC5D,GAAI,WAAA,GAAgB,OAAW,CAC7B,MAAM,IAAI,aAAA,CACR,6BAAA,CACA,yDACF,CACF,CACA,OAAO,WAAA,CAAY,iBACrB,CAMA,UAAA,CAAW,MAAA,CAA0B,CACnC,MAAM,MAAA,CAAS,UAAU,MAAA,CAAQ,EAAE,EACnC,IAAI,KAAA,CAAQ,GACZ,IAAA,KAAW,CAAC,IAAK,MAAM,CAAA,GAAK,KAAK,QAAA,CAAS,OAAA,GAAW,CACnD,GAAI,CAAC,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,CAAG,SAC7B,IAAA,MAAW,OAAA,IAAW,MAAA,CAAO,QAAA,CAAU,CACrC,GAAI,OAAA,CAAQ,QAAU,SAAA,CAAW,KAAA,EAAS,QAAQ,SACpD,CACF,CACA,OAAO,KACT,CAEA,OAAA,CAAQ,MAAA,CAAkB,SAAiC,CACzD,GAAI,SAAS,MAAA,GAAW,CAAA,CAAG,CACzB,MAAM,IAAI,cAAc,2BAAA,CAA6B,8BAA8B,CACrF,CACA,MAAM,IAAM,SAAA,CAAU,MAAA,CAAQ,QAAQ,CAAA,CACtC,MAAM,SAAW,IAAA,CAAK,QAAA,CAAS,IAAI,GAAG,CAAA,CACtC,GAAI,QAAA,GAAa,MAAA,CAAW,OAAO,QAAA,CACnC,MAAM,OAAA,CAAyB,CAC7B,OAAA,CAAS,CAAA,CACT,aAAc,CAAA,CACd,QAAA,CAAU,EACV,eAAA,CAAiB,IAAA,CAAK,MAAK,CAC3B,MAAA,CAAQ,OACR,YAAA,CAAc,OAAA,CAAQ,SAAQ,CAC9B,QAAA,CAAU,EAAC,CACX,WAAA,CAAa,IAAI,GACnB,CAAA,CACA,KAAK,QAAA,CAAS,GAAA,CAAI,IAAK,OAAO,CAAA,CAC9B,OAAO,OACT,CAWA,iBAAiB,MAAA,CAA+B,CAC9C,IAAI,IAAA,CAAO,CAAA,CACX,UAAW,OAAA,IAAW,MAAA,CAAO,SAAU,CACrC,GAAI,OAAA,CAAQ,KAAA,GAAU,SAAA,EAAa,OAAA,CAAQ,IAAM,IAAA,CAAM,IAAA,CAAO,QAAQ,IACxE,CACA,OAAO,IAAA,CAAO,CAChB,CAEA,YAAA,CACE,MAAA,CACA,SACA,MAAA,CACoB,CACpB,OAAO,CACL,QAAA,CAAU,OACV,QAAA,CACA,YAAA,CAAc,MAAA,CAAO,YAAA,CACrB,QAAA,CAAU,MAAA,CAAO,SACjB,SAAA,CAAW,MAAA,CAAO,eACpB,CACF,CAEA,MAAe,CACb,OAAO,KAAK,MAAA,CAAO,GAAA,GAAM,WAAA,EAC3B,CACF,EAGA,SAAS,sBAAsB,MAAA,CAAuB,QAAA,CAA8E,CAClI,IAAI,OAAA,CAAU,CAAA,CACd,SAAW,CAAC,KAAA,CAAO,OAAO,CAAA,GAAK,MAAA,CAAO,SAAS,OAAA,EAAQ,CAAG,CACxD,GAAI,OAAA,CAAQ,QAAU,SAAA,EAAa,CAAC,SAAS,OAAO,CAAA,CAAG,SACvD,MAAM,IAAA,CAAuB,CAAE,GAAG,OAAA,CAAS,MAAO,SAAU,CAAA,CAC5D,OAAO,QAAA,CAAS,KAAK,EAAI,IAAA,CACzB,MAAA,CAAO,YAAY,GAAA,CAAI,IAAA,CAAK,UAAW,IAAI,CAAA,CAC3C,UACF,CACA,OAAO,CAAE,OAAQ,CACnB,CC9WA,IAAMG,mBAAAA,CAAqB,GAAA,KAEd,mBAAA,CAAN,KAAiD,CAMtD,WAAA,CAAY,KAAA,CAA+B,YAA8F,CAA9F,IAAA,CAAA,WAAA,CAAA,WAAA,CACzC,KAAK,MAAA,CAAS,KAAA,CACd,GAAI,WAAA,GAAgB,MAAA,EAAa,YAAY,MAAA,GAAW,MAAA,EACtD,OAAO,WAAA,CAAY,KAAA,EAAO,eAAiB,UAAA,CAAY,CACvD,MAAM,IAAI,aAAA,CAAc,0BAA2B,wEAAwE,CAC7H,CACA,qBAAA,CAAsB,IAAA,CAAM,CAC1B,iBAAA,CAAmB,CAAC,OAAQ,OAAA,CAAS,KAAA,GAAU,CAC7C,MAAM,MAAA,CAAS,IAAI,GAAA,CACnB,IAAI,QAAA,CAAW,CAAA,CACf,IAAA,KAAW,CAAC,IAAK,SAAS,CAAA,GAAK,KAAK,WAAA,CAAa,CAC/C,GAAI,SAAA,CAAU,QAAA,GAAa,QAAU,SAAA,CAAU,OAAA,GAAY,SAAW,SAAA,CAAU,KAAA,GAAU,MAAO,SACjG,IAAA,CAAK,YAAY,MAAA,CAAO,GAAG,EAC3B,MAAA,CAAO,GAAA,CAAI,UAAU,IAAI,CAAA,CACzB,UAAY,EACd,CACA,UAAW,IAAA,IAAQ,MAAA,CAAQ,CACzB,MAAM,KAAA,CAAQ,KAAK,SAAA,CAAU,GAAA,CAAI,UAAU,MAAA,CAAQ,IAAI,CAAC,CAAA,CACxD,GAAI,KAAA,GAAU,MAAA,CAAW,IAAA,CAAK,QAAA,CAAS,OAAQ,KAAK,EACtD,CACA,OAAO,QACT,CACF,CAAC,EACH,CAvB2C,WAAA,CALlC,SAAA,CAAY,IAAI,GAAA,CAChB,WAAA,CAAc,IAAI,GAAA,CAClB,MAAA,CACA,cAAgB,IAAI,GAAA,CA2B7B,MAAM,WAAA,CACJ,MAAA,CACA,KAAA,CAC8B,CAC9B,MAAM,GAAA,CAAM,UAAU,MAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,CACxC,MAAM,SAAW,IAAA,CAAK,SAAA,CAAU,IAAI,GAAG,CAAA,CACvC,GAAI,QAAA,GAAa,MAAA,EAAa,SAAS,KAAA,GAAU,SAAA,CAAW,OAAO,QAAA,CAEnE,MAAM,GAAA,CAAM,KAAK,IAAA,EAAK,CACtB,MAAM,KAAA,CAA6B,CACjC,SAAU,MAAA,CACV,IAAA,CAAM,MAAM,IAAA,CACZ,QAAA,CAAU,MAAM,QAAA,CAChB,WAAA,CAAa,MAAM,WAAA,CACnB,KAAA,CAAO,UACP,QAAA,CAAU,CAAA,CACV,UAAW,GAAA,CACX,SAAA,CAAW,GACb,CAAA,CACA,IAAA,CAAK,UAAU,GAAA,CAAI,GAAA,CAAK,KAAK,CAAA,CAC7B,OAAO,KACT,CAEA,MAAM,OAAO,MAAA,CAAkB,KAAA,CAAwD,CACrF,MAAM,KAAA,CAAQ,KAAK,QAAA,CAAS,MAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,CAC9C,GACE,MAAM,QAAA,GAAa,KAAA,CAAM,kBACzB,KAAA,CAAM,WAAA,GAAgB,MAAM,mBAAA,CAC5B,CACA,MAAM,IAAI,aAAA,CACR,6BACA,CAAA,gBAAA,EAAmB,KAAA,CAAM,IAAI,CAAA,EAAA,EAAK,MAAA,CAAO,MAAM,gBAAgB,CAAC,WAAW,KAAA,CAAM,mBAAmB,yCACtG,CACF,CACA,GAAI,KAAA,CAAM,KAAA,GAAU,YAAa,OAAO,KAAA,CACxC,OAAO,IAAA,CAAK,WAAA,CAAY,OAAQ,KAAA,CAAO,WAAW,CACpD,CAEA,MAAM,IAAI,MAAA,CAAkB,IAAA,CAA6D,CACvF,OAAO,IAAA,CAAK,SAAA,CAAU,IAAI,SAAA,CAAU,MAAA,CAAQ,IAAI,CAAC,CACnD,CAEA,MAAM,IAAA,CACJ,OACA,KAAA,CACyC,CAIzC,GAAI,KAAA,CAAM,mBAAA,GAAwB,OAAW,CAC3C,wBAAA,CAAyB,MAAM,mBAAA,CAAqB,qBAAqB,EAC3E,CACA,MAAM,OAAS,SAAA,CAAU,MAAA,CAAQ,EAAE,CAAA,CACnC,MAAM,QAAiC,EAAC,CACxC,SAAW,CAAC,GAAA,CAAK,KAAK,CAAA,GAAK,IAAA,CAAK,UAAU,OAAA,EAAQ,CAAG,CACnD,GAAI,CAAC,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,CAAG,SAC7B,GAAI,KAAA,CAAM,QAAU,MAAA,EAAa,KAAA,CAAM,QAAU,KAAA,CAAM,KAAA,CAAO,SAC9D,GAAI,KAAA,CAAM,sBAAwB,MAAA,CAAW,CAC3C,GAAI,KAAA,CAAM,eAAA,GAAoB,OAAW,SACzC,GAAI,KAAA,CAAM,eAAA,EAAmB,KAAA,CAAM,mBAAA,CAAqB,QAC1D,CACA,OAAA,CAAQ,KAAK,KAAK,EACpB,CACA,OAAA,CAAQ,IAAA,CAAK,CAAC,IAAA,CAAM,KAAA,GAAU,KAAK,IAAA,CAAK,aAAA,CAAc,MAAM,IAAI,CAAC,EACjE,OAAO,OAAA,CAAQ,KAAA,CAAM,CAAA,CAAG,KAAA,CAAM,KAAA,EAASA,mBAAkB,CAC3D,CAEA,MAAM,YAAA,CACJ,MAAA,CACA,MAC8B,CAC9B,MAAM,MAAQ,IAAA,CAAK,QAAA,CAAS,OAAQ,KAAA,CAAM,IAAI,EAC9C,GAAI,KAAA,CAAM,QAAU,WAAA,CAAa,CAC/B,MAAM,IAAI,aAAA,CACR,uBACA,CAAA,0CAAA,EAA6C,KAAA,CAAM,IAAI,CAAA,IAAA,EAAO,KAAA,CAAM,KAAK,CAAA,CAAA,CAC3E,CACF,CACA,MAAM,MAAA,CAAS,UAAU,MAAA,CAAQ,KAAA,CAAM,KAAM,KAAA,CAAM,OAAA,CAAS,MAAM,KAAK,CAAA,CACvE,GAAI,CAAC,IAAA,CAAK,WAAA,CAAY,IAAI,MAAM,CAAA,CAAG,CACjC,IAAA,CAAK,WAAA,CAAY,IAAI,MAAA,CAAQ,CAC3B,SAAU,MAAA,CACV,IAAA,CAAM,MAAM,IAAA,CACZ,OAAA,CAAS,MAAM,OAAA,CACf,KAAA,CAAO,MAAM,KAAA,CACb,SAAA,CAAW,KAAK,IAAA,EAClB,CAAC,EACH,CACA,OAAO,IAAA,CAAK,QAAA,CAAS,OAAQ,KAAK,CACpC,CAEA,MAAM,eAAA,CACJ,OACA,KAAA,CAC8B,CAC9B,MAAM,KAAA,CAAQ,IAAA,CAAK,SAAS,MAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,CAC9C,IAAA,CAAK,WAAA,CAAY,OAAO,SAAA,CAAU,MAAA,CAAQ,MAAM,IAAA,CAAM,KAAA,CAAM,QAAS,KAAA,CAAM,KAAK,CAAC,CAAA,CACjF,OAAO,KAAK,QAAA,CAAS,MAAA,CAAQ,KAAK,CACpC,CAEA,MAAM,iBAAA,CACJ,MAAA,CACA,KAC8B,CAC9B,MAAM,MAAQ,IAAA,CAAK,QAAA,CAAS,OAAQ,IAAI,CAAA,CACxC,GAAI,KAAA,CAAM,QAAA,GAAa,EAAG,CACxB,MAAM,IAAI,aAAA,CACR,sBAAA,CACA,UAAU,IAAI,CAAA,WAAA,EAAc,MAAM,QAAQ,CAAA,cAAA,CAC5C,CACF,CACA,OAAO,IAAA,CAAK,YAAY,MAAA,CAAQ,KAAA,CAAO,gBAAgB,CACzD,CAEA,MAAM,WAAA,CAAY,MAAA,CAAkB,KAAiD,CACnF,MAAM,MAAQ,IAAA,CAAK,QAAA,CAAS,OAAQ,IAAI,CAAA,CACxC,OAAO,IAAA,CAAK,WAAA,CAAY,MAAA,CAAQ,KAAA,CAAO,SAAS,CAClD,CAEA,MAAM,cAAA,CAAe,OAAkB,KAAA,CAAiE,CACtG,0BAA0B,KAAK,CAAA,CAC/B,yBAAyB,KAAA,CAAM,YAAA,CAAc,cAAc,CAAA,CAC3D,MAAM,SAAY,KAAA,EAAwC,KAAA,CAAM,WAAa,MAAA,EAAU,KAAA,CAAM,QAAA,GAAa,CAAA,EACrG,CAAC,IAAA,CAAK,YAAY,MAAA,CAAO,iBAAA,CAAkB,OAAQ,KAAA,CAAM,IAAI,IAC5D,KAAA,CAAM,KAAA,GAAU,mBAAsB,KAAA,CAAM,KAAA,GAAU,WAAa,KAAA,CAAM,KAAA,GAAU,cAAgB,KAAA,CAAM,SAAA,CAAY,MAAM,YAAA,CAAA,CACjI,IAAI,QAAU,CAAA,CAAG,aAAA,CAAgB,GAAI,IAAA,CAAO,KAAA,CAAO,QAAU,CAAA,CAAG,QAAA,CAAW,EAC3E,IAAI,YAAA,CACJ,MAAM,MAAA,CAAS,IAAA,CAAK,cAAc,GAAA,CAAI,MAAM,GAAK,EAAA,CAEjD,MAAM,QAAU,CAAC,GAAG,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,EAAE,MAAA,CAAO,QAAQ,EAC5D,MAAM,OAAA,CAAU,QAAQ,MAAA,CAAO,KAAA,EAAS,MAAM,KAAA,GAAU,gBAAgB,EAAE,IAAA,CAAK,CAAC,EAAG,CAAA,GAAM,CAAA,CAAE,KAAK,aAAA,CAAc,CAAA,CAAE,IAAI,CAAC,CAAA,CACrH,MAAM,KAAA,CAAQ,OAAA,CAAQ,OAAO,KAAA,EAAS,KAAA,CAAM,KAAO,MAAM,CAAA,CAAE,MAAM,CAAA,CAAG,KAAA,CAAM,KAAK,CAAA,CAC/E,MAAM,MAAQ,OAAA,CAAQ,MAAA,CAAO,OAAS,KAAA,CAAM,KAAA,GAAU,gBAAgB,CAAA,CAAE,IAAA,CAAK,CAAC,EAAG,CAAA,GAAM,CAAA,CAAE,UAAU,aAAA,CAAc,CAAA,CAAE,SAAS,CAAA,EAAK,CAAA,CAAE,KAAK,aAAA,CAAc,CAAA,CAAE,IAAI,CAAC,CAAA,CAAE,MAAM,CAAA,CAAG,KAAA,CAAM,MAAQ,KAAA,CAAM,MAAM,EAClM,MAAM,OAAA,CAAU,QAAQ,MAAA,CAAO,KAAA,EAAS,MAAM,IAAA,EAAQ,MAAM,EAAE,KAAA,CAAM,CAAA,CAAG,MAAM,KAAA,CAAQ,KAAA,CAAM,OAAS,KAAA,CAAM,MAAM,EAChH,MAAM,UAAA,CAAa,CAAC,GAAG,KAAA,CAAO,GAAG,KAAA,CAAO,GAAG,OAAO,EAClD,IAAA,CAAO,OAAA,CAAQ,OAAS,UAAA,CAAW,MAAA,CACnC,UAAW,SAAA,IAAa,UAAA,CAAY,CAClC,GAAI,OAAA,EAAA,GAAc,MAAM,KAAA,CAAO,CAAE,KAAO,IAAA,CAAM,KAAO,CACrD,MAAM,KAAA,CAAQ,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAA,CAAU,OAAQ,SAAA,CAAU,IAAI,CAAC,CAAA,CAClE,GAAI,CAAC,QAAA,CAAS,KAAK,EAAG,SACtB,MAAMC,SAAU,KAAA,CAAM,KAAA,GAAU,iBAAmB,KAAA,CAAQ,CAAE,GAAG,KAAA,CAAO,KAAA,CAAO,gBAAA,CAA2B,eAAA,CAAiB,KAAA,CAAM,GAAA,CAAK,UAAW,KAAA,CAAM,GAAI,EAC1J,IAAA,CAAK,SAAA,CAAU,IAAI,SAAA,CAAU,MAAA,CAAQ,MAAM,IAAI,CAAA,CAAGA,QAAO,CAAA,CACzD,GAAI,CAEF,MAAM,OAAA,CAAU,KAAK,WAAA,CAAY,MAAA,CAAO,8BAA8B,MAAA,CAAQ,KAAA,CAAM,KAAM,KAAA,CAAM,QAAA,CAAU,MAAM,GAAG,CAAA,CACnH,KAAK,WAAA,CAAY,KAAA,CAAM,aAAa,MAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,CACtD,OAAA,CAAQ,QAAO,CACf,MAAM,SAAW,OAAA,CAAQ,aAAA,CACzB,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAA,CAAU,OAAQ,KAAA,CAAM,IAAI,EAAG,CAAE,GAAGA,SAAS,KAAA,CAAO,SAAA,CAAW,UAAW,KAAA,CAAM,GAAI,CAAC,CAAA,CACxG,OAAA,EAAA,CAAW,eAAiB,SAC9B,CAAA,MAAS,MAAO,CACd,QAAA,EAAA,CAAY,eAAiB,MAC/B,CACF,CACA,IAAA,CAAK,aAAA,CAAc,IAAI,MAAA,CAAQ,OAAA,CAAQ,GAAG,EAAE,CAAA,EAAG,MAAQ,KAAA,CAAM,EAAA,CAAG,EAAE,CAAA,EAAG,IAAA,EAAQ,EAAE,CAAA,CAC/E,GAAI,SAAW,CAAA,CAAG,MAAM,IAAI,qBAAA,CAAsB,CAAE,OAAA,CAAS,QAAS,CAAA,CAAG,aAAc,EAAG,QAAA,CAAU,IAAA,CAAM,CAAE,KAAA,CAAO,YAAa,CAAC,CAAA,CACjI,OAAO,CAAE,OAAA,CAAS,OAAA,CAAS,EAAG,aAAA,CAAe,IAAK,CACpD,CAEA,WAAA,CACE,OACA,KAAA,CACA,IAAA,CACqB,CACrB,GAAI,CAAC,wBAAwB,KAAA,CAAM,KAAA,CAAO,IAAI,CAAA,CAAG,CAC/C,MAAM,IAAI,aAAA,CACR,uBACA,CAAA,EAAG,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,IAAI,6CAC3B,CACF,CACA,MAAM,GAAA,CAAM,IAAA,CAAK,IAAA,GACjB,MAAM,OAAA,CAA+B,CACnC,GAAG,KAAA,CACH,MAAO,IAAA,CACP,SAAA,CAAW,IACX,GAAI,IAAA,GAAS,iBAAmB,CAAE,eAAA,CAAiB,GAAI,CAAA,CAAI,EAC7D,CAAA,CACA,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAA,CAAU,MAAA,CAAQ,MAAM,IAAI,CAAA,CAAG,OAAO,CAAA,CACzD,OAAO,OACT,CAEA,QAAA,CAAS,OAAkB,KAAA,CAAiD,CAC1E,MAAM,SAAA,CAAY,SAAA,CAAU,OAAQ,KAAA,CAAM,IAAA,CAAM,EAAE,CAAA,CAClD,IAAI,QAAA,CAAW,CAAA,CACf,IAAA,MAAW,GAAA,IAAO,KAAK,WAAA,CAAY,IAAA,GAAQ,CACzC,GAAI,IAAI,UAAA,CAAW,SAAS,EAAG,QAAA,EAAY,EAC7C,CACA,MAAM,OAAA,CAA+B,CAAE,GAAG,KAAA,CAAO,SAAU,SAAA,CAAW,IAAA,CAAK,MAAO,CAAA,CAClF,KAAK,SAAA,CAAU,GAAA,CAAI,UAAU,MAAA,CAAQ,KAAA,CAAM,IAAI,CAAA,CAAG,OAAO,EACzD,OAAO,OACT,CAEA,QAAA,CAAS,MAAA,CAAkB,KAAwC,CACjE,MAAM,MAAQ,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,SAAA,CAAU,MAAA,CAAQ,IAAI,CAAC,CAAA,CACxD,GAAI,QAAU,MAAA,CAAW,CACvB,MAAM,IAAI,aAAA,CACR,mBACA,CAAA,OAAA,EAAU,IAAI,sCAChB,CACF,CACA,OAAO,KACT,CAEA,MAAe,CACb,OAAO,KAAK,MAAA,CAAO,GAAA,GAAM,WAAA,EAC3B,CACF,ECpOA,IAAM,kBAAoB,GAAA,CAC1B,IAAM,oBAAsB,IAAA,CAIrB,IAAM,mBAAN,KAA+C,CAKpD,YAAY,KAAA,CAAc,OAAA,CAAuC,OAA+B,CAA/B,IAAA,CAAA,MAAA,CAAA,MAAA,CAC/D,IAAA,CAAK,MAAA,CAAS,KAAA,CACd,IAAA,CAAK,SAAW,QAClB,CAHiE,OAJxD,aAAA,CAAgB,IAAI,IACpB,MAAA,CACA,QAAA,CAOT,MAAM,eAAA,CAAgB,MAAA,CAAiE,CACrF,OAAO,IAAA,CAAK,cAAc,GAAA,CAAI,MAAM,CACtC,CAEA,MAAM,iBACJ,MAAA,CACA,KAAA,CACmC,CAInC,GAAI,KAAA,CAAM,sBAAwB,MAAA,CAAW,CAC3C,yBAAyB,KAAA,CAAM,mBAAA,CAAqB,qBAAqB,EAC3E,CACA,MAAM,QAAA,CAAW,IAAA,CAAK,cAAc,GAAA,CAAI,MAAM,EAC9C,GAAI,QAAA,GAAa,MAAA,EAAa,KAAA,CAAM,OAAA,EAAW,QAAA,CAAS,QAAS,CAC/D,MAAM,IAAI,iBAAA,CACR,sCAAA,CACA,6BAA6B,MAAA,CAAO,QAAA,CAAS,OAAO,CAAC,CAAA,4BAAA,EAA+B,OAAO,KAAA,CAAM,OAAO,CAAC,CAAA,CAAA,CAAA,CACzG,QAAA,CACA,KAAK,IAAA,EACP,CACF,CACA,MAAM,YAAwC,CAC5C,QAAA,CAAU,OACV,OAAA,CAAS,KAAA,CAAM,QACf,cAAA,CAAgB,KAAA,CAAM,eACtB,cAAA,CAAgB,KAAA,CAAM,eACtB,cAAA,CAAgB,KAAA,CAAM,eACtB,iBAAA,CAAmB,KAAA,CAAM,kBACzB,iBAAA,CAAmB,KAAA,CAAM,iBAAA,CACzB,GAAI,KAAA,CAAM,mBAAA,GAAwB,OAC9B,EAAC,CACD,CAAE,mBAAA,CAAqB,KAAA,CAAM,mBAAoB,CACvD,CAAA,CACA,KAAK,aAAA,CAAc,GAAA,CAAI,OAAQ,WAAW,CAAA,CAC1C,OAAO,WACT,CAEA,MAAM,SAAA,CAAU,MAAA,CAA+C,CAC7D,OAAO,IAAA,CAAK,SAAS,MAAM,CAC7B,CAEA,MAAM,UAAA,CAAW,OAA0C,CACzD,MAAM,YAAc,IAAA,CAAK,mBAAA,CAAoB,MAAM,CAAA,CACnD,MAAM,MAAQ,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,CAClC,MAAM,IAAA,CAAO,IAAA,CAAK,UAAA,CAAW,KAAK,EAClC,MAAM,WAAA,CACJ,YAAY,mBAAA,GAAwB,MAAA,EACpC,KAAK,IAAA,EAAK,CAAI,YAAY,mBAAA,CAC5B,OAAO,CACL,WAAA,CACA,KAAA,CACA,QAAS,IAAA,CAAK,QAAA,CAAS,YAAa,KAAA,CAAO,WAAW,EACtD,cAAA,CACE,IAAA,EAAQ,YAAY,cAAA,CAAiB,EAAA,CAAK,YAAY,cAAA,CAAiB,IAAA,CACzE,WACF,CACF,CAEA,MAAM,eAAA,CACJ,MAAA,CACA,cACyC,CACzC,OAAO,KAAK,MAAA,CAAO,eAAA,CAAgB,UAAU,MAAA,CAAQ,aAAa,CAAC,CAAA,EAAG,WACxE,CAEA,MAAM,OAAA,CACJ,MAAA,CACA,MAC6B,CAC7B,MAAM,YAAc,IAAA,CAAK,mBAAA,CAAoB,MAAM,CAAA,CAKnD,MAAM,MAAM,IAAA,CAAK,IAAA,CAAK,oBAAoB,MAAM,CAAC,EACjD,MAAM,GAAA,CAAM,UAAU,MAAA,CAAQ,KAAA,CAAM,aAAa,CAAA,CACjD,MAAM,SAAW,IAAA,CAAK,MAAA,CAAO,gBAAgB,GAAG,CAAA,CAChD,GAAI,QAAA,GAAa,MAAA,CAAW,CAC1B,GAAI,QAAA,CAAS,YAAY,KAAA,GAAU,UAAA,CAAY,CAC7C,GACE,QAAA,CAAS,WAAA,CAAY,IAAA,GAAS,KAAA,CAAM,IAAA,EACpC,SAAS,WAAA,CAAY,aAAA,GAAkB,MAAM,aAAA,EAC7C,QAAA,CAAS,YAAY,WAAA,GAAgB,KAAA,CAAM,aAC3C,QAAA,CAAS,WAAA,CAAY,cAAgB,KAAA,CAAM,WAAA,CAC3C,CACA,MAAM,IAAI,cACR,4BAAA,CACA,CAAA,YAAA,EAAe,KAAA,CAAM,aAAa,CAAA,+CAAA,CACpC,CACF,CACA,OAAO,QAAA,CAAS,WAClB,CACA,MAAM,IAAI,aAAA,CACR,6BAAA,CACA,eAAe,KAAA,CAAM,aAAa,eAAe,QAAA,CAAS,WAAA,CAAY,KAAK,CAAA,CAAA,CAC7E,CACF,CAEA,MAAM,KAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,CAClC,MAAM,WAAA,CACJ,WAAA,CAAY,sBAAwB,MAAA,EACpC,IAAA,CAAK,MAAK,CAAI,WAAA,CAAY,oBAC5B,GAAI,IAAA,CAAK,SAAS,WAAA,CAAa,KAAA,CAAO,WAAW,CAAA,GAAM,WAAA,CAAa,CAClE,MAAM,IAAI,cACR,yBAAA,CACA,gGACF,CACF,CAEA,MAAM,eACJ,KAAA,CAAM,IAAA,GAAS,SAAW,WAAA,CAAY,cAAA,CAAiB,YAAY,cAAA,CACrE,GAAI,MAAM,aAAA,CAAgB,cAAA,CAAgB,CACxC,MAAM,IAAI,cACR,0BAAA,CACA,CAAA,EAAG,MAAA,CAAO,KAAA,CAAM,aAAa,CAAC,sBAAsB,KAAA,CAAM,IAAI,aAAa,MAAA,CAAO,cAAc,CAAC,CAAA,OAAA,CACnG,CACF,CACA,GAAI,IAAA,CAAK,WAAW,KAAK,CAAA,CAAI,MAAM,aAAA,CAAgB,WAAA,CAAY,eAAgB,CAC7E,MAAM,IAAI,aAAA,CACR,wBAAA,CACA,aAAa,MAAA,CAAO,KAAA,CAAM,aAAa,CAAC,CAAA,sCAAA,EAAyC,OAAO,WAAA,CAAY,cAAc,CAAC,CAAA,OAAA,CACrH,CACF,CAEA,MAAM,GAAA,CAAM,KAAK,IAAA,EAAK,CACtB,MAAM,WAAA,CAAkC,CACtC,QAAA,CAAU,MAAA,CACV,aAAA,CAAe,KAAA,CAAM,cACrB,KAAA,CAAO,UAAA,CACP,KAAM,KAAA,CAAM,IAAA,CACZ,cAAe,KAAA,CAAM,aAAA,CACrB,YAAa,KAAA,CAAM,WAAA,CACnB,YAAa,KAAA,CAAM,WAAA,CACnB,UAAW,GAAA,CACX,SAAA,CAAW,IAAI,IAAA,CAAK,IAAA,CAAK,OAAO,GAAA,EAAI,CAAE,SAAQ,CAAI,KAAA,CAAM,KAAK,CAAA,CAAE,WAAA,EACjE,CAAA,CACA,IAAA,CAAK,OAAO,gBAAA,CAAiB,GAAA,CAAK,CAAE,WAAA,CAAa,YAAA,CAAc,KAAM,CAAC,CAAA,CACtE,KAAK,SAAA,CAAU,MAAA,CAAQ,CAAE,GAAG,KAAA,CAAO,aAAA,CAAe,MAAM,aAAA,CAAgB,KAAA,CAAM,aAAc,CAAC,CAAA,CAC7F,OAAO,WACT,CAEA,MAAM,mBAAA,CACJ,MAAA,CACA,MACgC,CAChC,MAAM,IAAM,SAAA,CAAU,MAAA,CAAQ,MAAM,aAAa,CAAA,CACjD,MAAM,MAAA,CAAS,IAAA,CAAK,mBAAA,CAAoB,OAAQ,KAAA,CAAM,aAAa,EACnE,MAAM,WAAA,CAAc,OAAO,WAAA,CAE3B,GAAI,YAAY,KAAA,GAAU,WAAA,CAAa,CACrC,OAAO,CACL,YACA,KAAA,CAAO,IAAA,CAAK,SAAS,MAAM,CAAA,CAC3B,YAAA,CAAc,MAAA,CAAO,YACvB,CACF,CACA,GAAI,WAAA,CAAY,QAAU,UAAA,CAAY,CACpC,MAAM,IAAI,aAAA,CACR,8BACA,CAAA,YAAA,EAAe,KAAA,CAAM,aAAa,CAAA,IAAA,EAAO,WAAA,CAAY,KAAK,CAAA,CAAA,CAC5D,CACF,CACA,GAAI,IAAA,CAAK,MAAK,EAAK,WAAA,CAAY,UAAW,CACxC,IAAA,CAAK,QAAQ,MAAA,CAAQ,GAAA,CAAK,OAAQ,SAAS,CAAA,CAC3C,MAAM,IAAI,aAAA,CACR,8BACA,CAAA,YAAA,EAAe,KAAA,CAAM,aAAa,CAAA,YAAA,EAAe,WAAA,CAAY,SAAS,CAAA,CAAA,CACxE,CACF,CACA,GACE,KAAA,CAAM,gBAAA,GAAqB,YAAY,aAAA,EACvC,KAAA,CAAM,sBAAwB,WAAA,CAAY,WAAA,CAC1C,CAGA,IAAA,CAAK,OAAA,CAAQ,OAAQ,GAAA,CAAK,MAAA,CAAQ,SAAS,CAAA,CAC3C,MAAM,IAAI,aAAA,CACR,4BAAA,CACA,8CAA8C,KAAA,CAAM,aAAa,GACnE,CACF,CAEA,GAAI,WAAA,CAAY,IAAA,GAAS,SAAU,CACjC,GAAI,CACF,MAAM,IAAA,CAAK,SAAS,MAAA,CAAO,MAAA,CAAQ,CACjC,IAAA,CAAM,WAAA,CAAY,YAClB,gBAAA,CAAkB,KAAA,CAAM,iBACxB,mBAAA,CAAqB,KAAA,CAAM,mBAC7B,CAAC,EACH,CAAA,MAAS,MAAO,CACd,IAAA,CAAK,QAAQ,MAAA,CAAQ,GAAA,CAAK,OAAQ,SAAS,CAAA,CAC3C,GACE,KAAA,YAAiB,aAAA,GAChB,MAAM,IAAA,GAAS,kBAAA,EAAsB,MAAM,IAAA,GAAS,sBAAA,CAAA,CACrD,CACA,MAAM,IAAI,cACR,4BAAA,CACA,CAAA,YAAA,EAAe,MAAM,aAAa,CAAA,oCAAA,CAAA,CAClC,CAAE,KAAA,CAAO,KAAM,CACjB,CACF,CACA,MAAM,KACR,CACF,CAIA,MAAM,YAAA,CAAe,KAAK,MAAA,CAAO,SAAA,CAAU,OAAQ,WAAA,CAAY,WAAW,CAAA,CAC1E,MAAM,OAAA,CAAU,IAAA,CAAK,QAAQ,MAAA,CAAQ,GAAA,CAAK,OAAQ,WAAA,CAAa,YAAY,EAE3E,GAAI,CAAC,aAAc,CACjB,IAAA,CAAK,OAAO,eAAA,CAAgB,MAAA,CAAQ,WAAW,CAAA,CAC/C,MAAM,QAAU,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,CACpC,IAAA,CAAK,SAAA,CAAU,OAAQ,CACrB,GAAG,QACH,oBAAA,CACE,WAAA,CAAY,OAAS,QAAA,CACjB,OAAA,CAAQ,qBAAuB,WAAA,CAAY,aAAA,CAC3C,QAAQ,oBAAA,CACd,oBAAA,CACE,YAAY,IAAA,GAAS,QAAA,CACjB,QAAQ,oBAAA,CAAuB,WAAA,CAAY,aAAA,CAC3C,OAAA,CAAQ,oBAAA,CACd,WAAA,CACE,YAAY,IAAA,GAAS,QAAA,CAAW,QAAQ,WAAA,CAAc,EAAA,CAAK,QAAQ,WACvE,CAAC,EACH,CAEA,OAAO,CAAE,WAAA,CAAa,OAAA,CAAS,MAAO,IAAA,CAAK,QAAA,CAAS,MAAM,CAAA,CAAG,YAAa,CAC5E,CAEA,MAAM,iBACJ,MAAA,CACA,aAAA,CAC6B,CAC7B,MAAM,GAAA,CAAM,UAAU,MAAA,CAAQ,aAAa,EAC3C,MAAM,MAAA,CAAS,KAAK,mBAAA,CAAoB,MAAA,CAAQ,aAAa,CAAA,CAC7D,GAAI,OAAO,WAAA,CAAY,KAAA,GAAU,UAAA,CAAY,OAAO,MAAA,CAAO,WAAA,CAC3D,OAAO,IAAA,CAAK,OAAA,CAAQ,OAAQ,GAAA,CAAK,MAAA,CAAQ,SAAS,CACpD,CAEA,CAAC,mBAAA,CAAoB,MAAA,CAAkB,IAAM,IAAA,CAAK,IAAA,GAAQ,KAAA,CAAQ,MAAA,CAAO,iBAAwD,CAC/H,MAAM,OAAS,SAAA,CAAU,MAAA,CAAQ,EAAE,CAAA,CACnC,IAAI,QAAU,CAAA,CACd,IAAA,KAAW,CAAC,GAAA,CAAK,MAAM,IAAK,IAAA,CAAK,MAAA,CAAO,cAAa,CAAG,CACtD,GAAI,CAAC,GAAA,CAAI,WAAW,MAAM,CAAA,EAAK,MAAA,CAAO,WAAA,CAAY,KAAA,GAAU,UAAA,EAAc,IAAM,MAAA,CAAO,WAAA,CAAY,UAAW,SAC9G,MAAM,KAAK,OAAA,CAAQ,MAAA,CAAQ,IAAK,MAAA,CAAQ,SAAA,CAAW,MAAO,GAAG,CAAA,CAC7D,GAAI,EAAE,OAAA,GAAY,MAAO,MAC3B,CACF,CAEA,MAAM,cAAA,CAAe,OAAkB,KAAA,CAAgE,CACrG,0BAA0B,KAAK,CAAA,CAC/B,yBAAyB,KAAA,CAAM,aAAA,CAAe,eAAe,CAAA,CAC7D,IAAI,QAAU,CAAA,CAAG,aAAA,CAAgB,GAAI,OAAA,CAAU,CAAA,CAAG,KAAO,KAAA,CACzD,GAAI,CACF,IAAA,MAAW,WAAA,IAAe,IAAA,CAAK,oBAAoB,MAAA,CAAQ,KAAA,CAAM,IAAK,KAAA,CAAM,KAAK,EAAG,CAClF,OAAA,EAAA,CACA,eAAiB,WAAA,CAAY,cAC/B,CACF,CAAA,MAAS,KAAA,CAAO,CACd,MAAM,IAAI,sBAAsB,CAAE,OAAA,CAAS,OAAA,CAAS,aAAc,CAAA,CAAG,CAAA,CAAG,KAAM,CAAE,KAAM,CAAC,CACzF,CACA,MAAM,MAAA,CAAS,SAAA,CAAU,OAAQ,EAAE,CAAA,CACnC,GAAI,CACF,IAAA,KAAW,CAAC,GAAA,CAAK,MAAM,IAAK,IAAA,CAAK,MAAA,CAAO,YAAA,EAAa,CAAG,CACtD,GAAI,CAAC,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,CAAG,SAC7B,MAAM,GAAA,CAAM,MAAA,CAAO,YACnB,MAAM,YAAA,CAAe,IAAI,KAAA,GAAU,UAAA,EAAc,IAAI,SAAA,EAAa,KAAA,CAAM,IACxE,MAAM,YAAA,CAAA,CAAgB,IAAI,KAAA,GAAU,SAAA,EAAa,IAAI,KAAA,GAAU,SAAA,GAAc,IAAI,SAAA,GAAc,KAAA,CAAA,EAAa,IAAI,SAAA,CAAY,KAAA,CAAM,cAClI,GAAI,CAAC,cAAgB,CAAC,YAAA,CAAc,SACpC,GAAI,YAAA,EAAgB,QAAU,OAAA,GAAY,KAAA,CAAM,KAAA,CAAO,CAAE,IAAA,CAAO,IAAA,CAAM,QAAU,CAChF,IAAA,CAAK,OAAO,iBAAA,CAAkB,GAAG,EAAG,OAAA,GACtC,CACF,OAAS,KAAA,CAAO,CACd,MAAM,IAAI,qBAAA,CAAsB,CAAE,OAAA,CAAS,OAAA,CAAS,aAAc,CAAA,CAAG,CAAA,CAAG,OAAW,CAAE,KAAM,CAAC,CAC9F,CACA,OAAO,CAAE,OAAA,CAAS,QAAS,aAAA,CAAe,IAAK,CACjD,CAEA,OAAA,CACE,OACA,GAAA,CACA,MAAA,CACA,MACA,YAAA,CAAe,KAAA,CACf,UAAY,IAAA,CAAK,IAAA,EAAK,CACF,CACpB,MAAM,OAAA,CAA8B,CAClC,GAAG,MAAA,CAAO,YACV,KAAA,CACA,SACF,EACA,MAAM,KAAA,CAAQ,KAAK,QAAA,CAAS,MAAM,EAClC,GAAI,KAAA,CAAM,cAAgB,MAAA,CAAO,WAAA,CAAY,cAAe,CAC1D,MAAM,IAAI,aAAA,CAAc,4BAAA,CAA8B,wDAAwD,CAChH,CACA,KAAK,MAAA,CAAO,gBAAA,CAAiB,IAAK,CAAE,WAAA,CAAa,QAAS,YAAa,CAAC,EACxE,IAAA,CAAK,SAAA,CAAU,OAAQ,CAAE,GAAG,MAAO,aAAA,CAAe,KAAA,CAAM,aAAA,CAAgB,MAAA,CAAO,WAAA,CAAY,aAAc,CAAC,CAAA,CAC1G,OAAO,OACT,CAEA,QAAA,CACE,YACA,KAAA,CACA,WAAA,CACqB,CACrB,MAAM,IAAA,CAAO,KAAK,UAAA,CAAW,KAAK,EAClC,GAAI,IAAA,EAAQ,YAAY,cAAA,CAAgB,CAItC,MAAM,eAAA,CAAkB,WAAA,CAAY,mBAAA,GAAwB,OAC5D,OAAO,eAAA,EAAmB,CAAC,WAAA,CAAc,WAAA,CAAc,SACzD,CACA,GACE,YAAY,cAAA,CAAiB,EAAA,EAC7B,KAAO,mBAAA,EAAuB,WAAA,CAAY,eAAiB,iBAAA,CAC3D,CACA,OAAO,SACT,CACA,OAAO,QACT,CAEA,UAAA,CAAW,MAAmC,CAC5C,OAAO,MAAM,oBAAA,CAAuB,KAAA,CAAM,qBAAuB,KAAA,CAAM,aACzE,CAEA,QAAA,CAAS,MAAA,CAAsC,CAAE,OAAO,IAAA,CAAK,OAAO,SAAA,CAAU,MAAM,CAAG,CACvF,SAAA,CAAU,OAAkB,KAAA,CAAiC,CAC3D,KAAK,MAAA,CAAO,UAAA,CAAW,OAAQ,CAAE,GAAG,MAAO,SAAA,CAAW,IAAA,CAAK,MAAO,CAAC,EACrE,CAEA,mBAAA,CAAoB,OAA4C,CAC9D,MAAM,YAAc,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA,CACjD,GAAI,cAAgB,MAAA,CAAW,CAC7B,MAAM,IAAI,aAAA,CACR,8BACA,yDACF,CACF,CACA,OAAO,WACT,CAEA,mBAAA,CAAoB,MAAA,CAAkB,cAA0C,CAC9E,MAAM,OAAS,IAAA,CAAK,MAAA,CAAO,gBAAgB,SAAA,CAAU,MAAA,CAAQ,aAAa,CAAC,CAAA,CAC3E,GAAI,MAAA,GAAW,MAAA,CAAW,CACxB,MAAM,IAAI,cACR,+BAAA,CACA,CAAA,YAAA,EAAe,aAAa,CAAA,+BAAA,CAC9B,CACF,CACA,OAAO,MACT,CAEA,IAAA,EAAe,CACb,OAAO,IAAA,CAAK,MAAA,CAAO,GAAA,GAAM,WAAA,EAC3B,CACF,EClYA,IAAMD,oBAAqB,EAAA,CAOpB,IAAM,uBAAN,KAAuD,CACnD,OAAS,IAAI,GAAA,CAEtB,MAAM,OAAA,CAAQ,MAAA,CAAkB,MAA0D,CACxF,KAAM,CAAE,QAAS,CAAA,CAAI,MACrB,MAAM,UAAA,CAAa,uBAAuB,QAAQ,CAAA,CAClD,GAAI,CAAC,UAAA,CAAW,GAAI,CAClB,MAAM,IAAI,aAAA,CACR,6BAAA,CACA,uBAAuB,IAAA,CAAK,SAAA,CAAU,SAAS,IAAI,CAAC,CAAA,EAAA,EAAK,UAAA,CAAW,MAAM,CAAA,QAAA,EAAM,WAAW,MAAM,CAAA,CACnG,CACF,CAEA,MAAM,SAAW,IAAI,GAAA,CACrB,UAAW,IAAA,IAAQ,KAAA,CAAM,MAAO,CAC9B,GAAI,SAAS,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA,CAAG,CAC3B,MAAM,IAAI,aAAA,CACR,6BAAA,CACA,uBAAuB,IAAA,CAAK,SAAA,CAAU,SAAS,IAAI,CAAC,KAAK,IAAA,CAAK,SAAA,CAAU,KAAK,IAAI,CAAC,sBACpF,CACF,CACA,SAAS,GAAA,CAAI,IAAA,CAAK,KAAM,IAAA,CAAK,OAAO,EACtC,CAEA,IAAA,MAAW,QAAA,IAAY,SAAS,KAAA,CAAO,CACrC,MAAM,OAAA,CAAU,QAAA,CAAS,IAAI,QAAA,CAAS,IAAI,EAC1C,GAAI,OAAA,GAAY,OAAW,CACzB,MAAM,IAAI,aAAA,CACR,6BAAA,CACA,uBAAuB,IAAA,CAAK,SAAA,CAAU,SAAS,IAAI,CAAC,KAAK,IAAA,CAAK,SAAA,CAAU,SAAS,IAAI,CAAC,oCACxF,CACF,CACA,MAAM,KAAA,CAAQ,IAAI,aAAY,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,MAAA,CAChD,GAAI,KAAA,GAAU,QAAA,CAAS,QAAA,CAAU,CAC/B,MAAM,IAAI,cACR,6BAAA,CACA,CAAA,oBAAA,EAAuB,KAAK,SAAA,CAAU,QAAA,CAAS,IAAI,CAAC,CAAA,EAAA,EAAK,KAAK,SAAA,CAAU,QAAA,CAAS,IAAI,CAAC,CAAA,UAAA,EAAa,SAAS,QAAQ,CAAA,oBAAA,EAAuB,KAAK,CAAA,CAAA,CAClJ,CACF,CACF,CACA,GAAI,SAAS,IAAA,GAAS,QAAA,CAAS,MAAM,MAAA,CAAQ,CAC3C,MAAM,IAAI,aAAA,CACR,8BACA,CAAA,oBAAA,EAAuB,IAAA,CAAK,UAAU,QAAA,CAAS,IAAI,CAAC,CAAA,EAAA,EAAK,QAAA,CAAS,IAAI,CAAA,yBAAA,EAA4B,QAAA,CAAS,KAAA,CAAM,MAAM,CAAA,eAAA,CACzH,CACF,CAEA,MAAM,KAAA,CAAQ,oBAAoB,QAAA,CAAU,QAAA,CAAS,IAAI,qBAAqB,CAAE,EAChF,GAAI,CAAC,MAAM,EAAA,CAAI,CACb,MAAM,IAAI,aAAA,CACR,8BACA,CAAA,oBAAA,EAAuB,IAAA,CAAK,UAAU,QAAA,CAAS,IAAI,CAAC,CAAA,EAAA,EAAK,KAAA,CAAM,MAAM,CAAA,QAAA,EAAM,KAAA,CAAM,MAAM,CAAA,CACzF,CACF,CAEA,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,CAAU,MAAA,CAAQ,SAAS,IAAI,CAAA,CAAG,CAAE,QAAA,CAAU,QAAS,CAAC,CAAA,CACxE,OAAO,QACT,CAEA,MAAM,GAAA,CAAI,OAAkB,IAAA,CAAsD,CAChF,OAAO,IAAA,CAAK,MAAA,CAAO,IAAI,SAAA,CAAU,MAAA,CAAQ,IAAI,CAAC,CAAA,EAAG,QACnD,CAEA,MAAM,KAAK,MAAA,CAAkB,KAAA,CAAkE,CAC7F,MAAM,MAAA,CAAS,SAAA,CAAU,OAAQ,EAAE,CAAA,CACnC,MAAM,SAAA,CAAiC,GACvC,IAAA,KAAW,CAAC,IAAK,IAAI,CAAA,GAAK,KAAK,MAAA,CAAO,OAAA,GAAW,CAC/C,GAAI,CAAC,GAAA,CAAI,UAAA,CAAW,MAAM,CAAA,CAAG,SAC7B,SAAA,CAAU,KAAK,IAAA,CAAK,QAAQ,EAC9B,CACA,SAAA,CAAU,KAAK,CAAC,IAAA,CAAM,QAAW,IAAA,CAAK,IAAA,CAAO,MAAM,IAAA,CAAO,EAAA,CAAK,KAAK,IAAA,CAAO,KAAA,CAAM,KAAO,CAAA,CAAI,CAAE,EAC9F,OAAO,SAAA,CAAU,MAAM,CAAA,CAAG,KAAA,CAAM,OAASA,mBAAkB,CAC7D,CAEA,MAAM,QAAA,CACJ,OACA,IAAA,CACA,IAAA,CAC2C,CAC3C,MAAM,IAAA,CAAO,KAAK,MAAA,CAAO,GAAA,CAAI,UAAU,MAAA,CAAQ,IAAI,CAAC,CAAA,CACpD,GAAI,IAAA,GAAS,OAAW,OAAO,MAAA,CAC/B,MAAM,QAAA,CAAW,IAAA,CAAK,SAAS,KAAA,CAAM,IAAA,CAAM,MAAS,IAAA,CAAK,IAAA,GAAS,IAAI,CAAA,CACtE,MAAM,QAAU,IAAA,CAAK,QAAA,CAAS,IAAI,IAAI,CAAA,CACtC,GAAI,QAAA,GAAa,MAAA,EAAa,UAAY,MAAA,CAAW,OAAO,OAC5D,OAAO,CACL,KAAM,QAAA,CAAS,IAAA,CACf,YAAa,QAAA,CAAS,WAAA,CACtB,SAAU,QAAA,CAAS,QAAA,CACnB,OACF,CACF,CACF,ECzGA,IAAM,sBAAA,CAAyB,GAAA,CAExB,IAAM,kBAAA,CAAN,KAA+C,CAC3C,QAAA,CAAW,IAAI,IACf,MAAA,CAET,WAAA,CAAY,MAAc,CACxB,IAAA,CAAK,OAAS,MAChB,CAEA,MAAM,aAAA,CAAc,MAAA,CAAkB,MAAiD,CACrF,MAAM,IAAM,SAAA,CAAU,MAAA,CAAQ,gBAAiB,KAAA,CAAM,MAAM,EAC3D,MAAM,QAAA,CAAW,KAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,CACtC,GAAI,WAAa,MAAA,CAAW,CAC1B,GAAI,QAAA,CAAS,WAAA,GAAgB,MAAM,WAAA,CAAa,CAE9C,OAAO,QACT,CACA,MAAM,IAAI,iBAAA,CACR,mBAAA,CACA,QAAQ,KAAA,CAAM,MAAM,mEACpB,QAAA,CACA,IAAA,CAAK,MACP,CACF,CACA,MAAM,MAAA,CAAsB,CAC1B,QAAA,CAAU,MAAA,CACV,KAAM,eAAA,CACN,SAAA,CAAW,MAAM,MAAA,CACjB,GAAA,CAAK,EACL,WAAA,CAAa,KAAA,CAAM,YACnB,QAAA,CAAU,KAAA,CAAM,SAChB,IAAA,CAAM,KAAA,CAAM,KACZ,GAAI,KAAA,CAAM,QAAU,MAAA,CAAY,GAAK,CAAE,KAAA,CAAO,MAAM,KAAM,CAAA,CAC1D,GAAI,KAAA,CAAM,SAAA,GAAc,MAAA,CAAY,EAAC,CAAI,CAAE,UAAW,KAAA,CAAM,SAAU,EACtE,SAAA,CAAW,IAAA,CAAK,MAClB,CAAA,CACA,KAAK,QAAA,CAAS,GAAA,CAAI,IAAK,MAAM,CAAA,CAC7B,OAAO,MACT,CAEA,MAAM,aAAA,CAAc,MAAA,CAAkB,MAAiD,CACrF,MAAM,IAAM,SAAA,CAAU,MAAA,CAAQ,MAAM,IAAA,CAAM,KAAA,CAAM,SAAS,CAAA,CACzD,MAAM,SAAW,IAAA,CAAK,QAAA,CAAS,IAAI,GAAG,CAAA,CACtC,MAAM,UAAA,CAAa,QAAA,EAAU,KAAO,CAAA,CACpC,GAAI,KAAA,CAAM,WAAA,GAAgB,UAAA,CAAY,CACpC,MAAM,IAAI,iBAAA,CACR,0BACA,CAAA,OAAA,EAAU,KAAA,CAAM,IAAI,CAAA,CAAA,EAAI,KAAA,CAAM,SAAS,CAAA,WAAA,EAAc,UAAU,SAAS,KAAA,CAAM,WAAW,IACzF,QAAA,CACA,IAAA,CAAK,MACP,CACF,CACA,MAAM,MAAA,CAAsB,CAC1B,QAAA,CAAU,MAAA,CACV,KAAM,KAAA,CAAM,IAAA,CACZ,UAAW,KAAA,CAAM,SAAA,CACjB,IAAK,UAAA,CAAa,CAAA,CAClB,YAAa,KAAA,CAAM,WAAA,CACnB,SAAU,KAAA,CAAM,QAAA,CAChB,KAAM,KAAA,CAAM,IAAA,CACZ,GAAI,KAAA,CAAM,KAAA,GAAU,MAAA,CAAY,EAAC,CAAI,CAAE,MAAO,KAAA,CAAM,KAAM,EAC1D,GAAI,KAAA,CAAM,YAAc,MAAA,CAAY,GAAK,CAAE,SAAA,CAAW,MAAM,SAAU,CAAA,CACtE,UAAW,IAAA,CAAK,IAAA,EAClB,CAAA,CACA,IAAA,CAAK,SAAS,GAAA,CAAI,GAAA,CAAK,MAAM,CAAA,CAC7B,OAAO,MACT,CAEA,MAAM,UACJ,MAAA,CACA,QAAA,CACkC,CAClC,OAAO,IAAA,CAAK,SAAS,GAAA,CAAI,SAAA,CAAU,OAAQ,QAAA,CAAS,IAAA,CAAM,QAAA,CAAS,SAAS,CAAC,CAC/E,CAEA,MAAM,YAAA,CACJ,OACA,KAAA,CACwC,CACxC,MAAM,MAAA,CAAS,SAAA,CAAU,OAAQ,EAAE,CAAA,CACnC,MAAM,OAAA,CAAgC,GACtC,IAAA,KAAW,CAAC,IAAK,MAAM,CAAA,GAAK,IAAA,CAAK,QAAA,CAAS,OAAA,EAAQ,CAAG,CACnD,GAAI,CAAC,IAAI,UAAA,CAAW,MAAM,EAAG,SAC7B,GAAI,MAAM,IAAA,GAAS,MAAA,EAAa,OAAO,IAAA,GAAS,KAAA,CAAM,KAAM,SAC5D,GAAI,MAAM,SAAA,GAAc,MAAA,EAAa,CAAC,MAAA,CAAO,SAAA,CAAU,UAAA,CAAW,MAAM,SAAS,CAAA,CAAG,CAClF,QACF,CACA,QAAQ,IAAA,CAAK,CACX,KAAM,MAAA,CAAO,IAAA,CACb,UAAW,MAAA,CAAO,SAAA,CAClB,IAAK,MAAA,CAAO,GAAA,CACZ,YAAa,MAAA,CAAO,WAAA,CACpB,SAAU,MAAA,CAAO,QAAA,CACjB,GAAI,MAAA,CAAO,KAAA,GAAU,OAAY,EAAC,CAAI,CAAE,KAAA,CAAO,MAAA,CAAO,KAAM,CAAA,CAC5D,SAAA,CAAW,OAAO,SACpB,CAAC,EACH,CACA,OAAA,CAAQ,KACN,CAAC,IAAA,CAAM,KAAA,GACL,IAAA,CAAK,IAAA,CAAK,aAAA,CAAc,MAAM,IAAI,CAAA,EAAK,KAAK,SAAA,CAAU,aAAA,CAAc,MAAM,SAAS,CACvF,EACA,OAAO,OAAA,CAAQ,MAAM,CAAA,CAAG,KAAA,CAAM,OAAS,sBAAsB,CAC/D,CAEA,IAAA,EAAe,CACb,OAAO,IAAA,CAAK,MAAA,CAAO,KAAI,CAAE,WAAA,EAC3B,CACF,MCvHa,qBAAA,CAAwB,2BAE9B,SAAS,kBAAA,CAAmB,KAAA,CAAc,IAAI,IAAA,CAAK,qBAAqB,EAAiB,CAC9F,IAAI,QAAU,KAAA,CAAM,OAAA,EAAQ,CAC5B,OAAO,CACL,GAAA,EAAY,CACV,OAAO,IAAI,KAAK,OAAO,CACzB,EACA,OAAA,CAAQ,EAAA,CAAkB,CACxB,OAAA,EAAW,GACb,EACA,GAAA,CAAI,OAAA,CAAqB,CACvB,OAAA,CAAU,OAAA,CAAQ,UACpB,CACF,CACF,CCPA,SAAS,UAAU,KAAA,CAAkD,CACnE,OAAO,IAAA,CAAK,SAAA,CAAU,CACpB,KAAA,CAAM,QAAA,CACN,MAAM,MAAA,CACN,KAAA,CAAM,UACN,KAAA,CAAM,QAAA,CACN,MAAM,QAAA,CACN,KAAA,CAAM,OACN,KAAA,CAAM,GACR,CAAC,CACH,CAGO,IAAM,uCAAN,KAAuF,CACnF,gBAAkB,IAAI,GAAA,CAE/B,MAAM,OAAA,CAAQ,KAAA,CAA4D,CACxE,MAAM,SAAA,CAAY,KAAK,KAAA,CAAM,KAAA,CAAM,SAAS,CAAA,CAC5C,GAAI,CAAC,MAAA,CAAO,QAAA,CAAS,SAAS,CAAA,CAAG,MAAM,IAAI,MAAM,2CAA2C,CAAA,CAC5F,MAAM,GAAA,CAAM,SAAA,CAAU,KAAK,CAAA,CAC3B,GAAI,KAAK,eAAA,CAAgB,GAAA,CAAI,GAAG,CAAA,CAAG,aACnC,IAAA,CAAK,eAAA,CAAgB,IAAI,GAAA,CAAK,SAAS,CAAA,CACvC,OAAO,IACT,CAEA,MAAM,cAAA,CAAe,MAAA,CAAkB,MAA2D,CAChG,yBAAA,CAA0B,KAAK,CAAA,CAC/B,MAAM,OAAS,IAAA,CAAK,KAAA,CAAM,MAAM,GAAG,CAAA,CACnC,IAAI,OAAA,CAAU,CAAA,CAAG,KAAO,KAAA,CACxB,IAAA,KAAW,CAAC,GAAA,CAAK,SAAS,IAAK,IAAA,CAAK,eAAA,CAAiB,CACnD,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,GAAM,MAAA,EAAU,UAAY,MAAA,CAAQ,SACzD,GAAI,OAAA,GAAY,KAAA,CAAM,MAAO,CAAE,IAAA,CAAO,IAAA,CAAM,KAAO,CACnD,IAAA,CAAK,gBAAgB,MAAA,CAAO,GAAG,EAAG,OAAA,GACpC,CACA,OAAO,CAAE,OAAA,CAAS,QAAS,CAAA,CAAG,aAAA,CAAe,GAAI,IAAK,CACxD,CACF,ECXO,SAAS,yBACd,OAAA,CACyB,CACzB,MAAM,KAAA,CAAe,OAAA,CAAQ,OAAS,kBAAA,EAAmB,CACzD,MAAM,MAAA,CAAS,IAAI,sBAAsB,KAAK,CAAA,CAC9C,MAAM,OAAA,CAAU,IAAI,oBAAoB,KAAA,CAAO,CAAE,OAAQ,KAAA,CAAO,OAAA,CAAQ,WAAY,CAAC,CAAA,CACrF,MAAM,KAAA,CAAQ,IAAI,kBAAA,CAAmB,MAAO,OAAA,CAAS,MAAM,EAC3D,MAAM,MAAA,CAAqB,CACzB,OAAA,CAAS,IAAI,qBAAqB,KAAA,CAAO,KAAK,EAC9C,KAAA,CAAO,IAAI,mBAAmB,KAAK,CAAA,CACnC,MAAO,IAAI,kBAAA,CAAmB,KAAK,CAAA,CACnC,QAAA,CAAU,IAAI,qBAAA,CAAsB,KAAK,EACzC,OAAA,CACA,KAAA,CACA,WAAY,IAAI,sBAClB,EACA,OAAO,CAAE,OAAQ,KAAM,CACzB,CAGO,SAAS,sCAAA,CAAuC,YAGrD,CACA,MAAM,KAAA,CAAQ,kBAAA,EAAmB,CACjC,OAAO,CAAE,MAAA,CAAQ,wBAAA,CAAyB,CAAE,KAAA,CAAO,WAAY,CAAC,CAAA,CAAE,MAAA,CAAQ,KAAM,CAClF,KCpEa,oBAAA,CAAuB,MAAA,CAAO,OAAO,CAAC,KAAA,CAAO,MAAO,KAAA,CAAO,KAAA,CAAO,KAAA,CAAO,KAAA,CAAO,KAAK,CAAU,EAqBrG,IAAM,kBAAA,CAAqB,IAAM,MAMjC,IAAM,gBAAkB,IAAA,CAAK,GAAA,CAAI,IAAM,CAAA,CAAG,CAAC,EAC3C,IAAM,eAAA,CAAkB,KAAK,GAAA,CAAI,IAAA,CAAM,EAAG,CAAC,EAIlD,IAAM,IAAA,CAAO,IAAI,GAAA,CAAI,CAAC,QAAA,CAAU,MAAA,CAAQ,aAAc,YAAA,CAAc,OAAA,CAAS,IAAI,CAAC,CAAA,CAElF,IAAM,gBAAA,CAAmB,CAAC,GAAI,EAAA,CAAI,EAAA,CAAI,GAAI,EAAA,CAAI,EAAA,CAAI,GAAI,EAAA,CAAI,EAAA,CAAI,GAAI,EAAA,CAAI,EAAE,EACxE,IAAM,OAAA,CAAU,kDAChB,IAAM,MAAA,CAAS,MAEf,IAAM,YAAA,CAA4C,CAAC,KAAA,CAAO,KAAA,CAAO,MAAO,KAAA,CAAO,KAAA,CAAO,MAAO,KAAK,CAAA,CAGlG,IAAM,aAAA,CAAN,cAA4B,KAAM,CACvB,IAAA,CACT,WAAA,CAAY,KAAgC,OAAA,CAAiB,CAAE,MAAM,OAAO,CAAA,CAAG,KAAK,IAAA,CAAO,KAAM,CACnG,CAAA,CACA,IAAM,QAAW,OAAA,EAAoB,IAAI,cAAc,kBAAA,CAAoB,OAAO,EAElF,SAAS,OAAA,CAAQ,MAAgB,IAAA,CAAc,GAAA,CAAa,IAAqB,CAC/E,GAAI,OAAO,KAAA,GAAU,QAAA,EAAY,CAAC,MAAA,CAAO,SAAA,CAAU,KAAK,CAAA,EAAK,KAAA,CAAQ,KAAO,KAAA,CAAQ,GAAA,CAAK,MAAM,OAAA,CAAQ,CAAA,EAAG,IAAI,CAAA,oBAAA,EAAuB,GAAG,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAA,CACjJ,OAAO,KACT,CAEA,IAAM,UAAA,CAAa,IAAI,IACvB,SAAS,SAAA,CAAU,GAAiC,CAClD,IAAI,EAAI,UAAA,CAAW,GAAA,CAAI,EAAE,CAAA,CACzB,GAAI,CAAC,CAAA,CAAG,CACN,EAAI,IAAI,IAAA,CAAK,eAAe,OAAA,CAAS,CAAE,SAAU,EAAA,CAAI,SAAA,CAAW,MAAO,IAAA,CAAM,SAAA,CAAW,MAAO,SAAA,CAAW,GAAA,CAAK,UAAW,IAAA,CAAM,SAAA,CAAW,OAAQ,SAAA,CAAW,MAAA,CAAQ,SAAU,CAAC,CAAA,CACjL,GAAI,UAAA,CAAW,IAAA,EAAQ,EAAA,CAAI,WAAW,MAAA,CAAO,UAAA,CAAW,MAAK,CAAE,IAAA,GAAO,KAAM,CAAA,CAC5E,WAAW,GAAA,CAAI,EAAA,CAAI,CAAC,EACtB,CACA,OAAO,CACT,CAEA,SAAS,OAAA,CAAQ,EAAA,CAAqB,CACpC,GAAI,OAAO,EAAA,GAAO,UAAY,CAAC,OAAA,CAAQ,KAAK,EAAE,CAAA,CAAG,MAAM,IAAI,aAAA,CAAc,aAAc,CAAA,EAAG,IAAA,CAAK,UAAU,EAAE,CAAC,2BAA2B,CAAA,CACvI,GAAI,CAAE,SAAA,CAAU,EAAE,EAAG,CAAA,KAAQ,CAAE,MAAM,IAAI,aAAA,CAAc,YAAA,CAAc,IAAI,EAAE,CAAA,0BAAA,CAA4B,CAAG,CAC1G,OAAO,EACT,CAEA,SAAS,MAAM,QAAA,CAAmC,CAChD,GAAI,QAAA,GAAa,IAAA,EAAQ,OAAO,QAAA,GAAa,QAAA,EAAY,MAAM,OAAA,CAAQ,QAAQ,EAAG,MAAM,OAAA,CAAQ,4BAA4B,CAAA,CAC5H,IAAA,MAAW,OAAO,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAG,GAAI,CAAC,IAAA,CAAK,GAAA,CAAI,GAAG,CAAA,CAAG,MAAM,QAAQ,CAAA,cAAA,EAAiB,GAAG,CAAA,CAAE,CAAA,CACjG,MAAM,CAAA,CAAY,CAAE,MAAA,CAAQ,OAAA,CAAQ,SAAS,MAAA,CAAQ,QAAA,CAAU,EAAG,EAAE,CAAA,CAAG,KAAM,OAAA,CAAQ,QAAA,CAAS,KAAM,MAAA,CAAQ,CAAA,CAAG,EAAE,CAAA,CAAG,EAAA,CAAI,QAAQ,QAAA,CAAS,EAAE,CAAE,CAAA,CAC7I,MAAM,EAAI,QAAA,CACV,GAAI,EAAE,UAAA,GAAe,MAAA,EAAa,EAAE,UAAA,GAAe,MAAA,CAAW,MAAM,OAAA,CAAQ,8CAA8C,EAC1H,GAAI,CAAA,CAAE,QAAU,MAAA,EAAa,CAAA,CAAE,aAAe,MAAA,CAAW,MAAM,OAAA,CAAQ,wBAAwB,CAAA,CAC/F,GAAI,EAAE,UAAA,GAAe,MAAA,CAAW,CAC9B,GAAI,CAAC,MAAM,OAAA,CAAQ,CAAA,CAAE,UAAU,CAAA,EAAK,CAAA,CAAE,WAAW,MAAA,CAAS,CAAA,EAAK,EAAE,UAAA,CAAW,MAAA,CAAS,EAAG,MAAM,OAAA,CAAQ,+BAA+B,CAAA,CACrI,IAAA,MAAW,KAAK,CAAA,CAAE,UAAA,CAAY,GAAI,CAAE,oBAAA,CAA4C,SAAS,CAAC,CAAA,CAAG,MAAM,OAAA,CAAQ,CAAA,YAAA,EAAe,KAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAE,CAAA,CAC7I,EAAE,IAAA,CAAO,IAAI,GAAA,CAAI,CAAA,CAAE,UAAgC,EACrD,CACA,GAAI,CAAA,CAAE,aAAe,MAAA,CAAW,CAC9B,EAAE,UAAA,CAAa,OAAA,CAAQ,EAAE,UAAA,CAAY,YAAA,CAAc,EAAG,EAAE,CAAA,CACxD,GAAI,CAAA,CAAE,KAAA,GAAU,OAAW,CACzB,CAAA,CAAE,KAAA,CAAQ,OAAA,CAAQ,CAAA,CAAE,KAAA,CAAO,QAAS,CAAA,CAAG,EAAE,EACzC,GAAI,CAAA,CAAE,QAAU,CAAA,EAAK,CAAA,CAAE,aAAe,EAAA,CAAI,CACxC,MAAM,IAAI,aAAA,CAAc,0BAA2B,2GAA2G,CAChK,CACA,GAAI,CAAA,CAAE,UAAA,CAAa,gBAAA,CAAiB,CAAA,CAAE,KAAA,CAAQ,CAAC,CAAA,CAAI,CACjD,MAAM,IAAI,aAAA,CAAc,uBAAwB,CAAA,MAAA,EAAS,CAAA,CAAE,KAAK,CAAA,YAAA,EAAe,CAAA,CAAE,UAAU,CAAA,CAAE,CAC/F,CACF,CACF,CACA,OAAO,CACT,CAGO,SAAS,oBAAA,CAAqB,QAAA,CAAiD,CACpF,GAAI,CAAE,MAAM,QAAQ,CAAA,CAAG,OAAO,CAAE,EAAA,CAAI,IAAK,CAAG,CAAA,MAAS,EAAG,CACtD,GAAI,aAAa,aAAA,CAAe,OAAO,CAAE,EAAA,CAAI,KAAA,CAAO,IAAA,CAAM,CAAA,CAAE,IAAA,CAAM,OAAA,CAAS,EAAE,OAAQ,CAAA,CACrF,MAAM,CACR,CACF,CAGA,SAAS,UAAA,CAAW,GAAY,OAAA,CAAyB,CACvD,MAAM,CAAA,CAA4B,GAClC,IAAA,MAAW,IAAA,IAAQ,UAAU,EAAE,CAAA,CAAE,cAAc,OAAO,CAAA,CAAG,GAAI,IAAA,CAAK,IAAA,GAAS,UAAW,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,CAAI,MAAA,CAAO,KAAK,KAAK,CAAA,CACtH,OAAO,IAAA,CAAK,GAAA,CAAI,EAAE,IAAA,CAAO,CAAA,CAAE,MAAS,CAAA,CAAG,CAAA,CAAE,GAAA,CAAM,CAAA,CAAE,IAAA,CAAO,CAAA,CAAE,OAAS,CAAA,CAAE,MAAO,CAC9E,CACA,IAAM,SAAW,CAAC,EAAA,CAAY,UAAoB,UAAA,CAAW,EAAA,CAAI,OAAO,CAAA,CAAI,IAAA,CAAK,MAAM,OAAA,CAAU,GAAI,EAAI,GAAA,CAOzG,SAAS,QAAQ,EAAA,CAAY,KAAA,CAAsD,CACjF,MAAM,MAAA,CAAS,SAAS,EAAA,CAAI,KAAA,CAAQ,MAAM,CAAA,CAC1C,MAAM,QAAU,IAAI,GAAA,CAAI,CAAC,MAAA,CAAQ,QAAA,CAAS,GAAI,KAAK,CAAA,CAAG,SAAS,EAAA,CAAI,KAAA,CAAQ,MAAM,CAAC,CAAC,CAAA,CACnF,MAAM,KAAA,CAAQ,CAAC,GAAG,OAAO,CAAA,CAAE,IAAI,CAAA,EAAK,KAAA,CAAQ,CAAC,CAAA,CAAE,MAAA,CAAO,GAAK,QAAA,CAAS,EAAA,CAAI,CAAC,CAAA,GAAM,KAAA,CAAQ,CAAC,CAAA,CACxF,OAAO,KAAA,CAAM,MAAA,CAAS,CAAE,OAAA,CAAS,KAAK,GAAA,CAAI,GAAG,KAAK,CAAA,CAAG,OAAA,CAAS,KAAM,CAAA,CAAI,CAAE,QAAS,KAAA,CAAQ,MAAA,CAAQ,QAAS,IAAK,CACnH,CAEA,SAAS,WAAA,CAAY,EAAW,CAAA,CAAW,CAAA,CAAW,CAAA,CAAoB,CACxE,GAAI,CAAA,CAAE,KAAM,OAAO,CAAA,CAAE,KAAK,GAAA,CAAI,YAAA,CAAa,IAAI,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,CAAG,CAAA,CAAI,EAAG,CAAC,CAAC,EAAE,SAAA,EAAW,CAAE,CAAA,CACxF,GAAI,EAAE,UAAA,GAAe,MAAA,CAAW,OAAO,CAAA,GAAM,CAAA,CAAE,aAAe,CAAA,CAAE,KAAA,GAAU,QAAa,CAAA,GAAM,CAAA,CAAE,OAC/F,OAAO,IACT,CAYO,SAAS,qBAAA,CAAsB,SAA2B,GAAA,CAA4B,CAC3F,GAAI,CAAC,MAAA,CAAO,aAAA,CAAc,GAAG,CAAA,EAAK,GAAA,CAAM,iBAAmB,GAAA,EAAO,eAAA,CAAiB,CACjF,MAAM,IAAI,WAAW,iEAAiE,CACxF,CACA,IAAI,CAAA,CACJ,GAAI,CAAE,CAAA,CAAI,MAAM,QAAQ,EAAG,OAAS,KAAA,CAAO,CACzC,GAAI,KAAA,YAAiB,aAAA,CAAe,MAAM,IAAI,aAAA,CAAc,2BAA4B,KAAA,CAAM,OAAO,EACrG,MAAM,KACR,CACA,MAAM,KAAA,CAAQ,WAAW,CAAA,CAAE,EAAA,CAAI,GAAG,CAAA,CAClC,MAAM,KAAO,IAAA,CAAK,GAAA,CAAI,IAAI,IAAA,CAAK,KAAK,CAAA,CAAE,gBAAe,CAAG,IAAI,KAAK,KAAK,CAAA,CAAE,aAAY,CAAG,IAAI,KAAK,KAAK,CAAA,CAAE,YAAY,CAAA,CACnH,IAAI,IAAA,CAAO,QAAA,CACX,QAAS,CAAA,CAAI,EAAA,CAAI,GAAK,GAAA,CAAK,CAAA,EAAK,EAAG,CACjC,MAAM,IAAM,IAAI,IAAA,CAAK,KAAO,CAAA,CAAI,MAAM,EACtC,MAAM,CAAA,CAAI,IAAI,cAAA,EAAe,CAAG,EAAI,GAAA,CAAI,WAAA,GAAgB,CAAA,CAAG,CAAA,CAAI,GAAA,CAAI,UAAA,EAAW,CAC9E,GAAI,CAAC,WAAA,CAAY,CAAA,CAAG,EAAG,CAAA,CAAG,CAAC,EAAG,SAC9B,KAAM,CAAE,OAAA,CAAS,OAAQ,EAAI,OAAA,CAAQ,CAAA,CAAE,GAAI,IAAA,CAAK,GAAA,CAAI,EAAG,CAAA,CAAI,CAAA,CAAG,CAAA,CAAG,CAAA,CAAE,IAAA,CAAM,CAAA,CAAE,MAAM,CAAC,CAAA,CAClF,GAAI,OAAA,EAAW,GAAA,CAAK,SACpB,IAAA,CAAO,IAAA,CAAK,IAAI,IAAA,CAAM,OAAO,EAC7B,GAAI,CAAC,QAAS,KAChB,CACA,OAAO,IAAA,CAAO,GAAA,EAAO,kBAAA,CAAqB,IAAA,CAAO,IACnD","file":"index.js","sourcesContent":["/**\n * The one error taxonomy for `@byok-sdk/core`.\n *\n * Two rules the rest of the package is built around:\n *\n * 1. **One class, code-based branching.** Consumers switch on `error.code`, not\n * on class identity — the same idiom `@byok-sdk/keys` uses. A composition that\n * maps core errors onto HTTP does it with a code table, so adding a code is\n * an additive change instead of a new `instanceof` chain everywhere.\n * 2. **Every conflict carries the current snapshot.** A CAS failure that\n * reports only \"conflict\" forces the caller into a second round trip and\n * invites last-write-wins retries. {@link CoreConflictError} therefore\n * carries `current` — the authoritative state the caller lost to — plus the\n * `observedAt` instant it was read at.\n *\n * This module imports nothing. It is the graph sink: `quota.ts` narrows\n * {@link StorageErrorCode} out of this union and maps it to HTTP status, and\n * every port module documents which codes it can raise. That keeps the code\n * list in one place while letting each domain own its own status mapping.\n */\n\n/**\n * Every error code this package can raise.\n *\n * Codes are stable strings. Two groups are additionally **wire-stable** — a\n * composition is expected to surface them verbatim to clients, so renaming one\n * is a breaking change:\n *\n * - `terminal_conflict` (§12.6.4, HTTP 409)\n * - the five `storage_*` codes (§12.7.7, see `quota.ts`)\n */\nexport const CORE_ERROR_CODES = {\n routine_schedule_invalid: 'routine_schedule_invalid',\n retention_input_invalid: 'retention_input_invalid',\n retention_collect_failed: 'retention_collect_failed',\n // identity + content addressing\n tenant_id_invalid: 'tenant_id_invalid',\n content_hash_invalid: 'content_hash_invalid',\n\n // caller-supplied instants (see `time.ts`)\n timestamp_not_canonical: 'timestamp_not_canonical',\n\n // capability declaration (ADR-010)\n capability_declaration_invalid: 'capability_declaration_invalid',\n capability_unavailable: 'capability_unavailable',\n\n // device proof (§12.6.3)\n proof_envelope_invalid: 'proof_envelope_invalid',\n proof_canonicalization_failed: 'proof_canonicalization_failed',\n\n // device assertion (plan device-assertion-broker) — deliberately its own\n // code rather than reusing `proof_envelope_invalid`: the two envelopes are\n // non-interchangeable by design, and one shared \"envelope was bad\" code is\n // exactly how a log stops being able to say which authentication surface was\n // probed.\n assertion_envelope_invalid: 'assertion_envelope_invalid',\n\n // sealed provider provisioning (plan web-sealed-provisioning). Messages\n // never carry plaintext, ciphertext, or key material — only which check\n // failed.\n webcrypto_unavailable: 'webcrypto_unavailable',\n sealed_secret_invalid: 'sealed_secret_invalid',\n sealed_secret_open_failed: 'sealed_secret_open_failed',\n provider_provisioning_request_invalid: 'provider_provisioning_request_invalid',\n\n // mailbox (§12.7.3)\n mailbox_message_not_found: 'mailbox_message_not_found',\n mailbox_cursor_regression: 'mailbox_cursor_regression',\n mailbox_cursor_ahead_of_delivery: 'mailbox_cursor_ahead_of_delivery',\n mailbox_stream_closed: 'mailbox_stream_closed',\n\n // board coordination (§12.3)\n board_item_not_found: 'board_item_not_found',\n board_item_exists: 'board_item_exists',\n board_transition_invalid: 'board_transition_invalid',\n board_status_conflict: 'board_status_conflict',\n board_claim_conflict: 'board_claim_conflict',\n board_not_held: 'board_not_held',\n\n // truth records (§12.3, §12.6.4)\n truth_record_not_found: 'truth_record_not_found',\n terminal_conflict: 'terminal_conflict',\n truth_revision_conflict: 'truth_revision_conflict',\n\n // presence + activity hints (§12.3)\n activity_capacity_invalid: 'activity_capacity_invalid',\n activity_batch_invalid: 'activity_batch_invalid',\n hint_ttl_invalid: 'hint_ttl_invalid',\n hint_rate_limited: 'hint_rate_limited',\n\n // object manifest (§12.7.4, §12.7.8)\n object_key_prefix_invalid: 'object_key_prefix_invalid',\n object_not_found: 'object_not_found',\n object_state_invalid: 'object_state_invalid',\n\n // storage entitlement / usage / reservation (§12.7.6-12.7.7)\n storage_entitlement_missing: 'storage_entitlement_missing',\n storage_entitlement_version_conflict: 'storage_entitlement_version_conflict',\n storage_reservation_not_found: 'storage_reservation_not_found',\n storage_object_too_large: 'storage_object_too_large',\n storage_quota_exceeded: 'storage_quota_exceeded',\n storage_reservation_expired: 'storage_reservation_expired',\n storage_integrity_mismatch: 'storage_integrity_mismatch',\n storage_write_suspended: 'storage_write_suspended',\n\n // skill packs (plan `skill-pack-delivery-channel`)\n skill_pack_manifest_invalid: 'skill_pack_manifest_invalid',\n skill_pack_frontmatter_invalid: 'skill_pack_frontmatter_invalid',\n} as const;\n\nexport type CoreErrorCode = (typeof CORE_ERROR_CODES)[keyof typeof CORE_ERROR_CODES];\n\n/** Base error for every failure this package raises. */\nexport class ByokCoreError extends Error {\n public readonly code: CoreErrorCode;\n\n constructor(code: CoreErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'ByokCoreError';\n this.code = code;\n }\n}\n\n/**\n * A compare-and-set failure.\n *\n * `current` is the authoritative state at the moment the write was rejected —\n * the board item whose status moved, the terminal record already committed, the\n * entitlement row at a newer version. The caller re-decides against it; the\n * store never merges (§12.3: \"不做 silent last-write-wins\", §12.6.4: 不覆写第一份事实).\n */\nexport class CoreConflictError<TCurrent> extends ByokCoreError {\n public readonly current: TCurrent;\n public readonly observedAt: string;\n\n constructor(\n code: CoreErrorCode,\n message: string,\n current: TCurrent,\n observedAt: string,\n options?: ErrorOptions,\n ) {\n super(code, message, options);\n this.name = 'CoreConflictError';\n this.current = current;\n this.observedAt = observedAt;\n }\n}\n\n/** Narrows an unknown thrown value to a core error, optionally to one code. */\nexport function isCoreError(value: unknown, code?: CoreErrorCode): value is ByokCoreError {\n if (!(value instanceof ByokCoreError)) return false;\n return code === undefined || value.code === code;\n}\n\n/** Narrows an unknown thrown value to a conflict error carrying a snapshot. */\nexport function isCoreConflictError<TCurrent>(\n value: unknown,\n code?: CoreErrorCode,\n): value is CoreConflictError<TCurrent> {\n if (!(value instanceof CoreConflictError)) return false;\n return code === undefined || value.code === code;\n}\n","/**\n * Tenant identity — layer 1 of the six-layer isolation model\n * (`docs/architecture/sdk-architecture.md` §12.6.2).\n *\n * `TenantId` is a branded string and this module is the **only** place that may\n * produce one: every other module receives a `TenantId` it cannot forge without\n * calling {@link tenantId}. The brand carries no runtime value — it exists so a\n * bare `string` (a path segment, a claim from an unverified proof, a\n * device-supplied query parameter) can never silently slide into a store port's\n * first parameter.\n *\n * `src/__tests__/constraints.test.ts` greps the package for `as TenantId`: this\n * file and test fixtures are the only allowed sites. A module that needs a\n * `TenantId` takes one as a parameter or mints it here.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * A validated tenant identifier.\n *\n * Nominal by construction: structurally a `string`, but the phantom brand makes\n * it unassignable from an arbitrary string. Assignment the other way\n * (`TenantId` → `string`) stays legal on purpose, so composition code can pass\n * it as a SQL parameter or key prefix without a cast.\n */\nexport type TenantId = string & { readonly __byokTenantId: unique symbol };\n\n/**\n * Upper bound on tenant id length. Not a security boundary — a bound so a\n * pathological id cannot become an unbounded key prefix inside a store.\n */\nexport const TENANT_ID_MAX_LENGTH = 200;\n\n/**\n * Separator for flat composite keys. `NUL` cannot appear in a tenant id that a\n * control plane can express in a URL, a header, or a SQL identifier, and\n * {@link tenantId} rejects it outright — so a composite key is never ambiguous\n * between `(a, bc)` and `(ab, c)`.\n */\nexport const TENANT_KEY_SEPARATOR = '\\u0000';\n\n/**\n * The single mint point for {@link TenantId}.\n *\n * Fail-closed: empty, whitespace-padded, over-long, non-string, or\n * `NUL`-bearing values are rejected rather than normalized. Normalizing here\n * would create a second source of truth for \"which tenant is this\", because the\n * control plane that issued the id would then disagree with the SDK about its\n * canonical form.\n *\n * @throws {ByokCoreError} code `tenant_id_invalid`.\n */\nexport function tenantId(value: string): TenantId {\n const candidate: unknown = value;\n if (typeof candidate !== 'string') {\n throw new ByokCoreError(\n 'tenant_id_invalid',\n `Tenant id must be a string, received ${typeof candidate}.`,\n );\n }\n if (candidate.length === 0) {\n throw new ByokCoreError('tenant_id_invalid', 'Tenant id must not be empty.');\n }\n if (candidate.trim() !== candidate) {\n throw new ByokCoreError(\n 'tenant_id_invalid',\n 'Tenant id must not have leading or trailing whitespace.',\n );\n }\n if (candidate.length > TENANT_ID_MAX_LENGTH) {\n throw new ByokCoreError(\n 'tenant_id_invalid',\n `Tenant id must be at most ${TENANT_ID_MAX_LENGTH} characters.`,\n );\n }\n if (candidate.includes(TENANT_KEY_SEPARATOR)) {\n throw new ByokCoreError('tenant_id_invalid', 'Tenant id must not contain a NUL character.');\n }\n return candidate as TenantId;\n}\n\n/**\n * Non-throwing form of {@link tenantId}, for surfaces that must answer \"is this\n * a tenant id?\" without building an error (route matching, log redaction).\n * Accepts exactly what {@link tenantId} accepts, never more.\n */\nexport function isTenantId(value: unknown): value is TenantId {\n if (typeof value !== 'string') return false;\n return (\n value.length > 0 &&\n value.trim() === value &&\n value.length <= TENANT_ID_MAX_LENGTH &&\n !value.includes(TENANT_KEY_SEPARATOR)\n );\n}\n\n/**\n * Composite key helper for compositions that need a flat key space (in-memory\n * maps, KV namespaces). SQL compositions use a tenant-prefixed composite\n * primary key instead — §12.6.2 layer 3 forbids a bare device/task index\n * regardless of which representation a composition picks.\n */\nexport function tenantKey(tenant: TenantId, ...parts: readonly string[]): string {\n return [tenant as string, ...parts].join(TENANT_KEY_SEPARATOR);\n}\n","/**\n * Authenticated principals — layer 2 of the isolation model (§12.6.2).\n *\n * A handler never receives a raw tenant string; it receives a principal that\n * already carries a minted {@link TenantId}. The two principal shapes are\n * deliberately not one type with an optional `deviceId`: a control-plane caller\n * that can write entitlements and a device that can write truth records have\n * different authority, and a discriminated union makes a handler state which\n * one it accepts.\n *\n * `keyId`/`keyEpoch` are **not** here. They are device-proof semantics\n * (`plans/sprints/…sprint.md` §S6.2): the signing key's identity and rotation\n * generation, resolved by looking up the device row during proof verification.\n * Putting them on the principal would create permanently-empty fields on every\n * principal minted by a non-proof path.\n */\nimport type { TenantId } from './tenant';\n\n/** Principal kinds. A composition may not invent a third without a contract change. */\nexport const PRINCIPAL_KINDS = ['device', 'control-plane'] as const;\nexport type PrincipalKind = (typeof PRINCIPAL_KINDS)[number];\n\n/**\n * A paired device acting inside one tenant/product.\n *\n * Built only from a device row loaded with the tenant as part of the lookup key\n * (§12.6.2 layer 5) — never from claims a device asserted about itself.\n */\nexport interface DevicePrincipal {\n readonly kind: 'device';\n readonly tenantId: TenantId;\n readonly productId: string;\n readonly deviceId: string;\n}\n\n/**\n * The host's control plane acting on a tenant: entitlement writes, retention\n * policy, administrative reads. Carries the operator identity for audit, which\n * is opaque to the SDK.\n */\nexport interface ControlPlanePrincipal {\n readonly kind: 'control-plane';\n readonly tenantId: TenantId;\n readonly operatorId: string;\n}\n\n/** Anything that can address a tenant-scoped store. */\nexport type Principal = DevicePrincipal | ControlPlanePrincipal;\n\nexport function isDevicePrincipal(principal: Principal): principal is DevicePrincipal {\n return principal.kind === 'device';\n}\n\nexport function isControlPlanePrincipal(\n principal: Principal,\n): principal is ControlPlanePrincipal {\n return principal.kind === 'control-plane';\n}\n\n/**\n * The tenant every store call must be scoped to.\n *\n * Exists so a handler cannot accidentally read `principal.tenantId` off one\n * principal and pass a different tenant to a store: the facade that binds\n * stores to a tenant takes this, not a loose string.\n */\nexport function principalTenant(principal: Principal): TenantId {\n return principal.tenantId;\n}\n","/**\n * The one timestamp format this package accepts across every composition.\n *\n * Every instant that crosses a store port is an ISO-8601 UTC string, and the\n * in-memory reference compares those strings with `<` / `>=` — a downgrade\n * grace deadline, a retention cutoff, a reservation expiry. Lexicographic\n * order equals chronological order **only** for the canonical\n * `YYYY-MM-DDTHH:mm:ss.sssZ` shape that `Date.prototype.toISOString` emits.\n * Feed the same store `2026-08-08T00:00:00+08:00` and the string comparison\n * silently answers a different question than a SQL `timestamptz` comparison\n * would, so the in-memory and Postgres compositions would diverge on an input\n * the conformance suite never sees.\n *\n * The fix is a format contract rather than a normalizer: a caller-supplied\n * timestamp that is not already canonical is **rejected**, not rewritten.\n * Rewriting would make this module a second authority on what instant the\n * caller meant, and an offset-bearing or second-precision string is exactly the\n * case where that guess is worth refusing.\n *\n * Store-produced timestamps are canonical by construction (they come from\n * `Clock.now().toISOString()`); this module guards the *inbound* direction —\n * `downgradeGraceUntil`, `deletePendingBefore`, `ackedBefore`,\n * `expireUnackedBefore`, `reapDeadLettersBefore`.\n *\n * No `node:` import and no clock read: validation is pure, so a Workers\n * composition and the constraint test (`Date.now()` is banned package-wide)\n * both stay happy. `Date.parse` is used for *calendar validity only* — the\n * pattern is what pins the shape.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * Exactly what `toISOString()` produces: four-digit year, `T` separator,\n * millisecond precision, literal `Z`. No offsets, no omitted milliseconds, no\n * expanded-year form — each of those breaks the lexicographic-order property.\n */\nexport const CANONICAL_TIMESTAMP_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\n/**\n * True when `value` is a canonical ISO-8601 UTC instant.\n *\n * Two checks, in order: the pattern pins the *shape*, then a round trip\n * through `Date` pins *calendar validity* — `2026-02-30T00:00:00.000Z` matches\n * the pattern and is not an instant.\n */\nexport function isCanonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n if (!CANONICAL_TIMESTAMP_PATTERN.test(value)) return false;\n const parsed = Date.parse(value);\n if (!Number.isFinite(parsed)) return false;\n return new Date(parsed).toISOString() === value;\n}\n\n/**\n * Fail-closed gate for a caller-supplied instant.\n *\n * @param value The timestamp as received from the caller.\n * @param field Field name, so the failure names the contract that was missed\n * rather than just the bad string.\n * @returns The same string, so call sites can validate and assign in one step.\n * @throws {ByokCoreError} code `timestamp_not_canonical`.\n */\nexport function assertCanonicalTimestamp(value: string, field: string): string {\n if (!isCanonicalTimestamp(value)) {\n throw new ByokCoreError(\n 'timestamp_not_canonical',\n `${field} must be a canonical ISO-8601 UTC instant (YYYY-MM-DDTHH:mm:ss.sssZ), received ${JSON.stringify(value)}.`,\n );\n }\n return value;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Hosted mailbox contract (§12.7.3).\n *\n * The load-bearing rule of this file: **reading is not acknowledging.**\n * `readAfter` never mutates the cursor. The only ack is the cursor the daemon\n * brings back on its next poll, after it has durably appended the envelope to\n * its local journal. \"领走即弃\" means *cursor-advanced-then-deleted*, not\n * *read-then-deleted* — read-deletes would break the frozen at-least-once\n * semantics the client's stall recovery is built on (§8.3).\n *\n * The mailbox transports opaque envelope bytes and is **not** an\n * execution-state authority. `body` is a string here rather than a parsed\n * message because core is protocol-free: the frozen v1 shape lives in\n * `@byok-sdk/protocol`, and core must not grow an edge to it (§12.1 invariant).\n */\nimport type { ContentHash } from './blob';\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\n/**\n * Row lifecycle. `pending` and `acked` are derived from the device cursor;\n * `expired` is the dead-letter state for rows that aged out before ever being\n * acked — §12.7.5 requires those to be visible, not silently dropped.\n */\nexport const MAILBOX_MESSAGE_STATES = ['pending', 'acked', 'expired'] as const;\nexport type MailboxMessageState = (typeof MAILBOX_MESSAGE_STATES)[number];\n\n/** One mailbox row. `seq` is monotonic per (tenant, device) — never global. */\nexport interface MailboxMessage {\n readonly tenantId: TenantId;\n readonly deviceId: string;\n readonly seq: number;\n readonly messageId: string;\n /** Opaque encoded envelope. Core never parses it. */\n readonly body: string;\n readonly bodyHash: ContentHash;\n readonly byteSize: bigint;\n readonly state: MailboxMessageState;\n readonly appendedAt: string;\n}\n\n/** Opaque bytes produced after the mailbox has atomically reserved their delivery sequence. */\nexport interface MailboxBody {\n readonly body: string;\n readonly bodyHash: ContentHash;\n readonly byteSize: bigint;\n}\n\n/**\n * How an append is admitted against the tenant's `mailboxLimitBytes`.\n *\n * Mailbox bytes have one authority: the retained rows. Usage is the tenant's\n * `SUM(byteSize)` over its `pending` rows, and the limit is checked in the same\n * serialized unit that inserts the row — there is no counter for a writer to\n * forget, so acking, dead-lettering or deleting a row needs no accounting.\n * `acked` and `expired` rows stay retained for retention and §12.7.5\n * visibility but hold no quota, so undelivered-and-lost work can never wedge\n * a tenant at its limit.\n *\n * - `limited`: refused with `storage_quota_exceeded` when `used + byteSize`\n * exceeds the limit, and with `storage_entitlement_missing` when the tenant\n * has no entitlement. A refused append consumes no `seq`.\n * - `cancellation`: always admitted and still counted. Reserved for the one\n * cancellation row a task can own, so a full mailbox never blocks\n * `cancelTask`.\n */\nexport type MailboxAdmission = 'limited' | 'cancellation';\n\nexport interface MailboxAppendInput {\n readonly deviceId: string;\n /**\n * Producer-supplied idempotency key. A second append with the same\n * `messageId` returns the existing row instead of enqueuing a duplicate.\n */\n readonly messageId: string;\n /**\n * Builds the opaque body around the sequence reserved by this append.\n *\n * The store invokes this only for a new row and commits the returned bytes\n * at exactly that `seq`. Allocation, materialization, and insertion are one\n * per-device serialized operation; otherwise concurrent offers could commit\n * out of order and let an ack skip a late lower sequence.\n */\n readonly materialize: (seq: number) => MailboxBody | Promise<MailboxBody>;\n /**\n * Limit admission for a NEW row. An existing `messageId` returns its row\n * before any capacity check, so a retry is never refused for capacity. A\n * closed stream refuses before even that (see {@link MailboxStore.closeStream}).\n */\n readonly admission: MailboxAdmission;\n}\n\n/** Tenant mailbox usage, derived from the retained rows on every read. */\nexport interface MailboxUsage {\n /** `SUM(byteSize)` over the retained `pending` rows. */\n readonly bytes: bigint;\n}\n\nexport interface MailboxReadQuery {\n readonly deviceId: string;\n /** Exclusive lower bound. `0` reads from the beginning of the retained window. */\n readonly afterSeq: number;\n readonly limit?: number;\n}\n\nexport interface MailboxPage {\n readonly messages: readonly MailboxMessage[];\n /**\n * The seq to poll after next. Equal to `afterSeq` when the page is empty —\n * reading never moves the ack cursor, so a caller that only reads can replay\n * the same page forever without losing anything.\n */\n readonly nextSeq: number;\n readonly hasMore: boolean;\n /**\n * The earliest seq a reader can still recover from: one past the highest row\n * this device LOST. A caller at `recoverableFrom - 1` can still be handed\n * the first row it has any claim to; a caller below that has a gap it cannot\n * see, and resuming it would hand back a partial tail indistinguishable from\n * a complete one.\n *\n * Lost means `expired` — a row that aged out before anyone acked it. An\n * `acked` row is consumed, not lost, so acking never moves this and never\n * turns a re-poll from an old cursor into a failure; that distinction is the\n * whole point of the field.\n *\n * `1` for a mailbox that has lost nothing, so a fresh device's cursor `0` is\n * always inside the window. Monotonic: `collectExpired` reaps old dead\n * letters but always keeps each device's highest-seq one, which is the\n * evidence this floor is read from.\n *\n * This is a READ of the retained window, never a second retention authority:\n * `collectExpired` decides what is retained, this reports what it cost.\n */\n readonly recoverableFrom: number;\n}\n\nexport interface MailboxAdvanceCursorInput {\n readonly deviceId: string;\n /** Highest seq the device has durably journaled. */\n readonly ackedSeq: number;\n}\n\n/** Server-owned proof that a cursor was returned to this device. */\nexport interface MailboxRecordDeliveryInput {\n readonly deviceId: string;\n /** Highest cursor the server has returned to this device. */\n readonly deliveredSeq: number;\n}\n\n/** The device's durable delivery and acknowledgement positions. */\nexport interface MailboxCursorState {\n readonly tenantId: TenantId;\n readonly deviceId: string;\n /** Highest cursor the server has returned to this device. */\n readonly deliveredSeq: number;\n readonly ackedSeq: number;\n readonly updatedAt: string;\n}\n\n/**\n * Retention cutoffs.\n *\n * All three instants must be **canonical ISO-8601 UTC** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`. A retention sweep\n * deletes rows, so an offset-bearing string that a string comparison and a SQL\n * `timestamptz` comparison read differently is the worst place to guess — see\n * `time.ts`.\n */\nexport interface MailboxCollectExpiredInput extends CollectExpiredInput {\n /** Acked rows appended before this instant are deleted. */\n readonly ackedBefore: string;\n /** Unacked rows appended before this instant move to `expired`. */\n readonly expireUnackedBefore: string;\n /**\n * Dead letters (`expired` rows) appended before this instant are deleted,\n * except each device's highest-seq dead letter: that row is the evidence for\n * `recoverableFrom`, so a reap never moves the floor. Only rows that were\n * already `expired` when the call started are eligible; a row this call\n * expires waits for the next call. Reaped rows count in `removed`.\n */\n readonly reapDeadLettersBefore: string;\n}\n\n/**\n * Which of one device's `pending` rows {@link MailboxStore.expirePending}\n * dead-letters. A listed seq that is not `pending` (acked, already expired, or\n * never written) is skipped.\n */\nexport interface MailboxExpirePendingInput {\n readonly deviceId: string;\n readonly seqs: readonly number[];\n}\n\n/** Why a device's stream was closed: the device it addressed was retired. */\nexport const MAILBOX_STREAM_CLOSE_CAUSES = ['device_revoked', 'device_superseded'] as const;\nexport type MailboxStreamCloseCause = (typeof MAILBOX_STREAM_CLOSE_CAUSES)[number];\n\n/** An append refused because its device's stream was closed when the device was retired. */\nexport class MailboxStreamClosedError extends ByokCoreError {\n public readonly deviceId: string;\n public readonly closeCause: MailboxStreamCloseCause;\n\n constructor(deviceId: string, closeCause: MailboxStreamCloseCause, options?: ErrorOptions) {\n super('mailbox_stream_closed', `The mailbox stream of device ${deviceId} is closed (${closeCause}).`, options);\n this.name = 'MailboxStreamClosedError';\n this.deviceId = deviceId;\n this.closeCause = closeCause;\n }\n}\n\nexport interface MailboxCloseStreamInput {\n readonly deviceId: string;\n readonly cause: MailboxStreamCloseCause;\n}\n\nexport interface MailboxReopenStreamInput {\n readonly deviceId: string;\n}\n\n/**\n * Mailbox port. Tenant-first, async.\n *\n * Raises: `mailbox_cursor_regression` (an ack that moves the cursor backwards,\n * which would silently re-deliver already-journaled work),\n * `mailbox_cursor_ahead_of_delivery` (an ack beyond the highest cursor the\n * server has returned to that device),\n * `timestamp_not_canonical` (a retention cutoff that is not a canonical\n * ISO-8601 UTC instant), `storage_quota_exceeded` and\n * `storage_entitlement_missing` (a `limited` append refused at admission), and\n * `mailbox_stream_closed` ({@link MailboxStreamClosedError}, any append to a\n * closed stream).\n */\nexport interface MailboxStore {\n append(tenant: TenantId, input: MailboxAppendInput): Promise<MailboxMessage>;\n /** The tenant's mailbox bytes, summed from the retained `pending` rows. */\n readUsage(tenant: TenantId): Promise<MailboxUsage>;\n /** Pure read. Never advances the cursor, never deletes, never marks acked. */\n readAfter(tenant: TenantId, query: MailboxReadQuery): Promise<MailboxPage>;\n /** Records the highest cursor a device-facing response is about to return. */\n recordDelivery(\n tenant: TenantId,\n input: MailboxRecordDeliveryInput,\n ): Promise<MailboxCursorState>;\n /** The one and only ack. Monotonic and bounded by the recorded delivery watermark. */\n advanceCursor(\n tenant: TenantId,\n input: MailboxAdvanceCursorInput,\n ): Promise<MailboxCursorState>;\n readCursor(tenant: TenantId, deviceId: string): Promise<MailboxCursorState>;\n /** Retention hook: delete acked rows, reap old dead letters below the floor, dead-letter unacked ones. */\n collectExpired(\n tenant: TenantId,\n input: MailboxCollectExpiredInput,\n ): Promise<CollectExpiredResult>;\n /**\n * Dead-letters the listed undelivered rows of a task the Host abandoned,\n * without waiting for retention. Only `pending` rows move, and only to\n * `expired`: nothing is deleted, no row returns to `pending`, the cursor is\n * untouched, and the device's `seq` allocator keeps counting. The moved rows\n * stop holding mailbox quota and raise `recoverableFrom` exactly as a\n * retention sweep would. Serialized with the device's appends and acks.\n */\n expirePending(tenant: TenantId, input: MailboxExpirePendingInput): Promise<{ readonly expired: number }>;\n /**\n * Closes a retired device's stream and dead-letters every `pending` row on\n * it, as one step serialized with the device's appends: an append ordered\n * before it has its row expired here, and every append ordered after it is\n * refused with `mailbox_stream_closed`, whatever its admission and even for\n * a known `messageId`. The stream need not exist yet; closing creates it\n * closed. Closing a closed stream keeps its first close instant, records the\n * new cause and still expires pending rows. Cursor, `seq` and\n * `recoverableFrom` move exactly as {@link expirePending} moves them.\n */\n closeStream(tenant: TenantId, input: MailboxCloseStreamInput): Promise<{ readonly expired: number }>;\n /**\n * Reopens a stream for a device registered again under the same id. Rows,\n * cursor, `seq` and `recoverableFrom` are untouched, so delivery stays\n * monotonic across the close. A no-op on an open or absent stream.\n */\n reopenStream(tenant: TenantId, input: MailboxReopenStreamInput): Promise<void>;\n}\n","/**\n * Board coordination state (§12.3).\n *\n * This is the *human and multi-device* collaboration lifecycle, and it is a\n * separate vocabulary from the frozen wire execution vocabulary on purpose. One\n * run attempt is not one work item: an item can outlive several attempts, and a\n * finished attempt does not mean a human accepted the result. The constraint\n * test asserts that no wire execution state name appears in this file — if the\n * two vocabularies ever merge, status sniffing comes back and the board becomes\n * a second, unreliable execution authority.\n *\n * Three invariants the ports below encode:\n *\n * - **assignee and status are two fields**, not one enum. \"Who holds it\" and\n * \"where it is\" change independently.\n * - **every mutation is a CAS.** `claim` compares against \"unheld\"; every status\n * move carries `expectedStatus`. There is no last-write-wins path.\n * - **conflicts return the snapshot they lost to**, so the caller re-decides\n * against real state instead of retrying blind.\n */\nimport type { TenantId } from './tenant';\n\n/** The five board statuses. `closed` means \"terminated, unaccepted\" (§12.3). */\nexport const BOARD_STATUSES = ['todo', 'in_progress', 'in_review', 'done', 'closed'] as const;\nexport type BoardStatus = (typeof BOARD_STATUSES)[number];\n\n/**\n * Legal transitions, transcribed from the §12.3 state diagram.\n *\n * `in_review → done` is the human acceptance step: a device reporting a\n * terminal record can push an item to `in_review`, never straight to `done`.\n * `done` and `closed` are sinks — if archival semantics are ever needed, §12.3\n * pins the answer to an `archivedAt` field, not a sixth status.\n */\nexport const BOARD_TRANSITIONS: Readonly<Record<BoardStatus, readonly BoardStatus[]>> = {\n todo: ['in_progress', 'closed'],\n in_progress: ['todo', 'in_review', 'closed'],\n in_review: ['in_progress', 'done', 'closed'],\n done: [],\n closed: [],\n};\n\nexport function isLegalBoardTransition(from: BoardStatus, to: BoardStatus): boolean {\n return BOARD_TRANSITIONS[from].includes(to);\n}\n\n/** Who currently holds the item. Separate from {@link BoardItem.status}. */\nexport interface BoardAssignee {\n readonly holderId: string;\n readonly heldSince: string;\n}\n\n/**\n * One work item.\n *\n * `boardSeq` is monotonic **per tenant** and bumps on every mutation, which is\n * what makes incremental list polling possible without a cross-tenant sequence\n * (a global sequence would leak other tenants' write rate).\n */\nexport interface BoardItem {\n readonly tenantId: TenantId;\n readonly itemId: string;\n readonly channel: string;\n readonly title: string;\n readonly status: BoardStatus;\n readonly assignee?: BoardAssignee;\n readonly boardSeq: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport interface BoardItemInput {\n readonly itemId: string;\n readonly channel: string;\n readonly title: string;\n /** Defaults to `todo`. Creating directly into a sink status is legal but explicit. */\n readonly status?: BoardStatus;\n}\n\nexport interface BoardListQuery {\n /** Exclusive lower bound on `boardSeq`, for incremental polling. */\n readonly afterSeq?: number;\n readonly channel?: string;\n readonly status?: BoardStatus;\n readonly limit?: number;\n}\n\nexport interface BoardPage {\n readonly items: readonly BoardItem[];\n /** Highest `boardSeq` in this page, or the requested `afterSeq` when empty. */\n readonly nextSeq: number;\n readonly hasMore: boolean;\n}\n\nexport interface BoardClaimInput {\n readonly itemId: string;\n readonly holderId: string;\n /**\n * Status the claimer believes the item is in. Defaults to `todo`; supplying\n * it explicitly makes the claim a full CAS rather than an assignee-only one.\n *\n * The CAS holds on the idempotent path too: a re-claim by the current holder\n * that supplies a stale `expectedStatus` fails with `board_status_conflict`\n * and the current item. The default is *not* applied there — a retry of a\n * successful claim legitimately observes `in_progress`.\n */\n readonly expectedStatus?: BoardStatus;\n}\n\nexport interface BoardUnclaimInput {\n readonly itemId: string;\n /** Must match the current holder — releasing someone else's item is not a legal move. */\n readonly holderId: string;\n}\n\nexport interface BoardStatusUpdateInput {\n readonly itemId: string;\n readonly expectedStatus: BoardStatus;\n readonly status: BoardStatus;\n /** Optional holder assertion, for transitions only the holder may make. */\n readonly holderId?: string;\n}\n\n/**\n * Board port. Tenant-first, async.\n *\n * Raises: `board_item_not_found`, `board_claim_conflict` (loser gets the\n * winner's holder snapshot), `board_status_conflict` (`expectedStatus` missed —\n * carries the current item), `board_transition_invalid` (move not in\n * {@link BOARD_TRANSITIONS} — also carries the current item), `board_not_held`.\n */\nexport interface BoardStore {\n create(tenant: TenantId, input: BoardItemInput): Promise<BoardItem>;\n get(tenant: TenantId, itemId: string): Promise<BoardItem | undefined>;\n list(tenant: TenantId, query: BoardListQuery): Promise<BoardPage>;\n /** CAS on \"unheld\". Exactly one concurrent caller wins; losers get the holder snapshot. */\n claim(tenant: TenantId, input: BoardClaimInput): Promise<BoardItem>;\n unclaim(tenant: TenantId, input: BoardUnclaimInput): Promise<BoardItem>;\n updateStatus(tenant: TenantId, input: BoardStatusUpdateInput): Promise<BoardItem>;\n /** Removes the item; an absent item is not an error. The Host archive step (#1120) is the caller. */\n remove(tenant: TenantId, itemId: string): Promise<void>;\n}\n","/**\n * Truth records: attested metadata with two different write models (§12.3, §12.6.4).\n *\n * | kind | write model | conflict model |\n * | --------------- | ------------------------------ | --------------------------------------- |\n * | `task.terminal` | first write per task, immutable | different hash → `terminal_conflict` |\n * | `profile` | per-key snapshot | `expectedRev` CAS |\n * | `memory` | per-key snapshot | `expectedRev` CAS |\n *\n * The store is deliberately dumb about content. It can match, sort, and return\n * by tenant/kind/key/rev/hash, and that is the whole of its authority: no\n * summarizing, no merging, no relevance ranking (§12.3). Merge decisions belong\n * to the device that holds the context, which is why a conflict hands back the\n * current snapshot and stops.\n *\n * The manifest listing returns metadata only — never bodies. Selecting which\n * bodies to fetch is a local decision (§S6.4), so shipping bodies in the list\n * response would both defeat that and make the response unbounded.\n */\nimport type { ContentHash } from './blob';\nimport type { TenantId } from './tenant';\n\nexport const TRUTH_RECORD_KINDS = ['task.terminal', 'profile', 'memory'] as const;\nexport type TruthRecordKind = (typeof TRUTH_RECORD_KINDS)[number];\n\n/**\n * Where the record body lives. Small payloads may be inline and still count\n * against tenant usage (§12.7.6); larger ones are an object reference.\n */\nexport type TruthBodyRef =\n | { readonly kind: 'inline'; readonly body: string }\n | { readonly kind: 'object'; readonly hash: ContentHash };\n\nexport interface TruthRecord {\n readonly tenantId: TenantId;\n readonly kind: TruthRecordKind;\n /** For `task.terminal` this is the task id; for snapshots, the host's key. */\n readonly recordKey: string;\n /** `1` for the first write. Terminal records never advance past `1`. */\n readonly rev: number;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly body: TruthBodyRef;\n readonly label?: string;\n /** Idempotency key of the accepted write, for replay detection. */\n readonly requestId?: string;\n readonly writtenAt: string;\n}\n\n/** Manifest projection: everything needed to decide *whether* to fetch a body. */\nexport interface TruthManifestEntry {\n readonly kind: TruthRecordKind;\n readonly recordKey: string;\n readonly rev: number;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly label?: string;\n readonly updatedAt: string;\n}\n\nexport interface TerminalWriteInput {\n readonly taskId: string;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly body: TruthBodyRef;\n readonly label?: string;\n readonly requestId?: string;\n}\n\nexport interface SnapshotWriteInput {\n readonly kind: 'profile' | 'memory';\n readonly recordKey: string;\n /** `0` asserts \"no record yet\". Any other value must equal the stored `rev`. */\n readonly expectedRev: number;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly body: TruthBodyRef;\n readonly label?: string;\n readonly requestId?: string;\n}\n\nexport interface TruthRecordSelector {\n readonly kind: TruthRecordKind;\n readonly recordKey: string;\n}\n\nexport interface TruthManifestQuery {\n readonly kind?: TruthRecordKind;\n readonly keyPrefix?: string;\n readonly limit?: number;\n}\n\n/**\n * Truth port. Tenant-first, async.\n *\n * Raises: `terminal_conflict` (same task, different hash — carries the record\n * already committed), `truth_revision_conflict` (`expectedRev` missed — carries\n * the current record), `truth_record_not_found`.\n */\nexport interface TruthStore {\n /**\n * Writes the first terminal record for a task.\n *\n * Replaying the identical hash returns the original record unchanged, so a\n * retry after a lost response is safe. A different hash for the same task is\n * a conflict: the first fact is never overwritten.\n */\n writeTerminal(tenant: TenantId, input: TerminalWriteInput): Promise<TruthRecord>;\n /** Per-key snapshot write under `expectedRev` CAS. The store never merges bodies. */\n writeSnapshot(tenant: TenantId, input: SnapshotWriteInput): Promise<TruthRecord>;\n getRecord(tenant: TenantId, selector: TruthRecordSelector): Promise<TruthRecord | undefined>;\n /** Metadata only — key/rev/hash/size/label, no bodies. */\n listManifest(\n tenant: TenantId,\n query: TruthManifestQuery,\n ): Promise<readonly TruthManifestEntry[]>;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Presence hints (§12.3).\n *\n * Presence is lossy, TTL-bounded, unsigned, and never authoritative. Expiry means\n * *absence*, not a stale value: a hint past its TTL is invisible to readers, so\n * nothing downstream can mistake an old level for a live one.\n *\n * These hints must never be used to derive coordination state, execution state,\n * authorization, billing, or recovery — which is why this module shares no\n * vocabulary with `board.ts` and no vocabulary with the frozen wire states. The\n * constraint test enforces that separation by scanning this file for those\n * names. A device that looks busy is not evidence that any particular work item\n * moved anywhere.\n *\n */\nimport type { TenantId } from './tenant';\n\n/** The five presence levels. */\nexport const PRESENCE_LEVELS = ['online', 'thinking', 'working', 'error', 'offline'] as const;\nexport type PresenceLevel = (typeof PRESENCE_LEVELS)[number];\n\n/**\n * The capability matrix a daemon reported for one runtime: the shape of\n * `@byok-sdk/protocol`'s `RuntimeCapabilities` (#1103). Omitted fields are unknown.\n */\nexport interface PresenceRuntimeCapabilities {\n readonly steer?: boolean;\n readonly resume?: boolean;\n readonly approvalInteractive?: boolean;\n readonly mcpToolsets?: boolean;\n readonly messageDraft?: boolean;\n readonly toolAuthorizationAuto?: boolean;\n readonly durablePi?: boolean;\n readonly preparedLane?: boolean;\n readonly isolation?: {\n readonly userContext?: boolean;\n readonly userMcpServers?: boolean;\n readonly sessionPersistence?: boolean;\n };\n}\n\n/** Runtime facts observed by a daemon's real local probe. Omitted fields are unknown. */\nexport interface PresenceRuntimeFact {\n readonly id: string;\n readonly version?: string;\n readonly authPresent?: boolean;\n readonly capabilities?: PresenceRuntimeCapabilities;\n}\n\n/** Copies the defined boolean flags named by `keys`; a stored row holds no other keys. */\nfunction definedFlags<T extends object, K extends keyof T>(source: T, keys: readonly K[]): Pick<T, K> {\n const flags: Partial<Pick<T, K>> = {};\n for (const key of keys) if (source[key] !== undefined) flags[key] = source[key];\n return flags as Pick<T, K>;\n}\n\n/** A frozen copy of one runtime fact holding only the known fields; every presence store returns this. */\nexport function freezePresenceRuntimeFact(runtime: PresenceRuntimeFact): PresenceRuntimeFact {\n const capabilities = runtime.capabilities;\n return Object.freeze({\n id: runtime.id,\n ...(runtime.version === undefined ? {} : { version: runtime.version }),\n ...(runtime.authPresent === undefined ? {} : { authPresent: runtime.authPresent }),\n ...(capabilities === undefined ? {} : {\n capabilities: Object.freeze({\n ...definedFlags(capabilities, ['steer', 'resume', 'approvalInteractive', 'mcpToolsets', 'messageDraft', 'toolAuthorizationAuto', 'durablePi', 'preparedLane']),\n ...(capabilities.isolation === undefined ? {} : {\n isolation: Object.freeze(definedFlags(capabilities.isolation, ['userContext', 'userMcpServers', 'sessionPersistence'])),\n }),\n }),\n }),\n });\n}\n\n/** Unexpired presence facts nested in the tenant aggregate. */\nexport interface TenantReadinessPresence {\n readonly level: PresenceLevel;\n readonly detail?: string;\n readonly configuredToolsets?: readonly string[];\n readonly clientVersion?: string;\n readonly protocolVersions?: readonly number[];\n readonly runtimes?: readonly PresenceRuntimeFact[];\n readonly observedAt: string;\n readonly expiresAt: string;\n}\n\n/** Durable device state plus its optional live observation, scoped to one tenant. */\nexport interface TenantReadinessDevice {\n readonly deviceId: string;\n readonly productId: string;\n readonly deviceName: string;\n /** Retained but invariant: revocation deletes the row, so this is never `true`. */\n readonly revoked: boolean;\n /** Omitted when absent/expired or when the durable device is revoked. */\n readonly presence?: TenantReadinessPresence;\n}\n\n/** SDK-owned tenant read model; this is observation, never an execution gate. */\nexport interface TenantReadiness {\n readonly tenantId: TenantId;\n readonly activePairedDeviceCount: number;\n /** Retained but invariant: always 0, since a revoked device leaves no row to count. */\n readonly revokedDeviceCount: number;\n readonly observedPresenceCount: number;\n readonly observedPresenceByLevel: Readonly<Record<PresenceLevel, number>>;\n readonly devices: readonly TenantReadinessDevice[];\n}\n\n/** A device-level hint. `expiresAt` is authoritative: past it, the hint does not exist. */\nexport interface PresenceHint {\n readonly tenantId: TenantId;\n readonly deviceId: string;\n readonly level: PresenceLevel;\n /** Free-form host label, bounded by the composition. Never parsed by core. */\n readonly detail?: string;\n /**\n * Logical MCP toolset IDs this daemon reported as configured. Discovery\n * only: local task acceptance remains the fail-closed authority. Omission\n * means legacy/unknown; an empty array means known-none.\n */\n readonly configuredToolsets?: readonly string[];\n /** The U4a Local Agent release version, when the daemon supplied it. */\n readonly clientVersion?: string;\n /** Protocol versions actually advertised by this daemon. */\n readonly protocolVersions?: readonly number[];\n /** Runtime/auth facts from a real local probe; unknown facts are omitted. */\n readonly runtimes?: readonly PresenceRuntimeFact[];\n readonly observedAt: string;\n readonly expiresAt: string;\n}\n\nexport interface PresenceHintInput {\n readonly deviceId: string;\n readonly level: PresenceLevel;\n readonly detail?: string;\n /** Validated logical IDs only; executable connector definitions never belong here. */\n readonly configuredToolsets?: readonly string[];\n /** The U4a Local Agent release version, when available. */\n readonly clientVersion?: string;\n /** Protocol versions actually advertised by this daemon. */\n readonly protocolVersions?: readonly number[];\n /** Runtime/auth facts from a real local probe; unknown facts are omitted. */\n readonly runtimes?: readonly PresenceRuntimeFact[];\n /** Hint lifetime. §12.7.5 suggests 60-120s for presence. */\n readonly ttlMs: number;\n /** Minimum time between accepted publications for this device. `0` explicitly disables throttling. */\n readonly minimumIntervalMs: number;\n}\n\n/**\n * Presence port. Tenant-first, async.\n *\n * Reads filter expired hints out rather than returning them with a flag: an\n * expired hint is indistinguishable from one that was never written.\n */\nexport interface PresenceStore {\n collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult>;\n publish(tenant: TenantId, input: PresenceHintInput): Promise<PresenceHint>;\n read(tenant: TenantId, deviceId: string): Promise<PresenceHint | undefined>;\n list(tenant: TenantId): Promise<readonly PresenceHint[]>;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Content addressing and the object manifest (§12.7.4, §12.7.8).\n *\n * This module is **metadata only**. No byte transport, no presigning, no\n * hashing: R2/S3 URL signing and digest computation are composition concerns\n * that need platform crypto, and core stays Node-free. What core owns is the\n * shape everyone must agree on — the hash format, the manifest state machine,\n * and reference counting — so that Postgres, D1, and the in-memory reference\n * cannot disagree about when an object is safe to delete.\n *\n * Object keys are tenant-scoped by construction ({@link tenantObjectKey}).\n * A global `sha256/<hex>` key space would turn object existence into a\n * cross-tenant oracle, which is why §12.7.4 forbids it even though it would\n * deduplicate better.\n */\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\n/** `sha256:<64 lowercase hex>`. The only content-address form core accepts. */\nexport const CONTENT_HASH_PATTERN = /^sha256:[0-9a-f]{64}$/;\n\n/** A validated content address. Branded so an unvalidated digest cannot stand in for one. */\nexport type ContentHash = string & { readonly __byokContentHash: unique symbol };\n\n/**\n * The single mint point for {@link ContentHash}.\n *\n * Fail-closed on uppercase hex: accepting both cases would make the same bytes\n * addressable under two keys, which breaks per-tenant deduplication and the\n * \"count each hash once\" billing rule (§12.7.6).\n *\n * @throws {ByokCoreError} code `content_hash_invalid`.\n */\nexport function contentHash(value: string): ContentHash {\n if (!CONTENT_HASH_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'content_hash_invalid',\n `Content hash must match ${CONTENT_HASH_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ContentHash;\n}\n\n/** Non-throwing form of {@link contentHash}. */\nexport function isContentHash(value: unknown): value is ContentHash {\n return typeof value === 'string' && CONTENT_HASH_PATTERN.test(value);\n}\n\n/**\n * What a deployment-level key namespace may look like: slash-joined segments of\n * lowercase alphanumerics, `.`, `_`, and `-`, each starting with an\n * alphanumeric. No leading or trailing slash, and therefore no empty segment.\n *\n * Narrow on purpose, and narrower than S3 keys allow. A prefix is spliced into\n * every key this SDK ever writes, so the only prefixes worth accepting are the\n * ones that reach the object store spelled exactly as configured: anything\n * requiring percent-encoding would give the deployment's objects two names, and\n * anything with an empty segment would make `a//b` and `a/b` the same key at\n * rest but different strings in config. Case is folded out for the same reason\n * {@link contentHash} refuses uppercase hex — one address, one spelling.\n */\nexport const OBJECT_KEY_PREFIX_PATTERN = /^[a-z0-9][a-z0-9._-]*(\\/[a-z0-9][a-z0-9._-]*)*$/;\n\n/** A validated deployment key namespace. Branded, so only the mint point below can produce one. */\nexport type ObjectKeyPrefix = string & { readonly __byokObjectKeyPrefix: unique symbol };\n\n/**\n * The single mint point for {@link ObjectKeyPrefix}.\n *\n * There is no \"empty means no prefix\" spelling here: a composition that has no\n * prefix omits the option, and one that passes `''` has misconfigured something\n * (an unset environment variable is the usual way). Accepting it silently would\n * make the two indistinguishable at exactly the moment the difference decides\n * where a deployment's objects live.\n *\n * @throws {ByokCoreError} code `object_key_prefix_invalid`.\n */\nexport function objectKeyPrefix(value: string): ObjectKeyPrefix {\n if (!OBJECT_KEY_PREFIX_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'object_key_prefix_invalid',\n `Object key prefix must match ${OBJECT_KEY_PREFIX_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ObjectKeyPrefix;\n}\n\n/**\n * Tenant-scoped object key, e.g.\n * `tenants/<tenantId>/objects/sha256/<hex>` (§12.7.4).\n *\n * `prefix` namespaces the whole layout — `<prefix>/tenants/...` — so one bucket\n * can hold several deployments without either of them owning the bucket root.\n * Omitting it produces the unprefixed key verbatim, which is what makes the\n * option safe to add: every object already at rest was written without one.\n *\n * The prefix is an IMMUTABLE property of a deployment. It is spliced in here\n * and nowhere else, and nothing reads a key back under a second layout: change\n * a live deployment's prefix and its existing objects become unaddressable.\n * See `R2BlobStoreOptions.keyPrefix` in `@byok-sdk/cloud-dataplane` for the full\n * operational contract.\n */\nexport function tenantObjectKey(\n tenant: TenantId,\n hash: ContentHash,\n prefix?: ObjectKeyPrefix,\n): string {\n const hex = hash.slice('sha256:'.length);\n const key = `tenants/${tenant as string}/objects/sha256/${hex}`;\n return prefix === undefined ? key : `${prefix as string}/${key}`;\n}\n\n/**\n * Object manifest lifecycle (§12.7.8).\n *\n * `pending` exists because Postgres and R2 have no shared transaction: the row\n * is written before the bytes land, and only `committed` rows may be referenced\n * by a truth record. `delete_pending` is the tombstone the GC worker drives, so\n * a failed R2 delete is retryable instead of leaving usage silently wrong.\n */\nexport const OBJECT_STATES = ['pending', 'committed', 'delete_pending', 'deleted'] as const;\nexport type ObjectState = (typeof OBJECT_STATES)[number];\n\n/** Legal manifest transitions. Anything else raises `object_state_invalid`. */\nexport const OBJECT_STATE_TRANSITIONS: Readonly<Record<ObjectState, readonly ObjectState[]>> = {\n pending: ['committed', 'delete_pending'],\n committed: ['delete_pending'],\n delete_pending: ['deleted', 'committed'],\n deleted: [],\n};\n\nexport function isLegalObjectTransition(from: ObjectState, to: ObjectState): boolean {\n return OBJECT_STATE_TRANSITIONS[from].includes(to);\n}\n\n/** One row of `object_manifest` (§12.7.6). */\nexport interface ObjectManifestEntry {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n /** Declared at reservation time, re-verified at commit against the store's `HEAD`. */\n readonly byteSize: bigint;\n readonly contentType: string;\n readonly state: ObjectState;\n /** Number of live {@link ObjectReference} rows. `0` makes the object GC-eligible after grace. */\n readonly refCount: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n /** Set when the row entered `delete_pending`; the grace window is measured from here. */\n readonly deletePendingAt?: string;\n}\n\n/** What references an object. `refKind`/`refId` are opaque to core. */\nexport interface ObjectReference {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n readonly createdAt: string;\n}\n\nexport interface ObjectManifestInput {\n readonly hash: ContentHash;\n readonly byteSize: bigint;\n readonly contentType: string;\n}\n\n/**\n * Finalize input. `byteSize`/`contentType` are what the composition actually\n * observed on the object store, not what the client declared — the whole point\n * of the check is that the two can differ (§12.7.7 step 4).\n */\nexport interface ObjectCommitInput {\n readonly hash: ContentHash;\n readonly observedByteSize: bigint;\n readonly observedContentType: string;\n}\n\nexport interface ObjectReferenceInput {\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n}\n\nexport interface ObjectListQuery {\n readonly state?: ObjectState;\n /**\n * Only rows whose `deletePendingAt` is at or before this instant.\n *\n * Must be a **canonical ISO-8601 UTC instant** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`, because the\n * in-memory composition compares it as a string and a SQL composition\n * compares it as a `timestamptz` — see `time.ts`.\n */\n readonly deletePendingBefore?: string;\n readonly limit?: number;\n}\n\n/**\n * Object manifest port. Tenant-first, async, metadata only.\n *\n * Raises: `object_not_found`, `object_state_invalid`,\n * `storage_integrity_mismatch` (commit observed size/type disagreeing with the\n * declared manifest row), `timestamp_not_canonical` (a `list` query whose\n * `deletePendingBefore` is not a canonical ISO-8601 UTC instant).\n */\nexport interface ObjectStore {\n collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult>;\n /** Creates or returns the `pending` row for `hash`. Idempotent per (tenant, hash). */\n putManifest(tenant: TenantId, input: ObjectManifestInput): Promise<ObjectManifestEntry>;\n /** `pending` → `committed` after verifying observed size/type. */\n commit(tenant: TenantId, input: ObjectCommitInput): Promise<ObjectManifestEntry>;\n get(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry | undefined>;\n list(tenant: TenantId, query: ObjectListQuery): Promise<readonly ObjectManifestEntry[]>;\n /** Idempotent per (tenant, hash, refKind, refId) — re-adding does not double-count. */\n addReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n removeReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n /** Tombstone step 1: only legal at `refCount === 0`. */\n markDeletePending(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n /** Tombstone step 3: the object store delete succeeded. */\n markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n}\n\nexport interface ObjectCollectExpiredInput extends CollectExpiredInput { readonly orphanBefore: string; }\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Tenant storage entitlement, usage, reservation and retention (§12.7.6-12.7.7).\n *\n * The SDK does not know what a plan is. It never sees `free`, `pro`, a price, a\n * currency, or a purchase flow — those belong to the host SaaS. What crosses\n * this boundary is a *numeric, versioned* entitlement the host issues, and the\n * constraint test asserts this file contains no plan-name or price vocabulary.\n * The moment the SDK hardcodes a tier, every host is stuck with the SDK's\n * commercial model.\n *\n * Byte counts are `bigint`. Serialization is a composition concern: JSON has no\n * bigint, so a cloud handler renders them as decimal strings on the wire. Using\n * `number` here would put a silent 2^53 ceiling into a storage quota contract.\n *\n * Reservation exists because Postgres and R2 have no shared transaction\n * (§12.7.7). Every durable write reserves first, uploads second, finalizes\n * third; the invariant `committed + reserved + expected <= hardLimit` is\n * checked under the reservation lock, which is what makes concurrent uploads\n * unable to oversell the tenant.\n */\nimport type { ContentHash } from './blob';\nimport type { CoreErrorCode } from './errors';\nimport type { TenantId } from './tenant';\n\n/**\n * The host-issued numeric entitlement (§12.7.6, verbatim).\n *\n * `version` is monotonic and CAS-checked on write: a delayed control-plane\n * update must not resurrect an older plan over a newer one.\n */\nexport interface TenantStorageEntitlement {\n tenantId: TenantId;\n version: bigint;\n hardLimitBytes: bigint;\n maxObjectBytes: bigint;\n maxInlineBytes: bigint;\n mailboxLimitBytes: bigint;\n retentionPolicyId: string;\n /** Canonical ISO-8601 UTC instant — see {@link TenantStorageEntitlementInput}. */\n downgradeGraceUntil?: string;\n}\n\n/**\n * Measured tenant usage (§12.7.6, verbatim).\n *\n * Carries no `tenantId` because it is always read through a tenant-scoped port\n * call — the tenant is the query, not a field of the answer.\n */\nexport interface TenantStorageUsage {\n committedObjectBytes: bigint;\n committedInlineBytes: bigint;\n reservedBytes: bigint;\n objectCount: bigint;\n updatedAt: string;\n}\n\n/** Entitlement write payload. `tenantId` comes from the port's first parameter. */\nexport interface TenantStorageEntitlementInput {\n readonly version: bigint;\n readonly hardLimitBytes: bigint;\n readonly maxObjectBytes: bigint;\n readonly maxInlineBytes: bigint;\n readonly mailboxLimitBytes: bigint;\n readonly retentionPolicyId: string;\n /**\n * Deadline after which an over-limit tenant is suspended rather than blocked.\n *\n * Must be a **canonical ISO-8601 UTC instant** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`. The in-memory\n * composition compares this deadline as a string and a SQL composition\n * compares it as a `timestamptz`, and those two agree only on the canonical\n * form — see `time.ts`.\n */\n readonly downgradeGraceUntil?: string;\n}\n\n/** Durable write classes a reservation can cover. */\nexport const STORAGE_WRITE_KINDS = ['object', 'inline'] as const;\nexport type StorageWriteKind = (typeof STORAGE_WRITE_KINDS)[number];\n\nexport const STORAGE_RESERVATION_STATES = [\n 'reserved',\n 'committed',\n 'aborted',\n 'expired',\n] as const;\nexport type StorageReservationState = (typeof STORAGE_RESERVATION_STATES)[number];\n\nexport interface StorageReservation {\n readonly tenantId: TenantId;\n readonly reservationId: string;\n readonly state: StorageReservationState;\n readonly kind: StorageWriteKind;\n readonly expectedBytes: bigint;\n readonly contentHash: ContentHash;\n readonly contentType: string;\n readonly createdAt: string;\n readonly expiresAt: string;\n readonly settledAt?: string;\n}\n\nexport interface StorageReservationInput {\n readonly reservationId: string;\n readonly kind: StorageWriteKind;\n readonly expectedBytes: bigint;\n readonly contentHash: ContentHash;\n readonly contentType: string;\n readonly ttlMs: number;\n}\n\n/**\n * Finalize payload. Size/type are what the composition observed on the object\n * store, not what the client promised — disagreement is\n * `storage_integrity_mismatch`.\n *\n * Hash identity stays on the reservation as the authenticated daemon's\n * declaration (ADR-024). Object-store HEAD does not independently observe a\n * SHA-256 digest, so accepting one here would turn a copied declaration into a\n * false verification claim.\n */\nexport interface StorageFinalizeInput {\n readonly reservationId: string;\n readonly observedByteSize: bigint;\n readonly observedContentType: string;\n}\n\nexport interface StorageFinalizeResult {\n readonly reservation: StorageReservation;\n readonly usage: TenantStorageUsage;\n /**\n * True when this tenant already had the same content hash committed. The\n * reserved bytes are released and nothing is added: same tenant, same hash,\n * counted once (§12.7.6). Cross-tenant sharing never happens — usage is\n * per-tenant even when the bytes are identical.\n */\n readonly deduplicated: boolean;\n}\n\n/** Effective write posture derived from entitlement + usage + clock (§12.7.8). */\nexport const STORAGE_WRITE_POSTURES = ['normal', 'warning', 'blocked', 'suspended'] as const;\nexport type StorageWritePosture = (typeof STORAGE_WRITE_POSTURES)[number];\n\nexport interface StorageStatus {\n readonly entitlement: TenantStorageEntitlement;\n readonly usage: TenantStorageUsage;\n readonly posture: StorageWritePosture;\n /** `committed + reserved` against `hardLimitBytes`, for host UI. */\n readonly availableBytes: bigint;\n readonly graceActive: boolean;\n}\n\n/**\n * The five wire-stable storage error codes (§12.7.7). Renaming one is a\n * breaking change for every host that branches on them.\n */\nexport const STORAGE_ERROR_CODES = [\n 'storage_object_too_large',\n 'storage_quota_exceeded',\n 'storage_reservation_expired',\n 'storage_integrity_mismatch',\n 'storage_write_suspended',\n] as const satisfies readonly CoreErrorCode[];\n\nexport type StorageErrorCode = (typeof STORAGE_ERROR_CODES)[number];\n\n/** HTTP status mapping from §12.7.7. Compositions render these verbatim. */\nexport const STORAGE_ERROR_HTTP_STATUS = {\n storage_object_too_large: 413,\n storage_quota_exceeded: 507,\n storage_reservation_expired: 409,\n storage_integrity_mismatch: 422,\n storage_write_suspended: 423,\n} as const satisfies Record<StorageErrorCode, number>;\n\n/**\n * Quota port. Tenant-first, async.\n *\n * Raises: `storage_entitlement_missing`,\n * `storage_entitlement_version_conflict` (carries the current entitlement),\n * `storage_reservation_not_found`, and the five wire-stable codes above.\n */\nexport interface QuotaStore {\n collectExpired(tenant: TenantId, input: QuotaCollectExpiredInput): Promise<CollectExpiredResult>;\n readEntitlement(tenant: TenantId): Promise<TenantStorageEntitlement | undefined>;\n /**\n * Version CAS: a write at or below the stored version is rejected with the\n * current row. Raises `timestamp_not_canonical` when `downgradeGraceUntil` is\n * not a canonical ISO-8601 UTC instant.\n */\n writeEntitlement(\n tenant: TenantId,\n input: TenantStorageEntitlementInput,\n ): Promise<TenantStorageEntitlement>;\n readUsage(tenant: TenantId): Promise<TenantStorageUsage>;\n readStatus(tenant: TenantId): Promise<StorageStatus>;\n /** Tenant-scoped lookup used to bind a finalize request to its reservation. */\n readReservation(tenant: TenantId, reservationId: string): Promise<StorageReservation | undefined>;\n /**\n * Atomically checks `committed + reserved + expected <= hardLimitBytes` and,\n * on success, adds `expectedBytes` to `reservedBytes`.\n */\n reserve(tenant: TenantId, input: StorageReservationInput): Promise<StorageReservation>;\n /**\n * Moves reserved bytes to committed after verifying the observed object.\n * For object reservations, the composition commits the matching manifest in\n * the same authority step as reservation/accounting settlement.\n */\n finalizeReservation(\n tenant: TenantId,\n input: StorageFinalizeInput,\n ): Promise<StorageFinalizeResult>;\n /** Idempotent release. Already-settled reservations return their settled row. */\n abortReservation(tenant: TenantId, reservationId: string): Promise<StorageReservation>;\n\n}\n\nexport interface QuotaCollectExpiredInput extends CollectExpiredInput { readonly settledBefore: string; }\n","/**\n * Capability declaration (ADR-010).\n *\n * A client learns what a deployment supports by reading a declaration, never by\n * probing endpoints and interpreting 404/405/501. Status-code sniffing conflates\n * \"this build does not have that feature\" with \"that request was wrong\" and\n * with \"a proxy ate it\", and every consumer ends up with its own guess.\n *\n * The schema is intentionally the minimum that supports that rule: an opaque\n * string set plus a monotonic declaration version. Capability names are host and\n * deployment vocabulary — core validates their shape, never their meaning, so a\n * new capability never requires a core release.\n */\nimport { z } from 'zod';\nimport { ByokCoreError } from './errors';\n\nexport const CAPABILITY_DECLARATION_SCHEMA_ID = 'byok-capabilities-v1';\n\n/** Capability names: lowercase dotted segments, e.g. `board.sse`, `storage.reservations`. */\nexport const CAPABILITY_NAME_PATTERN = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;\n\nexport const CapabilityDeclarationSchema = z\n .object({\n schema: z.literal(CAPABILITY_DECLARATION_SCHEMA_ID),\n /** Monotonic per deployment. Lets a client cache and detect a rollout. */\n version: z.number().int().nonnegative(),\n capabilities: z.array(z.string().regex(CAPABILITY_NAME_PATTERN)),\n })\n .superRefine((declaration, ctx) => {\n const seen = new Set<string>();\n for (const [index, name] of declaration.capabilities.entries()) {\n if (seen.has(name)) {\n ctx.addIssue({\n code: 'custom',\n path: ['capabilities', index],\n message: `Duplicate capability ${JSON.stringify(name)}.`,\n });\n }\n seen.add(name);\n }\n });\n\nexport type CapabilityDeclaration = z.infer<typeof CapabilityDeclarationSchema>;\n\n/**\n * Parses a declaration fail-closed.\n *\n * @throws {ByokCoreError} code `capability_declaration_invalid`.\n */\nexport function parseCapabilityDeclaration(input: unknown): CapabilityDeclaration {\n const result = CapabilityDeclarationSchema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'capability_declaration_invalid',\n `Invalid capability declaration: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\nexport function hasCapability(\n declaration: CapabilityDeclaration,\n capability: string,\n): boolean {\n return declaration.capabilities.includes(capability);\n}\n\n/**\n * The enforcement point ADR-010 exists for: a caller asserts the capability up\n * front and gets a named failure, instead of issuing the request and guessing\n * what the status code meant.\n *\n * @throws {ByokCoreError} code `capability_unavailable`.\n */\nexport function assertCapability(\n declaration: CapabilityDeclaration,\n capability: string,\n): void {\n if (!hasCapability(declaration, capability)) {\n throw new ByokCoreError(\n 'capability_unavailable',\n `Capability ${JSON.stringify(capability)} is not declared by this deployment.`,\n );\n }\n}\n","/**\n * Skill packs: declarative content a SaaS deployment distributes to a paired\n * device (plan `skill-pack-delivery-channel`, Phase 1).\n *\n * A pack is an `agentskills.io`-shaped `SKILL.md` plus its static companion\n * files. That is the WHOLE of it, and the narrowness is the design:\n *\n * 1. **No executable surface, by schema.** {@link SkillPackManifestSchema} is a\n * `strictObject`, so an unknown key is a rejection rather than a field\n * someone's tooling might later start honoring, and\n * {@link SKILL_PACK_FORBIDDEN_FIELDS} names the specific ones — `exec`,\n * `env`, `credential`, `hooks`, `allowed-tools` — that get their own\n * rejection message. The credential-isolation rule this SDK is built around\n * (§9.1) cannot be enforced downstream if the manifest can carry a command\n * to run or an environment to run it in, so it is enforced here, once.\n * 2. **Every declared limit has an evaluation point in this file.** A size cap\n * that nothing measures, a path rule that nothing checks, and a content hash\n * that nothing verifies are the same failure: a security claim with no\n * enforcement behind it. {@link checkSkillPackManifest} evaluates the\n * manifest-level limits and {@link checkSkillPackFileContent} evaluates the\n * byte-level ones, both returning a named rejection instead of a boolean, so\n * a caller can say which limit fired.\n * 3. **Hashing lives outside core.** Core has no `node:` import and no crypto\n * (the same rule `blob.ts` and `attestation.ts` follow), so this module owns\n * the canonical bytes a hash is taken over ({@link skillPackContentHashInput})\n * and the comparison, never the digest itself. The installer supplies what it\n * observed; core decides whether that is acceptable.\n *\n * Distribution is hosted HTTP (`@byok-sdk/cloud`'s `GET /byok/skill-packs`),\n * declared through ADR-010 as `skills.pack`. Nothing here touches the frozen v1\n * wire envelope, and there is deliberately no new message type: a pack is\n * content a device PULLS after reading a declaration, not a message a server\n * pushes into a task stream.\n */\nimport { z } from 'zod';\nimport { CONTENT_HASH_PATTERN, contentHash, type ContentHash } from './blob';\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\nexport const SKILL_PACK_MANIFEST_SCHEMA_ID = 'byok-skill-pack-v1';\n\n/**\n * Pack names: lowercase, starting alphanumeric — the same shape\n * `OBJECT_KEY_PREFIX_PATTERN` accepts per segment, for the same reason. A pack\n * name becomes a directory name on a real device filesystem, so the accepted\n * set is the one that reaches disk spelled exactly as declared: no case folding\n * to collide over, no separator, no leading dot, nothing needing escaping.\n */\nexport const SKILL_PACK_NAME_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;\nexport const SKILL_PACK_NAME_MAX_LENGTH = 64;\nexport const SKILL_PACK_DESCRIPTION_MAX_LENGTH = 1024;\n\n/** `MAJOR.MINOR.PATCH`. A pack version orders two publications of one name; it is not a range language. */\nexport const SKILL_PACK_VERSION_PATTERN = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$/;\n\n/**\n * Relative POSIX paths only: slash-joined segments of alphanumerics, `.`, `_`\n * and `-`, each STARTING with an alphanumeric.\n *\n * That single \"starts with an alphanumeric\" rule is what closes the traversal\n * class rather than a blocklist of spellings: `..` cannot match (a segment may\n * not begin with `.`), an absolute path cannot match (no leading slash), an\n * empty segment cannot match (`a//b`), a Windows drive or UNC path cannot match\n * (no `:`, no `\\`), a home-relative path cannot match (no `~`), and a dotfile\n * cannot match either. A blocklist would have to anticipate every encoding of\n * the same idea; this allowlist has nothing to anticipate.\n */\nexport const SKILL_PACK_FILE_PATH_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*(\\/[A-Za-z0-9][A-Za-z0-9._-]*)*$/;\nexport const SKILL_PACK_FILE_PATH_MAX_LENGTH = 200;\n\n/** The entry file every pack must carry, spelled as `agentskills.io` spells it. */\nexport const SKILL_PACK_ENTRY_PATH = 'SKILL.md';\n\n/** Per-file ceiling, measured in BYTES over the observed content — never in characters. */\nexport const SKILL_PACK_FILE_MAX_BYTES = 262_144;\n/** Whole-pack ceiling, over the sum of the observed file sizes. */\nexport const SKILL_PACK_MAX_BYTES = 1_048_576;\nexport const SKILL_PACK_MAX_FILES = 64;\n\n/**\n * Manifest keys that must never exist, listed so the prohibition is testable\n * rather than implied.\n *\n * `strictObject` already rejects every unknown key, so this list adds no new\n * authority — it adds a NAMED rejection for the subset that matters: an\n * operator who sees `unrecognized key: \"env\"` learns nothing about why, and a\n * reviewer reading the schema cannot tell whether the omission was a decision\n * or an oversight. Pinned from both directions by\n * `__tests__/skill-pack.test.ts`.\n */\nexport const SKILL_PACK_FORBIDDEN_FIELDS = [\n 'exec',\n 'command',\n 'entrypoint',\n 'run',\n 'script',\n 'shell',\n 'env',\n 'environment',\n 'credential',\n 'credentials',\n 'secret',\n 'secrets',\n 'token',\n 'apiKey',\n 'api_key',\n 'allowedTools',\n 'allowed-tools',\n 'hooks',\n 'preinstall',\n 'postinstall',\n] as const;\n\nconst ContentHashSchema = z\n .string()\n .regex(CONTENT_HASH_PATTERN)\n .transform((value) => contentHash(value));\n\n/** One file in a pack: where it goes, what it must hash to, and how big it is. */\nexport const SkillPackFileSchema = z.strictObject({\n path: z.string().min(1).max(SKILL_PACK_FILE_PATH_MAX_LENGTH).regex(SKILL_PACK_FILE_PATH_PATTERN),\n contentHash: ContentHashSchema,\n byteSize: z.number().int().nonnegative().max(SKILL_PACK_FILE_MAX_BYTES),\n});\n\nexport type SkillPackFile = z.infer<typeof SkillPackFileSchema>;\n\n/**\n * The published description of one pack.\n *\n * `contentHash` addresses the manifest AS A WHOLE — see\n * {@link skillPackContentHashInput} — which is what makes an install\n * content-addressed: two publications that differ in any field a device can\n * observe land in two directories, and re-installing an unchanged pack is a\n * no-op rather than a partial overwrite.\n */\nexport const SkillPackManifestSchema = z.strictObject({\n schema: z.literal(SKILL_PACK_MANIFEST_SCHEMA_ID),\n name: z.string().min(1).max(SKILL_PACK_NAME_MAX_LENGTH).regex(SKILL_PACK_NAME_PATTERN),\n version: z.string().regex(SKILL_PACK_VERSION_PATTERN),\n description: z.string().min(1).max(SKILL_PACK_DESCRIPTION_MAX_LENGTH),\n files: z.array(SkillPackFileSchema).min(1).max(SKILL_PACK_MAX_FILES),\n contentHash: ContentHashSchema,\n});\n\nexport type SkillPackManifest = z.infer<typeof SkillPackManifestSchema>;\n\n/**\n * Parses a manifest fail-closed.\n *\n * @throws {ByokCoreError} code `skill_pack_manifest_invalid`.\n */\nexport function parseSkillPackManifest(input: unknown): SkillPackManifest {\n if (typeof input === 'object' && input !== null) {\n const present = SKILL_PACK_FORBIDDEN_FIELDS.filter((field) =>\n Object.prototype.hasOwnProperty.call(input, field),\n );\n if (present.length > 0) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `A skill pack manifest carries no executable or credential surface; refusing ${present\n .map((field) => JSON.stringify(field))\n .join(', ')}.`,\n );\n }\n }\n const result = SkillPackManifestSchema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Invalid skill pack manifest: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * The exact bytes `manifest.contentHash` is the sha256 of.\n *\n * Written out here, in core, because both ends have to agree on it and neither\n * end may derive its own version: the publisher hashes this string to mint the\n * address, the installer hashes it again to verify what it fetched, and a\n * disagreement between the two would make every install either falsely\n * accepted or unconditionally rejected. Newline-delimited and terminated so no\n * field's content can be shifted into the next field's position, and the file\n * rows are sorted by path so two publishers that enumerate a directory in\n * different orders still mint the same address.\n */\nexport function skillPackContentHashInput(manifest: {\n readonly name: string;\n readonly version: string;\n readonly description: string;\n readonly files: readonly SkillPackFile[];\n}): string {\n const rows = [...manifest.files]\n .sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0))\n .map((file) => `${file.path}\\n${file.contentHash as string}\\n${file.byteSize}\\n`);\n return [\n `${SKILL_PACK_MANIFEST_SCHEMA_ID}\\n`,\n `${manifest.name}\\n`,\n `${manifest.version}\\n`,\n `${manifest.description.length}\\n`,\n `${manifest.description}\\n`,\n `${manifest.files.length}\\n`,\n ...rows,\n ].join('');\n}\n\n/** Every way a pack can be refused. One name per declared limit — see {@link SkillPackCheck}. */\nexport const SKILL_PACK_REJECTIONS = [\n 'path-unsafe',\n 'duplicate-path',\n 'entry-missing',\n 'file-count-over-cap',\n 'file-over-cap',\n 'pack-over-cap',\n 'size-mismatch',\n 'hash-mismatch',\n 'name-mismatch',\n] as const;\nexport type SkillPackRejection = (typeof SKILL_PACK_REJECTIONS)[number];\n\n/**\n * Outcome of a check. `bytes` is the measured total on the accept path so a\n * caller can record what it admitted; a rejection always names WHICH limit\n * fired, because \"the pack was rejected\" is not an operable message.\n */\nexport type SkillPackCheck =\n | { readonly ok: true; readonly bytes: number }\n | { readonly ok: false; readonly reason: SkillPackRejection; readonly detail: string };\n\n/** Non-throwing path-safety predicate — the one authority on what a pack may name. */\nexport function isSkillPackPathSafe(path: string): boolean {\n return (\n path.length > 0 &&\n path.length <= SKILL_PACK_FILE_PATH_MAX_LENGTH &&\n SKILL_PACK_FILE_PATH_PATTERN.test(path)\n );\n}\n\n/**\n * The manifest-level limits, evaluated.\n *\n * Runs over a manifest that has already parsed, so the per-field caps zod owns\n * are not re-litigated here. What is left is everything zod cannot see: the\n * relationships BETWEEN files (a duplicate path, a missing entry file, a total\n * that clears every per-file cap and still blows the pack cap).\n */\nexport function checkSkillPackManifest(manifest: SkillPackManifest): SkillPackCheck {\n if (manifest.files.length > SKILL_PACK_MAX_FILES) {\n return {\n ok: false,\n reason: 'file-count-over-cap',\n detail: `${manifest.files.length} files exceeds the ${SKILL_PACK_MAX_FILES} file limit.`,\n };\n }\n\n const seen = new Set<string>();\n let bytes = 0;\n for (const file of manifest.files) {\n if (!isSkillPackPathSafe(file.path)) {\n return { ok: false, reason: 'path-unsafe', detail: `${JSON.stringify(file.path)} is not a safe relative path.` };\n }\n if (seen.has(file.path)) {\n return { ok: false, reason: 'duplicate-path', detail: `${JSON.stringify(file.path)} is declared twice.` };\n }\n seen.add(file.path);\n if (file.byteSize > SKILL_PACK_FILE_MAX_BYTES) {\n return {\n ok: false,\n reason: 'file-over-cap',\n detail: `${JSON.stringify(file.path)} declares ${file.byteSize} bytes, over the ${SKILL_PACK_FILE_MAX_BYTES} byte per-file limit.`,\n };\n }\n bytes += file.byteSize;\n }\n\n if (!seen.has(SKILL_PACK_ENTRY_PATH)) {\n return {\n ok: false,\n reason: 'entry-missing',\n detail: `A skill pack must carry ${SKILL_PACK_ENTRY_PATH}.`,\n };\n }\n if (bytes > SKILL_PACK_MAX_BYTES) {\n return {\n ok: false,\n reason: 'pack-over-cap',\n detail: `${bytes} declared bytes exceeds the ${SKILL_PACK_MAX_BYTES} byte pack limit.`,\n };\n }\n return { ok: true, bytes };\n}\n\n/** What an installer actually measured for one file, as opposed to what the manifest declared. */\nexport interface ObservedSkillPackFile {\n readonly byteSize: number;\n readonly contentHash: ContentHash;\n}\n\n/**\n * The byte-level limits, evaluated against what was actually fetched.\n *\n * The asymmetry with {@link checkSkillPackManifest} is the point: the declared\n * size is a claim by the publisher and the observed size is a fact about the\n * bytes on the device, so the cap is enforced on the OBSERVED value. A check\n * that only ever measured the declaration would pass a 4 KiB manifest row\n * attached to a 40 MiB response.\n */\nexport function checkSkillPackFileContent(\n declared: SkillPackFile,\n observed: ObservedSkillPackFile,\n): SkillPackCheck {\n if (!isSkillPackPathSafe(declared.path)) {\n return { ok: false, reason: 'path-unsafe', detail: `${JSON.stringify(declared.path)} is not a safe relative path.` };\n }\n if (observed.byteSize > SKILL_PACK_FILE_MAX_BYTES) {\n return {\n ok: false,\n reason: 'file-over-cap',\n detail: `${JSON.stringify(declared.path)} delivered ${observed.byteSize} bytes, over the ${SKILL_PACK_FILE_MAX_BYTES} byte per-file limit.`,\n };\n }\n if (observed.byteSize !== declared.byteSize) {\n return {\n ok: false,\n reason: 'size-mismatch',\n detail: `${JSON.stringify(declared.path)} declared ${declared.byteSize} bytes and delivered ${observed.byteSize}.`,\n };\n }\n if ((observed.contentHash as string) !== (declared.contentHash as string)) {\n return {\n ok: false,\n reason: 'hash-mismatch',\n detail: `${JSON.stringify(declared.path)} declared ${declared.contentHash as string} and delivered ${observed.contentHash as string}.`,\n };\n }\n return { ok: true, bytes: observed.byteSize };\n}\n\n/**\n * `SKILL.md` frontmatter, in the `agentskills.io` shape: exactly `name` and\n * `description`, both required.\n *\n * The allowlist is the whole contract. `allowed-tools`, `hooks` and friends are\n * real fields in other skill dialects and every one of them widens what a pack\n * can ask a runtime to do; a parser that merely IGNORED them would still let a\n * pack ship them to a host that does not.\n */\nexport interface SkillFrontmatter {\n readonly name: string;\n readonly description: string;\n}\n\n/** The only frontmatter keys a pack may declare. */\nexport const SKILL_FRONTMATTER_FIELDS = ['name', 'description'] as const;\n\nconst FRONTMATTER_DELIMITER = '---';\nconst FRONTMATTER_LINE_PATTERN = /^([A-Za-z][A-Za-z0-9_-]*):[ \\t]*(.*)$/;\n\nfunction unquote(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length >= 2) {\n const first = trimmed[0];\n const last = trimmed[trimmed.length - 1];\n if ((first === '\"' && last === '\"') || (first === \"'\" && last === \"'\")) {\n const inner = trimmed.slice(1, -1);\n return inner.includes(first) ? undefined : inner;\n }\n }\n return trimmed;\n}\n\n/**\n * Parses and validates a `SKILL.md`'s frontmatter block.\n *\n * Deliberately not a YAML engine: this is a closed two-key grammar, and the\n * whole reason to hand-write it is that a general parser would happily accept\n * anchors, aliases, nested maps, multi-document streams and block scalars —\n * every one of which is a way to express something this format has decided not\n * to have. Anything outside the grammar is a rejection, never a skipped line.\n *\n * @throws {ByokCoreError} code `skill_pack_frontmatter_invalid`.\n */\nexport function parseSkillFrontmatter(text: string): SkillFrontmatter {\n const reject = (message: string): never => {\n throw new ByokCoreError('skill_pack_frontmatter_invalid', message);\n };\n\n const lines = text.split('\\n');\n if (lines[0]?.trimEnd() !== FRONTMATTER_DELIMITER) {\n reject(`A skill file must open with a ${FRONTMATTER_DELIMITER} frontmatter delimiter.`);\n }\n const closing = lines.findIndex((line, index) => index > 0 && line.trimEnd() === FRONTMATTER_DELIMITER);\n if (closing < 0) reject(`The frontmatter block is not closed by a ${FRONTMATTER_DELIMITER} line.`);\n\n const fields = new Map<string, string>();\n for (const line of lines.slice(1, closing)) {\n if (line.trim().length === 0) continue;\n const match = FRONTMATTER_LINE_PATTERN.exec(line);\n if (match === null) reject(`Frontmatter line ${JSON.stringify(line)} is not a \\`key: value\\` pair.`);\n const key = match![1]!;\n if (!(SKILL_FRONTMATTER_FIELDS as readonly string[]).includes(key)) {\n reject(\n `Frontmatter key ${JSON.stringify(key)} is not one of ${SKILL_FRONTMATTER_FIELDS.join(', ')}; a skill declares no tools, hooks, or environment.`,\n );\n }\n if (fields.has(key)) reject(`Frontmatter key ${JSON.stringify(key)} is declared twice.`);\n const value = unquote(match![2]!);\n if (value === undefined || value.length === 0) {\n reject(`Frontmatter key ${JSON.stringify(key)} has no usable value.`);\n }\n fields.set(key, value!);\n }\n\n const name = fields.get('name');\n const description = fields.get('description');\n if (name === undefined) reject('Frontmatter is missing `name`.');\n if (description === undefined) reject('Frontmatter is missing `description`.');\n if (name!.length > SKILL_PACK_NAME_MAX_LENGTH || !SKILL_PACK_NAME_PATTERN.test(name!)) {\n reject(\n `Frontmatter \\`name\\` must match ${SKILL_PACK_NAME_PATTERN.source} and be at most ${SKILL_PACK_NAME_MAX_LENGTH} characters.`,\n );\n }\n if (description!.length > SKILL_PACK_DESCRIPTION_MAX_LENGTH) {\n reject(`Frontmatter \\`description\\` exceeds ${SKILL_PACK_DESCRIPTION_MAX_LENGTH} characters.`);\n }\n return { name: name!, description: description! };\n}\n\n/**\n * The entry file's own declaration must agree with the manifest's.\n *\n * Two authorities naming the same pack is not a redundancy to tolerate — a\n * device that installed under one name and handed the runtime a skill calling\n * itself another would be projecting content nobody asked for.\n */\nexport function checkSkillPackEntry(manifest: SkillPackManifest, entryText: string): SkillPackCheck {\n const frontmatter = parseSkillFrontmatter(entryText);\n if (frontmatter.name !== manifest.name) {\n return {\n ok: false,\n reason: 'name-mismatch',\n detail: `${SKILL_PACK_ENTRY_PATH} declares ${JSON.stringify(frontmatter.name)} but the manifest declares ${JSON.stringify(manifest.name)}.`,\n };\n }\n return { ok: true, bytes: new TextEncoder().encode(entryText).length };\n}\n\n/** One file's bytes, as the distribution surface hands them over. */\nexport interface SkillPackFileContent {\n readonly path: string;\n readonly contentHash: ContentHash;\n readonly byteSize: number;\n /** UTF-8 text. A pack carries Markdown, YAML and static text assets — never binaries, never archives. */\n readonly content: string;\n}\n\n/** What a publisher hands the store: the validated manifest plus the bytes it addresses. */\nexport interface SkillPackPublishInput {\n readonly manifest: SkillPackManifest;\n readonly files: readonly { readonly path: string; readonly content: string }[];\n}\n\nexport interface SkillPackListQuery {\n readonly limit?: number;\n}\n\n/**\n * Skill pack port. Tenant-first, async, content plus manifest.\n *\n * Registered in `ports-contract.ts` as a core PORT, and deliberately not (yet)\n * a member of `CoreStores`: a composition contract that named it would oblige\n * every existing composition to implement it in the same slice, and the\n * Postgres implementation is Phase 2 of this plan. See `ports-contract.ts` for\n * the full note on that split.\n *\n * Raises: `skill_pack_manifest_invalid` (a publish whose bytes disagree with\n * the manifest it was handed).\n */\nexport interface SkillPackStore {\n /** Idempotent per (tenant, name, contentHash). Publishing a changed pack under the same name replaces it. */\n publish(tenant: TenantId, input: SkillPackPublishInput): Promise<SkillPackManifest>;\n get(tenant: TenantId, name: string): Promise<SkillPackManifest | undefined>;\n list(tenant: TenantId, query: SkillPackListQuery): Promise<readonly SkillPackManifest[]>;\n readFile(tenant: TenantId, name: string, path: string): Promise<SkillPackFileContent | undefined>;\n}\n","/**\n * The composition contract: the full set of store ports, plus the clock seam.\n *\n * Every method on every port in this package obeys two rules, and\n * `src/__tests__/constraints.test.ts` enumerates them method by method to prove\n * it (sprint I7):\n *\n * 1. **Async.** Every method returns a `Promise`. A synchronous port would\n * silently exclude SQL and object-store compositions from the contract.\n * 2. **Tenant-first.** Every method's first parameter is a required\n * {@link TenantId}. There is no bare `deviceId`/`taskId` lookup anywhere —\n * §12.6.2 layer 3 forbids the index such a lookup would need, and layer 5\n * requires the tenant to be part of the lookup key rather than a second\n * comparison step that can be forgotten.\n *\n * No port method can change the tenant of an existing row. That is not an\n * omission: \"move this to another tenant\" is the one operation that would make\n * every cross-tenant assertion in the conformance suite unfalsifiable.\n */\nimport type { PresenceStore } from './presence';\nimport type { BoardStore } from './board';\nimport type { MailboxStore } from './mailbox';\nimport type { ObjectStore } from './blob';\nimport type { QuotaStore } from './quota';\nimport type { SkillPackStore } from './skill-pack';\nimport type { TenantId } from './tenant';\nimport type { TruthStore } from './truth';\n\n/**\n * Injected time.\n *\n * TTL semantics (presence expiry and reservation expiry) are\n * behavior the conformance suite has to assert deterministically, which is\n * impossible against a wall clock. Compositions inject one; nothing in core\n * calls `Date.now()` directly.\n */\nexport interface Clock {\n now(): Date;\n}\n\n/** A clock pinned to a fixed instant, advanced explicitly. Used by tests and the in-memory reference. */\nexport interface MutableClock extends Clock {\n advance(ms: number): void;\n set(instant: Date): void;\n}\n\n/** Every port a composition must supply. */\nexport interface CoreStores {\n readonly mailbox: MailboxStore;\n readonly board: BoardStore;\n readonly truth: TruthStore;\n readonly presence: PresenceStore;\n readonly objects: ObjectStore;\n readonly quota: QuotaStore;\n /**\n * Skill-pack storage is a MANDATORY member: every composition creates the\n * tables and supplies the port (Phase 2 of `skill-pack-delivery-channel`).\n * Storage presence is not capability advertisement — the wire route/capability\n * stays optional in `@byok-sdk/cloud` (`includeSkillPacks`), and a deployment\n * that never declares `skills.pack` simply keeps the tables empty.\n */\n readonly skillPacks: SkillPackStore;\n}\n\n/** Names of the ports in {@link CoreStores}, in contract order. */\nexport const CORE_STORE_NAMES = [\n 'mailbox',\n 'board',\n 'truth',\n 'presence',\n 'objects',\n 'quota',\n 'skillPacks',\n] as const;\n\nexport type CoreStoreName = (typeof CORE_STORE_NAMES)[number];\n\n// Layer 2 of §12.6.2 — the tenant-closed facade a handler actually receives —\n// is deliberately not here. It is shaped by how handlers are written, and the\n// first handlers land in `@byok-sdk/cloud` (S3). Defining it now would mean\n// guessing that shape and freezing the guess into the contract package that\n// every later sprint depends on. The tenant-first ports below are what make\n// that facade a thin binding rather than a new authority.\n","/**\n * The declared method inventory of every core port (sprint I7).\n *\n * This table is contract data, not test data — it says what a port IS, and it\n * is enforced from two directions that must read the same table:\n *\n * - `__tests__/constraints.test.ts` scans the *source interfaces* in this\n * package and asserts each listed method exists, is async, and takes a\n * required `TenantId` first.\n * - `@byok-sdk/conformance`'s port-inventory dimension asserts every *composition\n * under test* implements exactly these methods — no missing method, and no\n * extra one that the contract has not pinned down and that therefore no\n * other composition would implement.\n *\n * It lives in shipped source rather than under `__tests__/` because the second\n * enforcer is now a separate package (S4A story O-005): a `core → conformance`\n * devDependency for a table `core` itself asserts against would be a cycle,\n * and the direction that has to hold is `conformance → core`.\n *\n * Adding a port method means editing this table, which is the point: a port\n * grows by contract, not by whichever composition needed something.\n */\nimport { CORE_STORE_NAMES, type CoreStoreName } from './stores';\n\n/**\n * Ports that are core ports but NOT members of the composition contract.\n *\n * Now empty, and that is the whole point of Phase 2. Phase 1 of\n * `skill-pack-delivery-channel` held `skillPacks` here as a self-declared\n * temporary bridge: adding it to `CoreStores` before its Postgres\n * implementation existed would have obliged every composition to implement it\n * in the same slice, and the alternatives — an optional port member (a\n * compatibility fallback, forbidden) or a port outside the contract table\n * entirely (exempt from the tenant-first scan, the one rule most worth having)\n * — were both worse. Phase 2 delivered that implementation and moved\n * `skillPacks` into `CORE_STORE_NAMES`, so this list goes back to empty exactly\n * as the Phase 1 note promised. The empty set stays named rather than deleted:\n * it is the testable statement \"every core port is a composition member\", which\n * `CORE_STORE_NAMES` alone cannot make.\n */\nexport const CORE_NON_COMPOSITION_PORT_NAMES = [] as const;\n\nexport const CORE_PORT_METHODS: Readonly<Record<CoreStoreName, readonly string[]>> = {\n mailbox: [\n 'append',\n 'readUsage',\n 'readAfter',\n 'recordDelivery',\n 'advanceCursor',\n 'readCursor',\n 'collectExpired',\n 'expirePending',\n 'closeStream',\n 'reopenStream',\n ],\n board: ['create', 'get', 'list', 'claim', 'unclaim', 'updateStatus', 'remove'],\n truth: ['writeTerminal', 'writeSnapshot', 'getRecord', 'listManifest'],\n presence: ['publish', 'read', 'list', 'collectExpired'],\n objects: [\n 'putManifest',\n 'commit',\n 'get',\n 'list',\n 'addReference',\n 'removeReference',\n 'markDeletePending',\n 'markDeleted',\n 'collectExpired',\n ],\n quota: [\n 'readEntitlement',\n 'writeEntitlement',\n 'readUsage',\n 'readStatus',\n 'readReservation',\n 'reserve',\n 'finalizeReservation',\n 'abortReservation',\n 'collectExpired',\n ],\n skillPacks: ['publish', 'get', 'list', 'readFile'],\n};\n\n/** The interface each port name is declared as, for the source-side scan. */\nexport const CORE_PORT_INTERFACES: Readonly<Record<CoreStoreName, string>> = {\n mailbox: 'MailboxStore',\n board: 'BoardStore',\n truth: 'TruthStore',\n presence: 'PresenceStore',\n objects: 'ObjectStore',\n quota: 'QuotaStore',\n skillPacks: 'SkillPackStore',\n};\n","/**\n * Device proof envelope and canonical signing bytes (§12.6.3, sprint §S6.2).\n *\n * Three things live here and nothing else:\n *\n * 1. **The protected-claims schema.** Every field a signature must cover so the\n * proof binds a *specific request*: tenant, product, device, key + epoch,\n * request id, operation, resource, the request line (method+path or a stable\n * operation id), and the body's hash *and* size. Signing only the body is\n * forbidden — it would let a valid proof be replayed against a different\n * operation or resource.\n * 2. **A dependency-free deterministic canonicalizer.** RFC 8785 (JCS) in the\n * narrow subset the envelope allows. Node and Workers must produce\n * byte-identical output, so the accepted value space is deliberately small:\n * strings, booleans, null, safe integers, plain objects, arrays. Floats,\n * non-safe integers, `NaN`, `Infinity`, `undefined`, `bigint`, dates and\n * class instances throw instead of being coerced — a signature over a value\n * whose serialization is implementation-defined is not a signature.\n * 3. **The verify port.** An interface, never an implementation: core is\n * Node-free and Workers-safe, and `node:crypto` and WebCrypto disagree about\n * key handling. The composition brings its own verifier.\n *\n * Claims are **untrusted input**. `tenantId` here is a plain string, not a\n * branded `TenantId`, because a device asserting a tenant proves nothing: the\n * claim is a lookup key used to load the device row, and the row is the\n * authority (§12.6.2 layer 5). Branding happens after that lookup, not here.\n */\nimport { z } from 'zod';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\n\n/** Envelope schema id, self-consistent with the domain prefix below. */\nexport const DEVICE_PROOF_SCHEMA_ID = 'byok-device-proof-v1';\n\n/**\n * Domain separation prefix (§12.6.3). Prepended to the canonical claim bytes\n * before signing so a device-proof signature can never be replayed as a nonce\n * signature (`byok-nonce-v1\\n`) or a record attestation.\n */\nexport const DEVICE_PROOF_DOMAIN_PREFIX = 'byok-device-proof-v1\\n';\n\nexport const DEVICE_PROOF_VERSION = 1;\n\n/** Signature algorithms this envelope version admits. */\nexport const DEVICE_PROOF_ALGORITHMS = ['ed25519'] as const;\nexport type DeviceProofAlgorithm = (typeof DEVICE_PROOF_ALGORITHMS)[number];\n\n/**\n * HTTP header carrying the base64url device-proof envelope on a truth-route\n * request (§12.6.3). Both the daemon that mints the proof and the host that\n * decodes it must name the exact same header, so it is a single wire constant\n * here rather than a string re-spelled on each side.\n */\nexport const DEVICE_PROOF_HEADER = 'x-byok-device-proof';\n\nconst BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;\nconst HTTP_METHOD_PATTERN = /^[A-Z]+$/;\n\n// ---------------------------------------------------------------------------\n// Canonicalization (RFC 8785 subset)\n// ---------------------------------------------------------------------------\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | readonly JsonValue[] | { readonly [key: string]: JsonValue };\nexport type JsonObject = { readonly [key: string]: JsonValue };\n\nfunction canonicalizationFailure(path: string, reason: string): ByokCoreError {\n return new ByokCoreError(\n 'proof_canonicalization_failed',\n `Cannot canonicalize ${path}: ${reason}`,\n );\n}\n\nfunction isPlainObject(value: object): boolean {\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction canonicalizeValue(value: unknown, path: string, seen: Set<object>): string {\n if (value === null) return 'null';\n\n switch (typeof value) {\n case 'boolean':\n return value ? 'true' : 'false';\n case 'string':\n // JSON.stringify implements exactly the ECMAScript string serialization\n // RFC 8785 mandates, including well-formed escaping of lone surrogates.\n return JSON.stringify(value);\n case 'number': {\n if (!Number.isSafeInteger(value)) {\n throw canonicalizationFailure(\n path,\n `only safe integers are canonicalizable, received ${String(value)}`,\n );\n }\n // Normalizes -0 to 0; RFC 8785 has no signed zero.\n return String(value === 0 ? 0 : value);\n }\n case 'undefined':\n throw canonicalizationFailure(path, 'undefined has no canonical form');\n case 'bigint':\n throw canonicalizationFailure(path, 'bigint is not a JSON type');\n case 'function':\n case 'symbol':\n throw canonicalizationFailure(path, `${typeof value} is not a JSON type`);\n case 'object':\n break;\n default:\n throw canonicalizationFailure(path, `unsupported type ${typeof value}`);\n }\n\n const objectValue = value as object;\n if (seen.has(objectValue)) {\n throw canonicalizationFailure(path, 'circular reference');\n }\n seen.add(objectValue);\n try {\n if (Array.isArray(objectValue)) {\n const parts = objectValue.map((entry, index) =>\n canonicalizeValue(entry, `${path}[${index}]`, seen),\n );\n return `[${parts.join(',')}]`;\n }\n if (!isPlainObject(objectValue)) {\n throw canonicalizationFailure(\n path,\n 'only plain objects and arrays are canonicalizable',\n );\n }\n // Default string sort compares UTF-16 code units, which is what RFC 8785\n // specifies for member ordering.\n const keys = Object.keys(objectValue).sort();\n const record = objectValue as Record<string, unknown>;\n const parts = keys.map((key) => {\n const encodedKey = JSON.stringify(key);\n const encodedValue = canonicalizeValue(record[key], `${path}.${key}`, seen);\n return `${encodedKey}:${encodedValue}`;\n });\n return `{${parts.join(',')}}`;\n } finally {\n seen.delete(objectValue);\n }\n}\n\n/**\n * Canonical JSON text for `value`, per RFC 8785 restricted to the value space\n * above. Key insertion order never affects the output; anything outside the\n * accepted space throws `proof_canonicalization_failed`.\n */\nexport function canonicalizeJson(value: JsonValue): string {\n return canonicalizeValue(value, '<root>', new Set());\n}\n\n/** UTF-8 bytes of {@link canonicalizeJson}. `TextEncoder` is a platform global on Node and Workers. */\nexport function canonicalizeJsonBytes(value: JsonValue): Uint8Array {\n return new TextEncoder().encode(canonicalizeJson(value));\n}\n\n// ---------------------------------------------------------------------------\n// Protected claims\n// ---------------------------------------------------------------------------\n\n/**\n * The signed claim set (§S6.2).\n *\n * The request line is expressible two ways — `method` + `path`, or a stable\n * `operationId` — and exactly one form must be present. Allowing both at once\n * would create two different canonical byte strings for one request; allowing\n * neither would drop the operation binding the whole design rests on.\n */\nexport const DeviceProofProtectedClaimsSchema = z\n .strictObject({\n version: z.literal(DEVICE_PROOF_VERSION),\n tenantId: z.string().min(1),\n productId: z.string().min(1),\n deviceId: z.string().min(1),\n /** Identity of the signing key, resolved against the device row at verify time. */\n keyId: z.string().min(1),\n /** Rotation generation. An older epoch is rejected by the verifier, not here. */\n keyEpoch: z.number().int().nonnegative(),\n /** Idempotency key: exact replay returns the original result, reuse with a different body is a conflict. */\n requestId: z.string().min(1),\n /** Logical operation, e.g. `truth.write`. */\n operation: z.string().min(1),\n /** Tenant-scoped resource the operation targets. */\n resource: z.string().min(1),\n method: z.string().regex(HTTP_METHOD_PATTERN).optional(),\n path: z.string().startsWith('/').optional(),\n operationId: z.string().min(1).optional(),\n bodySha256: z.string().regex(CONTENT_HASH_PATTERN),\n /** Bound alongside the hash so a truncation attack cannot hide behind a hash collision claim. */\n bodySize: z.number().int().nonnegative(),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime().optional(),\n nonce: z.string().min(1).optional(),\n })\n .superRefine((claims, ctx) => {\n const hasRequestLine = claims.method !== undefined && claims.path !== undefined;\n const hasOperationId = claims.operationId !== undefined;\n if (hasRequestLine === hasOperationId) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'Claims must carry exactly one request binding: both `method` and `path`, or `operationId`.',\n });\n }\n if (!hasRequestLine && (claims.method !== undefined || claims.path !== undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: '`method` and `path` must be supplied together.',\n });\n }\n });\n\nexport type DeviceProofProtectedClaims = z.infer<typeof DeviceProofProtectedClaimsSchema>;\n\nexport const DeviceProofEnvelopeV1Schema = z.strictObject({\n schema: z.literal(DEVICE_PROOF_SCHEMA_ID),\n algorithm: z.enum(DEVICE_PROOF_ALGORITHMS),\n protected: DeviceProofProtectedClaimsSchema,\n /** base64url, unpadded. */\n signature: z.string().regex(BASE64URL_PATTERN),\n});\n\nexport type DeviceProofEnvelopeV1 = z.infer<typeof DeviceProofEnvelopeV1Schema>;\n\n/**\n * Parses an envelope fail-closed.\n *\n * @throws {ByokCoreError} code `proof_envelope_invalid`.\n */\nexport function parseDeviceProofEnvelope(input: unknown): DeviceProofEnvelopeV1 {\n const result = DeviceProofEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'proof_envelope_invalid',\n `Invalid device proof envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field rather than by spreading the parsed object: an absent\n * optional must be an *absent key*, never a key holding `undefined`, or\n * `{nonce: undefined}` and `{}` would be the same request with two different\n * signatures. The canonicalizer refuses `undefined` outright, so this\n * projection is where absence is decided.\n */\nexport function deviceProofCanonicalClaims(claims: DeviceProofProtectedClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n tenantId: claims.tenantId,\n productId: claims.productId,\n deviceId: claims.deviceId,\n keyId: claims.keyId,\n keyEpoch: claims.keyEpoch,\n requestId: claims.requestId,\n operation: claims.operation,\n resource: claims.resource,\n bodySha256: claims.bodySha256,\n bodySize: claims.bodySize,\n issuedAt: claims.issuedAt,\n };\n if (claims.method !== undefined) canonical['method'] = claims.method;\n if (claims.path !== undefined) canonical['path'] = claims.path;\n if (claims.operationId !== undefined) canonical['operationId'] = claims.operationId;\n if (claims.expiresAt !== undefined) canonical['expiresAt'] = claims.expiresAt;\n if (claims.nonce !== undefined) canonical['nonce'] = claims.nonce;\n return canonical;\n}\n\n/** Canonical JSON text of the protected claim set, without the domain prefix. */\nexport function deviceProofCanonicalJson(claims: DeviceProofProtectedClaims): string {\n return canonicalizeJson(deviceProofCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a device signs and a verifier reconstructs:\n * `byok-device-proof-v1\\n` followed by the canonical claim JSON, UTF-8 encoded.\n *\n * Frozen by `src/__tests__/golden/device-proof-v1.canonical.json`.\n */\nexport function deviceProofSigningInput(claims: DeviceProofProtectedClaims): Uint8Array {\n return new TextEncoder().encode(\n DEVICE_PROOF_DOMAIN_PREFIX + deviceProofCanonicalJson(claims),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Verify port\n// ---------------------------------------------------------------------------\n\nexport interface DeviceProofVerifyInput {\n readonly algorithm: DeviceProofAlgorithm;\n /** Raw public key, base64url — the JWK `x` encoding the device registry stores. */\n readonly publicKey: string;\n readonly signature: string;\n readonly signingInput: Uint8Array;\n}\n\n/**\n * Injected signature verification.\n *\n * Not a store port, so it has no tenant parameter: it answers a pure\n * cryptographic question about bytes. Deciding *which* key to check against is\n * the caller's tenant-scoped device-row lookup, and keeping that out of here is\n * what stops a verifier from becoming a second authority on device identity.\n */\nexport interface DeviceProofVerifier {\n verify(input: DeviceProofVerifyInput): Promise<boolean>;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Device assertion envelope, canonical signing bytes, and verifier\n * (plan `device-assertion-broker`, P3 ①-⑤).\n *\n * A device assertion is a short-lived, audience-scoped statement a *paired\n * device* makes about itself — \"this device, paired to this product against\n * this server, wants to talk to `<audience>` for the next two minutes\" — signed\n * with the same Ed25519 device identity key `attestation.ts`'s device proof\n * uses. A sibling CLI installed alongside the daemon presents one to the host's\n * cloud, which exchanges it for a product session. It is NOT a request-bound\n * proof (`attestation.ts`) and the two must never be interchangeable; see the\n * domain prefix below.\n *\n * Four decisions this file encodes, none of them re-litigable here:\n *\n * 1. **A custom JSON signing envelope, not JWS.** The domain prefix has to be\n * *inside* the signed bytes. JWS puts its type tag in a header that no\n * verifier is required to check, which is a fail-open shape: a token minted\n * for one purpose verifies for another as long as the key matches. So this\n * clones the mechanism `attestation.ts` already froze — RFC 8785-subset\n * canonicalization (`canonicalizeJson`, imported, never re-implemented) plus\n * a golden fixture pinning the exact bytes.\n * 2. **What the claims deliberately do NOT carry.** No `devicePublicKey`: a\n * verifier must resolve the key from its own device directory by `deviceId`,\n * or the envelope becomes self-authenticating. No caller identity: every\n * process under the same UID can reach the control socket, so a \"who asked\"\n * field would be synthesized authority, not evidence. No `keyId`: there is\n * no key-rotation story for this envelope yet, and a field nothing populates\n * honestly is a structure that invites a verifier to trust it.\n * 3. **`audience` is a single string, never an array.** A multi-audience token\n * forces every verifier to agree on the same containment rule; one string\n * compared with `===` cannot be got wrong.\n * 4. **The verifier cannot forget the revocation check.** {@link\n * verifyDeviceAssertion} takes `revoked` as a REQUIRED dependency, so a\n * caller that never looked the device row up does not compile. The daemon's\n * own local checks (see `@byok-sdk/client`'s `assertion.issue`) are only half\n * of revocation; the other half is this recheck at exchange time, and no\n * documentation may claim the daemon satisfies \"synchronous invalidation\"\n * on its own.\n *\n * Like `attestation.ts`, this module is crypto-free: signature verification is\n * an injected port (`DeviceAssertionVerifier`), because core must load on\n * Workers and `node:crypto`/WebCrypto disagree about key handling.\n */\nimport { z } from 'zod';\nimport { canonicalizeJson, type JsonObject, type JsonValue } from './attestation';\nimport { ByokCoreError } from './errors';\nimport type { DevicePrincipal } from './principals';\nimport { isTenantId, type TenantId } from './tenant';\n\n/** Envelope schema id, self-consistent with the domain prefix below. */\nexport const DEVICE_ASSERTION_SCHEMA_ID = 'byok-device-assertion-v1';\n\n/**\n * Domain separation prefix, prepended to the canonical claim bytes before\n * signing.\n *\n * Must remain mutually NON-PREFIX with the other three things this same Ed25519\n * device key signs — `byok-nonce-v1\\n` (challenge/token renewal, see\n * `@byok-sdk/client`'s `device-keys.ts`), `byok-device-proof-v1\\n`\n * (`attestation.ts`), and `byok-task-assertion-v1\\n` ({@link\n * TASK_ASSERTION_DOMAIN_PREFIX}) — so no signature over one domain can ever be\n * reinterpreted as a signature over another.\n * `packages/core/src/__tests__/device-assertion.test.ts` asserts the property\n * across the three core-owned prefixes and\n * `packages/client/src/__tests__/device-assertion-broker.test.ts` across all\n * four; those assertions are the falsifier for this whole design, not a nicety.\n */\nexport const DEVICE_ASSERTION_DOMAIN_PREFIX = 'byok-device-assertion-v1\\n';\n\nexport const DEVICE_ASSERTION_VERSION = 1;\n\n/**\n * Envelope schema id of the task-scoped assertion (contract §8.1), kept beside\n * the device one so the two are read — and reviewed — together.\n */\nexport const TASK_ASSERTION_SCHEMA_ID = 'byok-task-assertion-v1';\n\n/**\n * Domain separation prefix for `byok-task-assertion-v1`.\n *\n * Joins the mutually NON-PREFIX set the ONE Ed25519 device key signs under:\n * `byok-nonce-v1\\n`, `byok-device-proof-v1\\n`,\n * `byok-device-assertion-v1\\n`, and this. Contract §8.1 requires the old and\n * new envelopes to be non-interchangeable, and domain separation is the half of\n * that which holds even when both envelopes parse: a device-lane signature can\n * never be reinterpreted as a task-lane one, because the signed bytes differ in\n * their first line. The four-way falsifier lives in\n * `packages/client/src/__tests__/device-assertion-broker.test.ts` (the only\n * suite that can import the real nonce domain); the three core-owned prefixes\n * are cross-checked in `packages/core/src/__tests__/device-assertion.test.ts`.\n */\nexport const TASK_ASSERTION_DOMAIN_PREFIX = 'byok-task-assertion-v1\\n';\n\nexport const TASK_ASSERTION_VERSION = 1;\n\n/** Signature algorithms this envelope version admits. */\nexport const DEVICE_ASSERTION_ALGORITHMS = ['ed25519'] as const;\nexport type DeviceAssertionAlgorithm = (typeof DEVICE_ASSERTION_ALGORITHMS)[number];\n\n/**\n * Default assertion lifetime. Short on purpose: the daemon keeps no `jti`\n * ledger (it is not on the verification path and could not stop a real replay\n * anyway), so a narrow expiry window plus a burn-on-use verifier is the whole\n * replay story.\n */\nexport const DEVICE_ASSERTION_DEFAULT_TTL_MS = 120_000;\n\n/**\n * Hard ceiling on the lifetime, enforced at BOTH ends: a daemon refuses to be\n * configured above it, and {@link verifyDeviceAssertion} refuses an envelope\n * whose own `issuedAt`→`expiresAt` span exceeds it regardless of who minted it.\n */\nexport const DEVICE_ASSERTION_MAX_TTL_MS = 300_000;\n\n/** Bound on the `audience` claim, in UTF-8 bytes — an allowlist entry is a short identifier, not a document. */\nexport const DEVICE_ASSERTION_AUDIENCE_MAX_BYTES = 256;\n\n/** base64url of 16 CSPRNG bytes (128 bits), unpadded. */\nconst JTI_PATTERN = /^[A-Za-z0-9_-]{22}$/;\n\n/** base64url of a raw 64-byte Ed25519 signature, unpadded. */\nconst SIGNATURE_PATTERN = /^[A-Za-z0-9_-]{86}$/;\n\nfunction utf8ByteLength(value: string): number {\n return new TextEncoder().encode(value).length;\n}\n\n/**\n * The one `audience` validator both envelope kinds parse through.\n *\n * Declared once rather than restated per schema: a second copy is a second\n * place the byte bound could be relaxed, and `byok-task-assertion-v1` inherits\n * the bound by construction rather than by a reviewer noticing.\n */\nconst ASSERTION_AUDIENCE = z\n .string()\n .min(1)\n .refine((value) => utf8ByteLength(value) <= DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, {\n message: `audience must be at most ${DEVICE_ASSERTION_AUDIENCE_MAX_BYTES} UTF-8 bytes`,\n });\n\n// ---------------------------------------------------------------------------\n// Claims\n// ---------------------------------------------------------------------------\n\n/**\n * The signed claim set. `strictObject` with every member REQUIRED: an optional\n * claim is a claim a verifier may or may not see, and this envelope is small\n * enough that there is no honest reason for one.\n *\n * `issuer` is the paired server's origin (scheme + host + port, normalized) —\n * it binds the assertion to the deployment the device is actually paired\n * against, so an assertion minted by a device paired to a staging server cannot\n * be presented to production.\n */\nexport const DeviceAssertionClaimsSchema = z.strictObject({\n version: z.literal(DEVICE_ASSERTION_VERSION),\n /** The paired server's origin, normalized (`new URL(serverUrl).origin`). */\n issuer: z.string().min(1),\n productId: z.string().min(1),\n /** The device row this assertion claims to be. A lookup key, never authority — the row is the authority. */\n deviceId: z.string().min(1),\n /** Exactly one audience, compared with `===` by every verifier. Never an array, never a prefix. */\n audience: ASSERTION_AUDIENCE,\n /** 128-bit CSPRNG token, base64url unpadded. The verifier burns it; the signer never reuses one. */\n jti: z.string().regex(JTI_PATTERN),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime(),\n});\n\nexport type DeviceAssertionClaims = z.infer<typeof DeviceAssertionClaimsSchema>;\n\nexport const DeviceAssertionEnvelopeV1Schema = z.strictObject({\n schema: z.literal(DEVICE_ASSERTION_SCHEMA_ID),\n algorithm: z.enum(DEVICE_ASSERTION_ALGORITHMS),\n protected: DeviceAssertionClaimsSchema,\n /** Raw 64-byte Ed25519 signature, base64url unpadded. */\n signature: z.string().regex(SIGNATURE_PATTERN),\n});\n\nexport type DeviceAssertionEnvelopeV1 = z.infer<typeof DeviceAssertionEnvelopeV1Schema>;\n\n/**\n * Parses an envelope fail-closed.\n *\n * @throws {ByokCoreError} code `assertion_envelope_invalid`.\n */\nexport function parseDeviceAssertionEnvelope(input: unknown): DeviceAssertionEnvelopeV1 {\n const result = DeviceAssertionEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'assertion_envelope_invalid',\n `Invalid device assertion envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field rather than by spreading the parsed object — the same\n * discipline `deviceProofCanonicalClaims` documents. Nothing here is optional,\n * so there is no absent-key decision to get wrong; the explicit projection is\n * what keeps it that way if a field is ever added.\n */\nexport function deviceAssertionCanonicalClaims(claims: DeviceAssertionClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n issuer: claims.issuer,\n productId: claims.productId,\n deviceId: claims.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n };\n return canonical;\n}\n\n/** Canonical JSON text of the claim set, without the domain prefix. */\nexport function deviceAssertionCanonicalJson(claims: DeviceAssertionClaims): string {\n return canonicalizeJson(deviceAssertionCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a device signs and a verifier reconstructs:\n * `byok-device-assertion-v1\\n` followed by the canonical claim JSON, UTF-8\n * encoded.\n *\n * Frozen by `src/__tests__/golden/device-assertion-v1.canonical.json`.\n */\nexport function deviceAssertionSigningInput(claims: DeviceAssertionClaims): Uint8Array {\n return new TextEncoder().encode(\n DEVICE_ASSERTION_DOMAIN_PREFIX + deviceAssertionCanonicalJson(claims),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Verify\n// ---------------------------------------------------------------------------\n\nexport interface DeviceAssertionVerifyInput {\n readonly algorithm: DeviceAssertionAlgorithm;\n /** Raw public key, base64url — the JWK `x` encoding the device registry stores. */\n readonly publicKey: string;\n readonly signature: string;\n readonly signingInput: Uint8Array;\n}\n\n/**\n * Injected signature verification, for the same reason `DeviceProofVerifier`\n * exists: core is Node-free and Workers-safe, so it answers no cryptographic\n * question itself. Kept separate from `DeviceProofVerifier` even though the\n * shapes coincide — one composition object satisfies both — because this file's\n * entire purpose is that the two domains never become interchangeable, and a\n * shared type is the first step toward a shared code path.\n */\nexport interface DeviceAssertionVerifier {\n verify(input: DeviceAssertionVerifyInput): Promise<boolean>;\n}\n\n/**\n * The device-row fields a verification reads — the verifier's OWN directory\n * row, resolved by `deviceId`, never anything the envelope carried.\n *\n * Both fields together, from one lookup, are what make forgetting impossible:\n * the caller cannot obtain `publicKeyJwkX` without also obtaining the current\n * `revoked` state, because they arrive as one object from one call.\n */\nexport interface DeviceAssertionDeviceRow {\n /** JWK `x` of the device's registered Ed25519 public key. The ONLY key a signature is ever checked against. */\n readonly publicKeyJwkX: string;\n /** The row's CURRENT revocation state, read in the same lookup as the key. */\n readonly revoked: boolean;\n}\n\n/**\n * Everything a verification needs that is NOT in the envelope.\n *\n * The device row is supplied through a LOOKUP PORT, not as a pre-fetched\n * value, and that is the whole point (this is the faithful clone of\n * `DeviceProofVerifier`'s \"core is never a second authority on device\n * identity\" shape). `verifyDeviceAssertion` reads `deviceId` from the parsed\n * claims and calls `lookupDevice(deviceId)` ITSELF, so:\n *\n * - There is no way to invoke a verification without providing the means to\n * look the current row up — \"I forgot to check revocation\" cannot be\n * expressed, because the function does the lookup, not the caller.\n * - Both the public key AND the revocation state come from that one row, so a\n * caller cannot pass a key while claiming `revoked: false` from thin air.\n * - The `deviceId` handed to `lookupDevice` is the claimed one; the row it\n * returns is authority. A device asserting an identity it is not is caught\n * by the lookup missing, or by the returned row's key failing the signature.\n */\nexport interface DeviceAssertionVerifyDeps {\n readonly verifier: DeviceAssertionVerifier;\n /**\n * Resolve the verifier's own device row by the claimed `deviceId`.\n * `undefined` for an unknown device. Sync or async; awaited either way.\n */\n readonly lookupDevice: (\n deviceId: string,\n ) => Promise<DeviceAssertionDeviceRow | undefined> | DeviceAssertionDeviceRow | undefined;\n /** Injected instant — core never reads a wall clock (`stores.ts`'s `Clock`). */\n readonly now: Date;\n /** Bound on `issuedAt`→`expiresAt`. Defaults to (and may never exceed) {@link DEVICE_ASSERTION_MAX_TTL_MS}. */\n readonly maxLifetimeMs?: number;\n}\n\nfunction parseInstant(value: string): number | undefined {\n const parsed = Date.parse(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Raw Ed25519 public key as a JWK `x`: 32 bytes, base64url unpadded — exactly\n * 43 characters. The envelope's `algorithm` is a closed `ed25519`, so the row's\n * key must be an Ed25519 key of this exact shape.\n */\nconst EDDSA_JWK_X_PATTERN = /^[A-Za-z0-9_-]{43}$/;\n\n/**\n * codex round-2 F2: strict runtime validation of a looked-up device row, since\n * `lookupDevice` is a caller-supplied port whose return value TypeScript cannot\n * enforce at runtime. Fails closed on any shape that isn't exactly a usable row:\n *\n * - `revoked` must be the literal boolean `false`. A missing, `undefined`,\n * truthy, or non-boolean `revoked` is a malformed row — and a missing\n * `revoked` reading as \"not revoked\" (`undefined` is falsey) is precisely the\n * fail-open this guard closes: a revoked device must never slip through on a\n * row shape the caller got wrong.\n * - `publicKeyJwkX` must be a present, well-formed Ed25519 JWK `x`. A missing or\n * malformed key is rejected here, before any crypto — so a bad key can never\n * reach (and throw inside) the verifier port either.\n */\nfunction isUsableDeviceRow(row: unknown): row is DeviceAssertionDeviceRow {\n if (row === null || typeof row !== 'object') return false;\n if ((row as { revoked?: unknown }).revoked !== false) return false;\n const key = (row as { publicKeyJwkX?: unknown }).publicKeyJwkX;\n return typeof key === 'string' && EDDSA_JWK_X_PATTERN.test(key);\n}\n\n/**\n * Resolve the effective lifetime ceiling, or `undefined` when the caller asked\n * for one this module refuses to honour.\n *\n * Both envelope kinds resolve it here so `byok-task-assertion-v1` cannot be\n * given a longer window than `byok-device-assertion-v1` — contract §8.1 says\n * the task lane inherits the SDK's existing maximum TTL rather than deriving\n * its own from an unpredictable task lifetime.\n */\nfunction resolveMaxLifetimeMs(requested: number | undefined): number | undefined {\n const maxLifetimeMs = requested ?? DEVICE_ASSERTION_MAX_TTL_MS;\n if (\n !Number.isSafeInteger(maxLifetimeMs) ||\n maxLifetimeMs <= 0 ||\n maxLifetimeMs > DEVICE_ASSERTION_MAX_TTL_MS\n ) {\n return undefined;\n }\n return maxLifetimeMs;\n}\n\n/**\n * The time-window rule, shared by both envelope kinds so there is exactly one\n * place it can be widened: a parseable `[issuedAt, expiresAt)` half-open\n * interval, no clock-skew allowance, and a span no longer than the ceiling.\n */\nfunction assertionWindowAdmits(\n claims: { readonly issuedAt: string; readonly expiresAt: string },\n now: Date,\n maxLifetimeMs: number,\n): boolean {\n const issuedAt = parseInstant(claims.issuedAt);\n const expiresAt = parseInstant(claims.expiresAt);\n if (issuedAt === undefined || expiresAt === undefined) return false;\n if (expiresAt <= issuedAt) return false;\n if (expiresAt - issuedAt > maxLifetimeMs) return false;\n\n const instant = now.getTime();\n if (!Number.isFinite(instant)) return false;\n return instant >= issuedAt && instant < expiresAt;\n}\n\n/**\n * Verifies an assertion and returns its claims, or `undefined`.\n *\n * Every rejected state collapses to `undefined` — malformed input, an unknown\n * or revoked device, an expired or over-long window, a bad signature — so a\n * route has one response for all of them and cannot accidentally leak which\n * check failed. That is the same shape `authenticateDeviceProof`\n * (`@byok-sdk/cloud`) already uses.\n *\n * The row lookup and both authority reads (key, revocation) happen INSIDE this\n * function — see {@link DeviceAssertionVerifyDeps}. What the caller MUST still\n * do afterward, and this cannot: assert `claims.audience` equals the audience\n * it actually serves, assert `claims.issuer`/`claims.productId` match its own\n * deployment, and BURN `claims.jti` so the assertion cannot be presented\n * twice. The daemon keeps no `jti` ledger; single use is entirely the\n * verifier's job.\n */\nexport async function verifyDeviceAssertion(\n input: unknown,\n deps: DeviceAssertionVerifyDeps,\n): Promise<DeviceAssertionClaims | undefined> {\n const maxLifetimeMs = resolveMaxLifetimeMs(deps.maxLifetimeMs);\n if (maxLifetimeMs === undefined) return undefined;\n\n let envelope: DeviceAssertionEnvelopeV1;\n try {\n envelope = parseDeviceAssertionEnvelope(input);\n } catch {\n return undefined;\n }\n const claims = envelope.protected;\n\n // Resolve the row by the CLAIMED deviceId, then read authority from the row.\n // An unknown device, a revoked one, and a MALFORMED one all stop here, before\n // any crypto is done on the claimed identity's behalf. The row is validated\n // strictly (codex round-2 F2): `revoked` must be exactly `false` and the key\n // must be a well-formed Ed25519 JWK `x` — a missing `revoked` never reads as\n // \"not revoked\", and a missing/malformed key never reaches the verifier.\n const row = await deps.lookupDevice(claims.deviceId);\n if (!isUsableDeviceRow(row)) return undefined;\n\n // No clock-skew allowance: this envelope's whole safety margin is its short\n // window, and a tolerance knob is just that window quietly widened. A\n // deployment whose clocks disagree by minutes has a clock problem to fix, not\n // an assertion lifetime to extend. Validity is a half-open interval\n // `[issuedAt, expiresAt)` — at the exact `expiresAt` instant the assertion is\n // already expired. See {@link assertionWindowAdmits}, the one place that rule\n // is written down for both envelope kinds.\n if (!assertionWindowAdmits(claims, deps.now, maxLifetimeMs)) return undefined;\n\n const verified = await deps.verifier.verify({\n algorithm: envelope.algorithm,\n // The row's key, never an envelope-supplied one.\n publicKey: row.publicKeyJwkX,\n signature: envelope.signature,\n signingInput: deviceAssertionSigningInput(claims),\n });\n if (!verified) return undefined;\n\n return claims;\n}\n\n// ---------------------------------------------------------------------------\n// Authenticate + consume once\n// ---------------------------------------------------------------------------\n\n/** The verifier's complete current row. Claims remain lookup keys, never authority. */\nexport interface DeviceAssertionAuthorityRow extends DeviceAssertionDeviceRow {\n readonly tenantId: TenantId;\n readonly productId: string;\n readonly deviceId: string;\n}\n\n/** Trusted deployment values the host compares with exact string equality. */\nexport interface DeviceAssertionExpectedBinding {\n readonly issuer: string;\n readonly productId: string;\n readonly audience: string;\n}\n\n/**\n * The envelope kinds that share one replay authority.\n *\n * A closed union with no default: contract §8.2(2) requires the replay key to\n * carry an envelope-kind discriminator so the same `jti` presented as a device\n * assertion and as a task assertion occupies two key slots and neither lane can\n * burn the other's. A defaulted or optional field would reintroduce exactly the\n * collision the discriminator exists to prevent, so every caller states its\n * lane and a caller that forgets does not compile.\n */\nexport type DeviceAssertionReplaySchemaId =\n | typeof DEVICE_ASSERTION_SCHEMA_ID\n | typeof TASK_ASSERTION_SCHEMA_ID;\n\n/** One replay key. Every field is derived from verified claims/current authority. */\nexport interface DeviceAssertionReplayConsumeInput {\n /** Which signed envelope kind produced this key. Required; never inferred, never defaulted. */\n readonly schema: DeviceAssertionReplaySchemaId;\n readonly tenantId: TenantId;\n readonly issuer: string;\n readonly productId: string;\n readonly deviceId: string;\n readonly audience: string;\n readonly jti: string;\n readonly expiresAt: string;\n}\n\n/**\n * Atomic single-use authority. `true` means this caller inserted the key;\n * `false` means it was already consumed. Operational failures throw and must\n * never be translated into authenticated success.\n */\nexport interface DeviceAssertionReplayAuthority {\n collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult>;\n consume(input: DeviceAssertionReplayConsumeInput): Promise<boolean>;\n}\n\nexport interface AuthenticateDeviceAssertionDeps {\n readonly verifier: DeviceAssertionVerifier;\n readonly lookupDevice: (\n deviceId: string,\n ) => Promise<DeviceAssertionAuthorityRow | undefined> | DeviceAssertionAuthorityRow | undefined;\n readonly replay: DeviceAssertionReplayAuthority;\n readonly expected: DeviceAssertionExpectedBinding;\n readonly now: Date;\n readonly maxLifetimeMs?: number;\n}\n\n/**\n * What both lanes' results carry: the current-authority principal plus the\n * audit fields of the credential that was spent. Never a name a caller holds —\n * a value is always one lane or the other, and {@link AuthenticatedAssertion}\n * is the union to accept when a consumer genuinely serves both.\n */\ninterface AuthenticatedAssertionBase {\n readonly device: DevicePrincipal;\n readonly issuer: string;\n readonly audience: string;\n readonly jti: string;\n readonly issuedAt: string;\n readonly expiresAt: string;\n}\n\n/**\n * Audit-safe result of a consumed DEVICE assertion; no credential or signature\n * is retained.\n *\n * `lane` is the discriminator contract §8.1 requires the result to carry. The\n * two lanes have zero interchange, so a consumer that serves only one of them\n * has to be able to say which — and \"which fields are present\" is not that\n * statement: a structural check drifts the moment either claim set grows, and\n * an extension relationship would make a task credential satisfy every\n * device-lane type check for free.\n */\nexport interface AuthenticatedDeviceAssertion extends AuthenticatedAssertionBase {\n readonly lane: 'device';\n}\n\nfunction isNonEmptyExactString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0 && value.trim() === value;\n}\n\nfunction isAuthorityRow(row: unknown, requestedDeviceId: string): row is DeviceAssertionAuthorityRow {\n if (row === null || typeof row !== 'object') return false;\n const candidate = row as Partial<DeviceAssertionAuthorityRow>;\n return (\n isTenantId(candidate.tenantId) &&\n isNonEmptyExactString(candidate.productId) &&\n candidate.deviceId === requestedDeviceId\n );\n}\n\n/**\n * Authenticate one device assertion and atomically consume its JTI.\n *\n * All invalid authentication states collapse to `undefined`. Replay-store\n * operational failures reject the promise, allowing a host to return an\n * availability error without ever degrading to signature-only acceptance.\n */\nexport async function authenticateDeviceAssertion(\n input: unknown,\n deps: AuthenticateDeviceAssertionDeps,\n): Promise<AuthenticatedDeviceAssertion | undefined> {\n if (\n !isNonEmptyExactString(deps.expected.issuer) ||\n !isNonEmptyExactString(deps.expected.productId) ||\n !isNonEmptyExactString(deps.expected.audience) ||\n utf8ByteLength(deps.expected.audience) > DEVICE_ASSERTION_AUDIENCE_MAX_BYTES\n ) {\n return undefined;\n }\n\n let authorityRow: DeviceAssertionAuthorityRow | undefined;\n const claims = await verifyDeviceAssertion(input, {\n verifier: deps.verifier,\n lookupDevice: async (deviceId) => {\n const row = await deps.lookupDevice(deviceId);\n if (!isAuthorityRow(row, deviceId)) return undefined;\n authorityRow = row;\n return { publicKeyJwkX: row.publicKeyJwkX, revoked: row.revoked };\n },\n now: deps.now,\n ...(deps.maxLifetimeMs === undefined ? {} : { maxLifetimeMs: deps.maxLifetimeMs }),\n });\n if (claims === undefined || authorityRow === undefined) return undefined;\n\n if (\n claims.issuer !== deps.expected.issuer ||\n claims.productId !== deps.expected.productId ||\n claims.audience !== deps.expected.audience ||\n authorityRow.productId !== deps.expected.productId ||\n authorityRow.deviceId !== claims.deviceId\n ) {\n return undefined;\n }\n\n const consumed = await deps.replay.consume({\n schema: DEVICE_ASSERTION_SCHEMA_ID,\n tenantId: authorityRow.tenantId,\n issuer: claims.issuer,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n expiresAt: claims.expiresAt,\n });\n if (!consumed) return undefined;\n\n return {\n lane: 'device',\n device: {\n kind: 'device',\n tenantId: authorityRow.tenantId,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n },\n issuer: claims.issuer,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Task assertion (`byok-task-assertion-v1`) — contract §8.1 / §8.2(2)\n// ---------------------------------------------------------------------------\n\n/**\n * The task-scoped assertion: a separate envelope, NOT a device assertion with\n * extra claims.\n *\n * Contract §8.1 fixes the property this section exists to hold: the old and new\n * envelopes are not interchangeable in either direction. Three independent\n * mechanisms carry it, and none of them is \"the verifier remembers to check\":\n *\n * 1. **Different signed bytes.** {@link TASK_ASSERTION_DOMAIN_PREFIX} is\n * non-prefix with every other domain this device key signs under, so a\n * signature made in one lane cannot be reinterpreted in another even if the\n * claim sets were made to coincide.\n * 2. **Different strict schemas.** `schema` is a literal and `protected` is a\n * `strictObject`, so a device envelope fails\n * {@link parseTaskAssertionEnvelope} on its missing `taskId`/`agentRef`/\n * `toolsetId` and a task envelope fails\n * {@link parseDeviceAssertionEnvelope} on those same claims being unknown.\n * 3. **Different replay keys.** {@link DeviceAssertionReplayConsumeInput}\n * carries a required `schema` segment (§8.2(2)), so the two lanes' ledgers\n * are distinguishable and neither can burn the other's `jti`.\n *\n * What is deliberately NOT duplicated: `jti`/signature encodings, the audience\n * byte bound, {@link DEVICE_ASSERTION_MAX_TTL_MS}, the window rule and the\n * device-row rule are the SAME validators the device lane uses, referenced not\n * copied. Contract §8.1: the task lane inherits the SDK's existing limits and\n * does not define a second, looser set.\n *\n * The claim set carries no caller identity for the reason stated at the top of\n * this file — under one UID every process can reach the control socket, so a\n * self-reported \"who asked\" is synthesized authority. The task/AgentRef binding\n * here is authority precisely because the daemon signs it after checking its\n * own local registry, not because a caller sent it.\n */\n\n/** Bound on each AgentRef scalar, in UTF-8 bytes. Mirrors `AGENT_REF_MAX_BYTES` in `@byok-sdk/protocol`. */\nexport const TASK_ASSERTION_AGENT_REF_MAX_BYTES = 160;\n\n/** Bound on `toolsetId`. Mirrors the `ToolsetIdSchema` bound in `@byok-sdk/protocol`. */\nexport const TASK_ASSERTION_TOOLSET_ID_MAX_LENGTH = 128;\n\n/**\n * AgentRef scalar, restated from the SDK's authoritative `AgentRefSchema`\n * (`@byok-sdk/protocol`'s `messages.ts`) rather than imported.\n *\n * Core may not grow an edge to protocol — the §12.1 invariant that\n * `packages/core/src/__tests__/constraints.test.ts` enforces on shipped source\n * AND tests — so this lane cannot import the authority it must not weaken. The\n * falsifier for the restatement is therefore a BEHAVIOURAL drift test in the\n * client suite (`device-assertion-broker.test.ts`), which imports the real\n * `AgentRefSchema`/`ToolsetIdSchema` alongside these and asserts the two agree\n * on every candidate. A weakened copy here turns that suite red; it does not\n * quietly widen the task lane.\n */\nconst AGENT_REF_VALUE = z\n .string()\n .min(1)\n .max(TASK_ASSERTION_AGENT_REF_MAX_BYTES)\n .refine((value) => utf8ByteLength(value) <= TASK_ASSERTION_AGENT_REF_MAX_BYTES, {\n message: `AgentRef values must not exceed ${TASK_ASSERTION_AGENT_REF_MAX_BYTES} UTF-8 bytes`,\n })\n .regex(/^[^\\u0000-\\u001f\\u007f\\r\\n]+$/u, 'AgentRef values must not contain control characters');\n\nconst WINDOWS_RESERVED_AGENT_SEGMENT = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\..*)?$/iu;\n\n/** The frozen offer's Agent identity. Same shape and same rules as the SDK's `AgentRefSchema`. */\nexport const TaskAssertionAgentRefSchema = z\n .object({\n agentId: AGENT_REF_VALUE.regex(/^[^\\\\/:<>\"|?*]+$/u, 'agentId must be one portable pathname segment')\n .refine((value) => value !== '.' && value !== '..', 'agentId must not be a dot segment')\n .refine(\n (value) => !/[. ]$/u.test(value) && !WINDOWS_RESERVED_AGENT_SEGMENT.test(value),\n 'agentId must be a portable Windows-safe pathname segment',\n ),\n /**\n * From the FROZEN offer. Contract §8.1 forbids substituting the current\n * revision read from a working directory's `profile.json`; this module\n * cannot enforce that (it never reads a file) — the signer's contract does.\n */\n profileRevision: AGENT_REF_VALUE,\n })\n .strict();\n\nexport type TaskAssertionAgentRef = z.infer<typeof TaskAssertionAgentRefSchema>;\n\n/** Logical, host-owned toolset id. Restated from `@byok-sdk/protocol`'s `ToolsetIdSchema`; see {@link TaskAssertionAgentRefSchema}. */\nconst TOOLSET_ID_VALUE = z\n .string()\n .min(1)\n .max(TASK_ASSERTION_TOOLSET_ID_MAX_LENGTH)\n .regex(/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/u, 'toolset ids must be lowercase logical identifiers');\n\n/**\n * The wire's task id shape: the same `z.string().min(1)` the protocol envelope's\n * `task_id` routing key is built from. Contract §8.1 makes `taskId` the sole\n * execution locator, so this lane must accept exactly what the wire routes —\n * neither inventing a narrower bound nor admitting an empty one.\n */\nconst TASK_ID_VALUE = z.string().min(1);\n\n/**\n * The signed task claim set: the device claim set plus the three bindings that\n * make the assertion task-scoped, every member required for the same reason the\n * device claims are.\n */\nexport const TaskAssertionClaimsSchema = z.strictObject({\n version: z.literal(TASK_ASSERTION_VERSION),\n /** The paired server's origin, normalized (`new URL(serverUrl).origin`). */\n issuer: z.string().min(1),\n productId: z.string().min(1),\n /** The device row this assertion claims to be. A lookup key, never authority. */\n deviceId: z.string().min(1),\n /** Exactly one audience, compared with `===`. Participates in the replay key (§8.2(2)). */\n audience: ASSERTION_AUDIENCE,\n /** Same 128-bit CSPRNG token shape the device lane uses; burned once per `schema` segment. */\n jti: z.string().regex(JTI_PATTERN),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime(),\n /** The only execution locator (§8.1). No attemptId is minted beside it. */\n taskId: TASK_ID_VALUE,\n /** The frozen offer's Agent identity, at the SDK's full AgentRef strength. */\n agentRef: TaskAssertionAgentRefSchema,\n /** The frozen toolset this invocation belongs to (the wire's `toolset` field). */\n toolsetId: TOOLSET_ID_VALUE,\n});\n\nexport type TaskAssertionClaims = z.infer<typeof TaskAssertionClaimsSchema>;\n\nexport const TaskAssertionEnvelopeV1Schema = z.strictObject({\n schema: z.literal(TASK_ASSERTION_SCHEMA_ID),\n algorithm: z.enum(DEVICE_ASSERTION_ALGORITHMS),\n protected: TaskAssertionClaimsSchema,\n /** Raw 64-byte Ed25519 signature, base64url unpadded — the device lane's encoding, unchanged. */\n signature: z.string().regex(SIGNATURE_PATTERN),\n});\n\nexport type TaskAssertionEnvelopeV1 = z.infer<typeof TaskAssertionEnvelopeV1Schema>;\n\n/**\n * Parses a task envelope fail-closed. A device assertion is not a degraded task\n * assertion and is rejected here, not tolerated (§8.1: task lane zero fallback).\n *\n * @throws {ByokCoreError} code `assertion_envelope_invalid`.\n */\nexport function parseTaskAssertionEnvelope(input: unknown): TaskAssertionEnvelopeV1 {\n const result = TaskAssertionEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'assertion_envelope_invalid',\n `Invalid task assertion envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects task claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field, like the device projection, and covering EVERY claim —\n * contract §8.1 requires the canonical projection to include all added claims,\n * so an unsigned `taskId`, `agentRef` or `toolsetId` would be a claim a verifier\n * reads but no signature covers.\n */\nexport function taskAssertionCanonicalClaims(claims: TaskAssertionClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n issuer: claims.issuer,\n productId: claims.productId,\n deviceId: claims.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n taskId: claims.taskId,\n agentRef: {\n agentId: claims.agentRef.agentId,\n profileRevision: claims.agentRef.profileRevision,\n },\n toolsetId: claims.toolsetId,\n };\n return canonical;\n}\n\n/** Canonical JSON text of the task claim set, without the domain prefix. */\nexport function taskAssertionCanonicalJson(claims: TaskAssertionClaims): string {\n return canonicalizeJson(taskAssertionCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a daemon signs and a verifier reconstructs:\n * `byok-task-assertion-v1\\n` followed by the canonical claim JSON, UTF-8\n * encoded.\n *\n * Frozen by `src/__tests__/golden/task-assertion-v1.canonical.json`.\n */\nexport function taskAssertionSigningInput(claims: TaskAssertionClaims): Uint8Array {\n return new TextEncoder().encode(\n TASK_ASSERTION_DOMAIN_PREFIX + taskAssertionCanonicalJson(claims),\n );\n}\n\n/**\n * Verifies a task assertion and returns its claims, or `undefined`.\n *\n * The twin of {@link verifyDeviceAssertion}, with the same\n * collapse-to-`undefined` discipline, the same injected row lookup, and the\n * same window and ceiling rules ({@link assertionWindowAdmits},\n * {@link resolveMaxLifetimeMs}) — and a schema this function will not widen: a\n * `byok-device-assertion-v1` envelope is rejected at the parse step.\n *\n * What the caller MUST still do, exactly as in the device lane: compare\n * `issuer`/`productId`/`audience` against its own deployment, burn the `jti`\n * under this envelope's `schema` segment, and check that `taskId`/`agentRef`/\n * `toolsetId` belong to the frozen offer (§8.2(2)) — the last of which is Host\n * authority that core cannot hold.\n */\nexport async function verifyTaskAssertion(\n input: unknown,\n deps: DeviceAssertionVerifyDeps,\n): Promise<TaskAssertionClaims | undefined> {\n const maxLifetimeMs = resolveMaxLifetimeMs(deps.maxLifetimeMs);\n if (maxLifetimeMs === undefined) return undefined;\n\n let envelope: TaskAssertionEnvelopeV1;\n try {\n envelope = parseTaskAssertionEnvelope(input);\n } catch {\n return undefined;\n }\n const claims = envelope.protected;\n\n const row = await deps.lookupDevice(claims.deviceId);\n if (!isUsableDeviceRow(row)) return undefined;\n\n if (!assertionWindowAdmits(claims, deps.now, maxLifetimeMs)) return undefined;\n\n const verified = await deps.verifier.verify({\n algorithm: envelope.algorithm,\n publicKey: row.publicKeyJwkX,\n signature: envelope.signature,\n signingInput: taskAssertionSigningInput(claims),\n });\n if (!verified) return undefined;\n\n return claims;\n}\n\n/**\n * Audit-safe result of a consumed TASK assertion; no credential or signature is\n * retained.\n *\n * Deliberately NOT an extension of {@link AuthenticatedDeviceAssertion}. It was\n * one, and that was the same mistake in the type system that §8.1 forbids on\n * the wire: an extension is assignable to the thing it extends, so every\n * consumer written for device authority would have accepted a task credential\n * silently, with no fallback ever written down. The two results share\n * {@link AuthenticatedAssertionBase} and differ in `lane`, so a consumer that\n * must accept exactly one of them compares one field, and a consumer that must\n * accept either says so with {@link AuthenticatedAssertion}.\n */\nexport interface AuthenticatedTaskAssertion extends AuthenticatedAssertionBase {\n readonly lane: 'task';\n readonly taskId: string;\n readonly agentRef: TaskAssertionAgentRef;\n readonly toolsetId: string;\n}\n\n/**\n * Either lane's result, discriminated by `lane`.\n *\n * For the consumer that genuinely serves both (an audit projection, a ledger\n * writer). A consumer that serves ONE lane must name that lane's type instead —\n * this union exists so \"both\" is stated on purpose, not reached by accident.\n */\nexport type AuthenticatedAssertion = AuthenticatedDeviceAssertion | AuthenticatedTaskAssertion;\n\n/**\n * Authenticate one task assertion and atomically consume its JTI under the\n * `byok-task-assertion-v1` replay segment.\n *\n * Identical in shape and failure discipline to\n * {@link authenticateDeviceAssertion}: every invalid state collapses to\n * `undefined`, and a replay-store operational failure REJECTS rather than\n * degrading to signature-only acceptance (§8.2(2): an unavailable replay store\n * fails, it does not downgrade authentication).\n *\n * Consumption is the last step, after every binding comparison, so a rejected\n * assertion never burns a key — the \"reject before side effects\" ordering AC11\n * requires. The frozen-offer check (`taskId`/`agentRef`/`toolsetId` belong to\n * this Execution) is deliberately NOT here: that authority lives in the Host,\n * and a core function that accepted it as an argument would be inviting a\n * caller to synthesize it.\n */\nexport async function authenticateTaskAssertion(\n input: unknown,\n deps: AuthenticateDeviceAssertionDeps,\n): Promise<AuthenticatedTaskAssertion | undefined> {\n if (\n !isNonEmptyExactString(deps.expected.issuer) ||\n !isNonEmptyExactString(deps.expected.productId) ||\n !isNonEmptyExactString(deps.expected.audience) ||\n utf8ByteLength(deps.expected.audience) > DEVICE_ASSERTION_AUDIENCE_MAX_BYTES\n ) {\n return undefined;\n }\n\n let authorityRow: DeviceAssertionAuthorityRow | undefined;\n const claims = await verifyTaskAssertion(input, {\n verifier: deps.verifier,\n lookupDevice: async (deviceId) => {\n const row = await deps.lookupDevice(deviceId);\n if (!isAuthorityRow(row, deviceId)) return undefined;\n authorityRow = row;\n return { publicKeyJwkX: row.publicKeyJwkX, revoked: row.revoked };\n },\n now: deps.now,\n ...(deps.maxLifetimeMs === undefined ? {} : { maxLifetimeMs: deps.maxLifetimeMs }),\n });\n if (claims === undefined || authorityRow === undefined) return undefined;\n\n if (\n claims.issuer !== deps.expected.issuer ||\n claims.productId !== deps.expected.productId ||\n claims.audience !== deps.expected.audience ||\n authorityRow.productId !== deps.expected.productId ||\n authorityRow.deviceId !== claims.deviceId\n ) {\n return undefined;\n }\n\n const consumed = await deps.replay.consume({\n schema: TASK_ASSERTION_SCHEMA_ID,\n tenantId: authorityRow.tenantId,\n issuer: claims.issuer,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n expiresAt: claims.expiresAt,\n });\n if (!consumed) return undefined;\n\n return {\n lane: 'task',\n device: {\n kind: 'device',\n tenantId: authorityRow.tenantId,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n },\n issuer: claims.issuer,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n taskId: claims.taskId,\n agentRef: claims.agentRef,\n toolsetId: claims.toolsetId,\n };\n}\n","/**\n * The WebCrypto surface core relies on, declared structurally so core's\n * published types need neither the DOM lib nor Node's types, and resolved\n * from `globalThis.crypto.subtle` so the browser, Node, and Bun share one\n * code path. No `node:crypto`.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * A WebCrypto `CryptoKey`, declared structurally so core's published types\n * need neither the DOM lib nor Node's types. Every runtime's native\n * `CryptoKey` satisfies it.\n */\nexport interface WebCryptoKey {\n readonly type: string;\n readonly extractable: boolean;\n readonly algorithm: object;\n readonly usages: readonly string[];\n}\n\n/** The subset of `SubtleCrypto` this package calls, typed loosely on purpose (see {@link WebCryptoKey}). */\nexport interface WebCryptoSubtle {\n importKey(format: 'raw' | 'jwk', keyData: object, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n exportKey(format: 'raw', key: WebCryptoKey): Promise<ArrayBuffer>;\n generateKey(algorithm: object, extractable: boolean, usages: string[]): Promise<{ publicKey: WebCryptoKey; privateKey: WebCryptoKey }>;\n deriveBits(algorithm: object, baseKey: WebCryptoKey, length: number): Promise<ArrayBuffer>;\n sign(algorithm: string, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n encrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n decrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n digest(algorithm: string, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n}\n\n/** The WebCrypto subtle interface, or a closed-set failure when the runtime lacks it. */\nexport function webCryptoSubtle(): WebCryptoSubtle {\n const subtle = (globalThis as { crypto?: { subtle?: WebCryptoSubtle } }).crypto?.subtle;\n if (subtle === undefined) {\n throw new ByokCoreError('webcrypto_unavailable', 'WebCrypto subtle is unavailable in this runtime');\n }\n return subtle;\n}\n","/**\n * RFC 9180 HPKE, base mode, exactly one cipher suite:\n * `DHKEM(P-256, HKDF-SHA256) / HKDF-SHA256 / AES-128-GCM`\n * (KEM `0x0010`, KDF `0x0001`, AEAD `0x0001`).\n *\n * Why this module exists instead of a dependency: the same bytes must be\n * produced in a browser (the Web seals a provider key), in Node, and in a\n * Bun-compiled device daemon (which opens it). Every primitive used here —\n * P-256 ECDH, HMAC-SHA-256, AES-GCM, SHA-256, random key generation — is a\n * WebCrypto primitive all three runtimes ship, so the suite needs no\n * third-party code and no `node:` import (core must stay Workers/browser\n * safe). There is no algorithm negotiation: one suite, one mode, and anything\n * else is rejected by the envelope schema before this module is reached.\n *\n * Only one-shot seal/open is reachable from the package root. The key\n * schedule and sequence-numbered nonces are exported from this module for the\n * RFC 9180 Appendix A.3 conformance tests only; `index.ts` never re-exports a\n * reusable encryption context.\n *\n * Self-implemented HPKE: RFC vectors and an independent implementation\n * interoperate in the test suite, but passing vectors is not an audit. A\n * dedicated security review is required before a release is published.\n */\nimport { ByokCoreError } from './errors';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nconst KEM_ID = 0x0010;\nconst KDF_ID = 0x0001;\nconst AEAD_ID = 0x0001;\n\n/** Encoded P-256 public key and encapsulation length (uncompressed SEC1). */\nexport const HPKE_P256_PUBLIC_KEY_BYTES = 65;\nconst N_SECRET = 32;\nconst N_K = 16;\nconst N_N = 12;\nconst N_H = 32;\n/** AES-GCM authentication tag length. */\nexport const HPKE_AEAD_TAG_BYTES = 16;\n\nconst MODE_BASE = 0x00;\nconst HPKE_V1 = utf8('HPKE-v1');\nconst KEM_SUITE_ID = concat(utf8('KEM'), i2osp(KEM_ID, 2));\nconst HPKE_SUITE_ID = concat(utf8('HPKE'), i2osp(KEM_ID, 2), i2osp(KDF_ID, 2), i2osp(AEAD_ID, 2));\nconst EMPTY = new Uint8Array(0);\n/** HMAC pads its key with zeros to the block size, so an empty salt equals HashLen zeros. */\nconst ZERO_SALT = new Uint8Array(N_H);\n\ntype Bytes = Uint8Array<ArrayBuffer>;\n\nfunction utf8(value: string): Bytes {\n return new TextEncoder().encode(value) as Bytes;\n}\n\nfunction concat(...parts: readonly Uint8Array[]): Bytes {\n const length = parts.reduce((total, part) => total + part.byteLength, 0);\n const out = new Uint8Array(length);\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out;\n}\n\nfunction i2osp(value: number, length: number): Bytes {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer encoding requires a non-negative safe integer');\n }\n const out = new Uint8Array(length);\n let remaining = value;\n for (let index = length - 1; index >= 0; index -= 1) {\n out[index] = remaining % 256;\n remaining = Math.floor(remaining / 256);\n }\n if (remaining !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer does not fit the requested width');\n }\n return out;\n}\n\nfunction copy(bytes: Uint8Array): Bytes {\n return new Uint8Array(bytes) as Bytes;\n}\n\nasync function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, copy(data))) as Bytes;\n}\n\nasync function hkdfExpand(prk: Uint8Array, info: Uint8Array, length: number): Promise<Bytes> {\n if (length > 255 * N_H) {\n throw new ByokCoreError('sealed_secret_invalid', 'HKDF output length exceeds its limit');\n }\n const out = new Uint8Array(length);\n let previous: Uint8Array = EMPTY;\n let offset = 0;\n for (let counter = 1; offset < length; counter += 1) {\n previous = await hmacSha256(prk, concat(previous, info, Uint8Array.of(counter)));\n const take = Math.min(previous.byteLength, length - offset);\n out.set(previous.subarray(0, take), offset);\n offset += take;\n }\n return out as Bytes;\n}\n\nasync function labeledExtract(suiteId: Uint8Array, salt: Uint8Array, label: string, ikm: Uint8Array): Promise<Bytes> {\n return hmacSha256(salt.byteLength === 0 ? ZERO_SALT : salt, concat(HPKE_V1, suiteId, utf8(label), ikm));\n}\n\nasync function labeledExpand(\n suiteId: Uint8Array,\n prk: Uint8Array,\n label: string,\n info: Uint8Array,\n length: number,\n): Promise<Bytes> {\n return hkdfExpand(prk, concat(i2osp(length, 2), HPKE_V1, suiteId, utf8(label), info), length);\n}\n\n/**\n * Import an uncompressed SEC1 P-256 public key for ECDH.\n *\n * The length and `0x04` prefix are checked here; the on-curve check is the\n * WebCrypto import itself, which rejects a point that is not on P-256.\n */\nexport async function importP256PublicKey(raw: Uint8Array): Promise<WebCryptoKey> {\n if (raw.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || raw[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key must be a 65-byte uncompressed point');\n }\n try {\n return await webCryptoSubtle().importKey('raw', copy(raw), { name: 'ECDH', namedCurve: 'P-256' }, true, []);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key is not a valid curve point', { cause });\n }\n}\n\nasync function ecdhP256(privateKey: WebCryptoKey, publicKey: WebCryptoKey): Promise<Bytes> {\n const bits = await webCryptoSubtle().deriveBits({ name: 'ECDH', public: publicKey }, privateKey, N_SECRET * 8);\n return new Uint8Array(bits) as Bytes;\n}\n\nasync function extractAndExpand(dh: Uint8Array, kemContext: Uint8Array): Promise<Bytes> {\n const eaePrk = await labeledExtract(KEM_SUITE_ID, EMPTY, 'eae_prk', dh);\n return labeledExpand(KEM_SUITE_ID, eaePrk, 'shared_secret', kemContext, N_SECRET);\n}\n\n/** Key schedule output for base mode. Exported for the RFC 9180 conformance tests only. */\nexport interface HpkeBaseKeySchedule {\n readonly sharedSecret: Uint8Array;\n readonly key: Uint8Array;\n readonly baseNonce: Uint8Array;\n readonly exporterSecret: Uint8Array;\n}\n\nasync function keyScheduleBase(sharedSecret: Uint8Array, info: Uint8Array): Promise<HpkeBaseKeySchedule> {\n const pskIdHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'psk_id_hash', EMPTY);\n const infoHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'info_hash', info);\n const context = concat(Uint8Array.of(MODE_BASE), pskIdHash, infoHash);\n const secret = await labeledExtract(HPKE_SUITE_ID, sharedSecret, 'secret', EMPTY);\n return {\n sharedSecret,\n key: await labeledExpand(HPKE_SUITE_ID, secret, 'key', context, N_K),\n baseNonce: await labeledExpand(HPKE_SUITE_ID, secret, 'base_nonce', context, N_N),\n exporterSecret: await labeledExpand(HPKE_SUITE_ID, secret, 'exp', context, N_H),\n };\n}\n\n/** A caller-fixed ephemeral key pair. Conformance tests only; production always generates one. */\nexport interface HpkeEphemeralKeyPair {\n readonly privateKey: WebCryptoKey;\n readonly publicKey: Uint8Array;\n}\n\n/** `SetupBaseS`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseSender(\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n ephemeral?: HpkeEphemeralKeyPair,\n): Promise<{ enc: Uint8Array; schedule: HpkeBaseKeySchedule }> {\n const pkR = await importP256PublicKey(recipientPublicKey);\n let pair = ephemeral;\n if (pair === undefined) {\n const subtle = webCryptoSubtle();\n const generated = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveBits']);\n pair = {\n privateKey: generated.privateKey,\n publicKey: new Uint8Array(await subtle.exportKey('raw', generated.publicKey)),\n };\n }\n const enc = copy(pair.publicKey);\n const dh = await ecdhP256(pair.privateKey, pkR);\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return { enc, schedule: await keyScheduleBase(sharedSecret, info) };\n}\n\n/** `SetupBaseR`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseRecipient(\n enc: Uint8Array,\n recipientPrivateKey: WebCryptoKey,\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n): Promise<HpkeBaseKeySchedule> {\n if (recipientPublicKey.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || recipientPublicKey[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 recipient public key must be a 65-byte uncompressed point');\n }\n const pkE = await importP256PublicKey(enc);\n let dh: Bytes;\n try {\n dh = await ecdhP256(recipientPrivateKey, pkE);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE decapsulation failed', { cause });\n }\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return keyScheduleBase(sharedSecret, info);\n}\n\n/** `ComputeNonce(seq)`. Exported for the RFC 9180 conformance tests only. */\nexport function hpkeNonce(baseNonce: Uint8Array, sequence: number): Bytes {\n const seq = i2osp(sequence, N_N);\n const out = new Uint8Array(N_N);\n for (let index = 0; index < N_N; index += 1) out[index] = baseNonce[index]! ^ seq[index]!;\n return out as Bytes;\n}\n\nasync function aesGcmKey(key: Uint8Array, usage: 'encrypt' | 'decrypt'): Promise<WebCryptoKey> {\n return webCryptoSubtle().importKey('raw', copy(key), { name: 'AES-GCM' }, false, [usage]);\n}\n\n/** AEAD seal at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadSeal(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n plaintext: Uint8Array,\n): Promise<Bytes> {\n const ciphertext = await webCryptoSubtle().encrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'encrypt'),\n copy(plaintext),\n );\n return new Uint8Array(ciphertext) as Bytes;\n}\n\n/** AEAD open at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadOpen(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n ciphertext: Uint8Array,\n): Promise<Bytes> {\n if (ciphertext.byteLength < HPKE_AEAD_TAG_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE ciphertext is shorter than its authentication tag');\n }\n try {\n const plaintext = await webCryptoSubtle().decrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'decrypt'),\n copy(ciphertext),\n );\n return new Uint8Array(plaintext) as Bytes;\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE ciphertext failed authentication', { cause });\n }\n}\n\n/** One-shot `SealBase`: a fresh ephemeral key, sequence 0, never reused. */\nexport async function hpkeSealBase(input: {\n readonly recipientPublicKey: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly plaintext: Uint8Array;\n}): Promise<{ enc: Uint8Array; ciphertext: Uint8Array }> {\n const { enc, schedule } = await setupBaseSender(input.recipientPublicKey, input.info);\n return { enc, ciphertext: await hpkeAeadSeal(schedule, 0, input.aad, input.plaintext) };\n}\n\n/** One-shot `OpenBase`, sequence 0. */\nexport async function hpkeOpenBase(input: {\n readonly recipientPrivateKey: WebCryptoKey;\n readonly recipientPublicKey: Uint8Array;\n readonly enc: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly ciphertext: Uint8Array;\n}): Promise<Uint8Array> {\n const schedule = await setupBaseRecipient(input.enc, input.recipientPrivateKey, input.recipientPublicKey, input.info);\n return hpkeAeadOpen(schedule, 0, input.aad, input.ciphertext);\n}\n","/**\n * A zod parse that never throws.\n *\n * `safeParse` returns a failure for invalid data, but it does not catch an\n * error that a getter or a proxy trap throws while zod reads the value, and a\n * revoked proxy throws on any read. A receiver that promises a typed result\n * for hostile input, or a typed error for bad caller input, parses through\n * this. Wire input from `JSON.parse` cannot hold getters or proxies; this\n * closes the same gap for in-process callers.\n */\nimport type { z } from 'zod';\n\nexport type TotalParseResult<T> =\n | { readonly success: true; readonly data: T }\n | { readonly success: false; readonly error?: z.ZodError };\n\n/** `schema.safeParse(value)`, with a throw while reading `value` as a failure without issues. */\nexport function safeParseTotal<S extends z.ZodType>(schema: S, value: unknown): TotalParseResult<z.output<S>> {\n try {\n return schema.safeParse(value);\n } catch {\n return { success: false };\n }\n}\n","/**\n * Sealed provider provisioning v1 (plan web-sealed-provisioning §3).\n *\n * A browser seals a provider API key to one device's long-lived P-256\n * sealing key; the cloud relays only ciphertext; the device opens it in\n * memory. This module is the single byte authority both ends share:\n *\n * - the request schema (header + non-secret config + optional sealed secret),\n * - canonical AAD bytes, config digest, and request digest,\n * - the sealing-key claim canonical bytes a device signs at registration,\n * - plaintext padding (2-byte length prefix, zero-padded to 256-byte blocks),\n * - one-shot seal/open on top of `hpke.ts`.\n *\n * Every function is WebCrypto-only and `node:`-free so the Web bundle and the\n * device use literally the same code. Nothing here reads a clock, a network,\n * or a store; time windows, replay ledgers, placement and enrollment are the\n * device's (`@byok-sdk/keys`) decisions.\n *\n * Error messages never include plaintext, ciphertext, or key material.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject, type JsonValue } from './attestation';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\nimport {\n HPKE_AEAD_TAG_BYTES,\n HPKE_P256_PUBLIC_KEY_BYTES,\n hpkeOpenBase,\n hpkeSealBase,\n importP256PublicKey,\n} from './hpke';\nimport { isCanonicalTimestamp } from './time';\nimport { safeParseTotal } from './total-parse';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nexport type { WebCryptoKey } from './webcrypto';\n\n/** The only HPKE suite v1 admits. There is no negotiation and no second value. */\nexport const PROVIDER_SECRET_HPKE_SUITE = 'hpke-base.dhkem-p256-hkdf-sha256.hkdf-sha256.aes-128-gcm';\n\n/** HPKE `info`, versioned; a v2 is a new constant, never a parser branch. */\nexport const PROVIDER_SECRET_HPKE_INFO = 'byok-sdk.provider-secret.v1';\n\nexport const PROVIDER_PROVISIONING_REQUEST_VERSION = 1;\n\nexport const PROVIDER_PROVISIONING_OPERATIONS = ['configure', 'update_model', 'replace_secret', 'delete'] as const;\nexport type ProviderProvisioningOperation = (typeof PROVIDER_PROVISIONING_OPERATIONS)[number];\n\n/** Operations whose request must carry exactly one sealed secret. */\nexport const PROVIDER_PROVISIONING_SECRET_OPERATIONS = ['configure', 'replace_secret'] as const;\n\n/** Upper bound for `expiresAt - issuedAt` (plan D11). */\nexport const PROVIDER_PROVISIONING_MAX_TTL_MS = 15 * 60 * 1000;\n\n/** Plaintext is padded to a multiple of this many bytes so ciphertext length hides key length. */\nexport const PROVIDER_SECRET_PAD_BLOCK_BYTES = 256;\n\n/** Largest padded plaintext v1 accepts; the secret itself is at most this minus the 2-byte prefix. */\nexport const PROVIDER_SECRET_MAX_PADDED_BYTES = 4096;\n\nexport const PROVIDER_SECRET_MAX_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES - 2;\n\n/** Length of a sealing key id: base64url(sha256(raw public key)) truncated to 22 characters. */\nexport const SEALING_KEY_ID_LENGTH = 22;\n\n// ---------------------------------------------------------------------------\n// base64url (strict, unpadded, canonical)\n// ---------------------------------------------------------------------------\n\nconst B64URL_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\nconst B64URL_PATTERN = /^[A-Za-z0-9_-]*$/;\n\nexport function encodeBase64Url(bytes: Uint8Array): string {\n let out = '';\n let index = 0;\n for (; index + 3 <= bytes.length; index += 3) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8) | bytes[index + 2]!;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]! + B64URL_ALPHABET[value & 63]!;\n }\n const rest = bytes.length - index;\n if (rest === 1) {\n const value = bytes[index]! << 16;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!;\n } else if (rest === 2) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8);\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]!;\n }\n return out;\n}\n\n/** Decode canonical unpadded base64url, or throw — never a repaired approximation. */\nexport function decodeBase64Url(value: string, field: string): Uint8Array<ArrayBuffer> {\n if (!B64URL_PATTERN.test(value) || value.length % 4 === 1) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n const out = new Uint8Array(Math.floor((value.length * 3) / 4));\n let buffer = 0;\n let bits = 0;\n let offset = 0;\n for (const char of value) {\n buffer = (buffer << 6) | B64URL_ALPHABET.indexOf(char);\n bits += 6;\n if (bits >= 8) {\n bits -= 8;\n out[offset] = (buffer >> bits) & 0xff;\n offset += 1;\n }\n }\n if (encodeBase64Url(out) !== value) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n return out;\n}\n\nfunction base64UrlField(bytes: { exact?: number; max?: number }) {\n return z.string().superRefine((value, ctx) => {\n try {\n const decoded = decodeBase64Url(value, 'field');\n if (bytes.exact !== undefined && decoded.byteLength !== bytes.exact) {\n ctx.addIssue({ code: 'custom', message: `must decode to exactly ${bytes.exact} bytes` });\n }\n if (bytes.max !== undefined && decoded.byteLength > bytes.max) {\n ctx.addIssue({ code: 'custom', message: `must decode to at most ${bytes.max} bytes` });\n }\n } catch {\n ctx.addIssue({ code: 'custom', message: 'must be canonical unpadded base64url' });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Hashing\n// ---------------------------------------------------------------------------\n\nasync function sha256(bytes: Uint8Array): Promise<Uint8Array> {\n return new Uint8Array(await webCryptoSubtle().digest('SHA-256', new Uint8Array(bytes)));\n}\n\nfunction hex(bytes: Uint8Array): string {\n let out = '';\n for (const byte of bytes) out += byte.toString(16).padStart(2, '0');\n return out;\n}\n\nasync function contentDigest(value: JsonValue): Promise<string> {\n return `sha256:${hex(await sha256(canonicalizeJsonBytes(value)))}`;\n}\n\n// ---------------------------------------------------------------------------\n// Sealing key (public JWK + claim)\n// ---------------------------------------------------------------------------\n\n/**\n * The only public-key shape v1 accepts. Strict: a `d` (private) member, an\n * `alg`, `use`, `key_ops` or any other extra member is rejected rather than\n * ignored, so a private JWK can never be published by mistake.\n */\nexport const SealingPublicJwkSchema = z.strictObject({\n kty: z.literal('EC'),\n crv: z.literal('P-256'),\n x: base64UrlField({ exact: 32 }),\n y: base64UrlField({ exact: 32 }),\n});\nexport type SealingPublicJwk = z.infer<typeof SealingPublicJwkSchema>;\n\nexport const SealingKeyIdSchema = z.string().regex(new RegExp(`^[A-Za-z0-9_-]{${SEALING_KEY_ID_LENGTH}}$`));\n\nfunction parseSealingPublicJwk(input: unknown): SealingPublicJwk {\n const result = safeParseTotal(SealingPublicJwkSchema, input);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing public key must be a strict P-256 EC public JWK');\n }\n return result.data;\n}\n\n/** Uncompressed SEC1 bytes (`0x04 || x || y`) of a sealing public JWK. */\nexport function sealingPublicKeyBytes(publicJwk: SealingPublicJwk): Uint8Array<ArrayBuffer> {\n const jwk = parseSealingPublicJwk(publicJwk);\n const raw = new Uint8Array(HPKE_P256_PUBLIC_KEY_BYTES);\n raw[0] = 0x04;\n raw.set(decodeBase64Url(jwk.x, 'x'), 1);\n raw.set(decodeBase64Url(jwk.y, 'y'), 33);\n return raw;\n}\n\n/** `base64url(sha256(0x04 || x || y))[0..22]` — the device's and the browser's shared key id rule. */\nexport async function deriveSealingKeyId(publicJwk: SealingPublicJwk): Promise<string> {\n const raw = sealingPublicKeyBytes(publicJwk);\n await importP256PublicKey(raw);\n return encodeBase64Url(await sha256(raw)).slice(0, SEALING_KEY_ID_LENGTH);\n}\n\n/**\n * The claim a device signs (through its device-proof signer, host glue) when\n * it registers its sealing key. The proof body is these canonical bytes.\n */\nexport const SealingKeyClaimV1Schema = z.strictObject({\n version: z.literal(1),\n keyId: SealingKeyIdSchema,\n epoch: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n publicJwk: SealingPublicJwkSchema,\n});\nexport type SealingKeyClaimV1 = z.infer<typeof SealingKeyClaimV1Schema>;\n\n/** Canonical UTF-8 bytes of a sealing-key claim. */\nexport function sealingKeyClaimCanonicalBytes(claim: SealingKeyClaimV1): Uint8Array {\n const result = safeParseTotal(SealingKeyClaimV1Schema, claim);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key claim is invalid');\n }\n const parsed = result.data;\n return canonicalizeJsonBytes({\n version: parsed.version,\n keyId: parsed.keyId,\n epoch: parsed.epoch,\n publicJwk: { kty: parsed.publicJwk.kty, crv: parsed.publicJwk.crv, x: parsed.publicJwk.x, y: parsed.publicJwk.y },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Request schema\n// ---------------------------------------------------------------------------\n\n/** Opaque identifier: non-empty, bounded, no surrounding whitespace, no control characters. */\nconst OpaqueIdSchema = z.string().min(1).max(200).superRefine((value, ctx) => {\n if (value.trim() !== value || /[\\u0000-\\u001f\\u007f]/u.test(value)) {\n ctx.addIssue({ code: 'custom', message: 'must not carry surrounding whitespace or control characters' });\n }\n});\n\nconst CanonicalTimestampSchema = z.string().refine(isCanonicalTimestamp, 'must be a canonical ISO-8601 UTC instant');\n\nconst ProfileRefSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ProviderKindSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ModelIdSchema = z.string().min(1).max(160).refine((value) => value.trim() === value && !/[\\u0000-\\u001f\\u007f]/u.test(value), 'model id is invalid');\nconst CapabilitySchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/u);\n\n/**\n * `pi_model` travels as an opaque canonicalizable JSON object; the device\n * validates it against `@byok-sdk/keys`' strict `PiModelConfigSchema`. Core\n * only guarantees it has one canonical byte form.\n */\nconst PiModelJsonSchema = z.custom<JsonObject>((value) => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return false;\n try {\n canonicalizeJson(value as JsonObject);\n return true;\n } catch {\n return false;\n }\n}, 'piModel must be a canonical JSON object');\n\nconst ModelConfigFields = {\n agentId: OpaqueIdSchema,\n providerKind: ProviderKindSchema,\n modelId: ModelIdSchema,\n piModel: PiModelJsonSchema,\n capabilities: z.array(CapabilitySchema).max(8).refine((values) => new Set(values).size === values.length, 'capabilities must be unique'),\n};\n\n/**\n * The non-secret configuration, one exact shape per operation. An operation\n * carries only the fields it acts on — `delete` has no model, `replace_secret`\n * declares only the provider kind its key is scoped to — so nothing is\n * accepted and silently ignored.\n */\nexport const ProviderProvisioningConfigV1Schema = z.discriminatedUnion('operation', [\n z.strictObject({ operation: z.literal('configure'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('update_model'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('replace_secret'), agentId: OpaqueIdSchema, providerKind: ProviderKindSchema }),\n z.strictObject({ operation: z.literal('delete'), agentId: OpaqueIdSchema }),\n]);\nexport type ProviderProvisioningConfigV1 = z.infer<typeof ProviderProvisioningConfigV1Schema>;\n\n/** The credential-free provider triple the Host believes is current (A3), or `null` for none. */\nexport const ProviderProvisioningExpectedProfileSchema = z.union([\n z.null(),\n z.strictObject({\n profileRef: ProfileRefSchema,\n profileRevision: z.string().regex(/^(?:0|[1-9][0-9]{0,19})$/u),\n profileHash: z.string().regex(CONTENT_HASH_PATTERN),\n }),\n]);\nexport type ProviderProvisioningExpectedProfile = z.infer<typeof ProviderProvisioningExpectedProfileSchema>;\n\n/**\n * Opaque, Host-issued identity version: the enrollment revision (changes on\n * re-pair / re-enrollment of the same device id) or the agent placement\n * revision. The device compares it byte-for-byte with its own snapshot.\n */\nexport const ProviderProvisioningIdentityRevisionSchema = z.string().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/u);\n\nexport const ProviderProvisioningHeaderV1Schema = z.strictObject({\n tenantId: OpaqueIdSchema,\n deviceId: OpaqueIdSchema,\n agentId: OpaqueIdSchema,\n requestId: OpaqueIdSchema,\n operation: z.enum(PROVIDER_PROVISIONING_OPERATIONS),\n /** Non-secret, strictly increasing per bot (A3); a device rejects anything not above its high-watermark. */\n operationGeneration: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n expectedProfile: ProviderProvisioningExpectedProfileSchema,\n /** The device enrollment revision the Host authorized against (F2). */\n expectedEnrollmentRevision: ProviderProvisioningIdentityRevisionSchema,\n /** The agent placement revision the Host authorized against (F2). */\n expectedPlacementRevision: ProviderProvisioningIdentityRevisionSchema,\n configDigest: z.string().regex(CONTENT_HASH_PATTERN),\n issuedAt: CanonicalTimestampSchema,\n expiresAt: CanonicalTimestampSchema,\n});\nexport type ProviderProvisioningHeaderV1 = z.infer<typeof ProviderProvisioningHeaderV1Schema>;\n\n/** Ciphertext bound: largest padded plaintext plus the AEAD tag. */\nconst MAX_CIPHERTEXT_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES + HPKE_AEAD_TAG_BYTES;\n\nexport const SealedProviderSecretV1Schema = z.strictObject({\n suite: z.literal(PROVIDER_SECRET_HPKE_SUITE),\n keyId: SealingKeyIdSchema,\n enc: base64UrlField({ exact: HPKE_P256_PUBLIC_KEY_BYTES }),\n ciphertext: base64UrlField({ max: MAX_CIPHERTEXT_BYTES }),\n});\nexport type SealedProviderSecretV1 = z.infer<typeof SealedProviderSecretV1Schema>;\n\nfunction isSecretOperation(operation: ProviderProvisioningOperation): boolean {\n return (PROVIDER_PROVISIONING_SECRET_OPERATIONS as readonly string[]).includes(operation);\n}\n\nexport const ProviderProvisioningRequestV1Schema = z\n .strictObject({\n version: z.literal(PROVIDER_PROVISIONING_REQUEST_VERSION),\n header: ProviderProvisioningHeaderV1Schema,\n config: ProviderProvisioningConfigV1Schema,\n sealed: SealedProviderSecretV1Schema.optional(),\n })\n .superRefine((request, ctx) => {\n if (request.header.operation !== request.config.operation) {\n ctx.addIssue({ code: 'custom', path: ['config', 'operation'], message: 'config operation must equal header operation' });\n }\n if (request.header.agentId !== request.config.agentId) {\n ctx.addIssue({ code: 'custom', path: ['config', 'agentId'], message: 'config agentId must equal header agentId' });\n }\n if (isSecretOperation(request.header.operation) !== (request.sealed !== undefined)) {\n ctx.addIssue({ code: 'custom', path: ['sealed'], message: 'a sealed secret is required exactly for configure and replace_secret' });\n }\n });\nexport type ProviderProvisioningRequestV1 = z.infer<typeof ProviderProvisioningRequestV1Schema>;\n\n/** Parse a request fail-closed. Issue text names paths and rules only, never values. */\nexport function parseProviderProvisioningRequest(input: unknown): ProviderProvisioningRequestV1 {\n const result = safeParseTotal(ProviderProvisioningRequestV1Schema, input);\n if (!result.success) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n `Invalid provider provisioning request: ${(result.error?.issues ?? [{ path: [], message: 'is not readable' }])\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n );\n }\n return result.data;\n}\n\n// ---------------------------------------------------------------------------\n// Canonical bytes and digests\n// ---------------------------------------------------------------------------\n\nfunction configJson(config: ProviderProvisioningConfigV1): JsonObject {\n return config as unknown as JsonObject;\n}\n\n/** `sha256:<hex>` over the canonical JSON of the non-secret config. */\nexport async function providerProvisioningConfigDigest(config: ProviderProvisioningConfigV1): Promise<string> {\n const result = safeParseTotal(ProviderProvisioningConfigV1Schema, config);\n if (!result.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n return contentDigest(configJson(result.data));\n}\n\n/**\n * Canonical AAD bytes. Every header field plus the sealing key id is bound,\n * so tampering with any of tenant, device, key, request, agent, operation,\n * generation, expected triple, expected enrollment and placement revisions,\n * config digest, or time window fails the AEAD.\n */\nexport function providerSecretAadBytes(header: ProviderProvisioningHeaderV1, keyId: string): Uint8Array {\n const parsed = safeParseTotal(ProviderProvisioningHeaderV1Schema, header);\n if (!parsed.success || !safeParseTotal(SealingKeyIdSchema, keyId).success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning AAD input is invalid');\n }\n const value = parsed.data;\n return canonicalizeJsonBytes({\n v: PROVIDER_PROVISIONING_REQUEST_VERSION,\n tenantId: value.tenantId,\n deviceId: value.deviceId,\n keyId,\n requestId: value.requestId,\n agentId: value.agentId,\n operation: value.operation,\n operationGeneration: value.operationGeneration,\n expectedProfile: value.expectedProfile === null\n ? null\n : {\n profileRef: value.expectedProfile.profileRef,\n profileRevision: value.expectedProfile.profileRevision,\n profileHash: value.expectedProfile.profileHash,\n },\n expectedEnrollmentRevision: value.expectedEnrollmentRevision,\n expectedPlacementRevision: value.expectedPlacementRevision,\n configDigest: value.configDigest,\n issuedAt: value.issuedAt,\n expiresAt: value.expiresAt,\n });\n}\n\n/**\n * `sha256:<hex>` over the canonical JSON of the complete request. A device\n * compares it for an already-seen `requestId`: equal returns the stored\n * result, different is a conflict.\n */\nexport async function providerProvisioningRequestDigest(request: ProviderProvisioningRequestV1): Promise<string> {\n const parsed = parseProviderProvisioningRequest(request);\n return contentDigest(parsed as unknown as JsonObject);\n}\n\n/** Fail closed unless `header.configDigest` is the digest of `config`. */\nexport async function assertProviderProvisioningConfigDigest(request: ProviderProvisioningRequestV1): Promise<void> {\n const parsed = parseProviderProvisioningRequest(request);\n if ((await providerProvisioningConfigDigest(parsed.config)) !== parsed.header.configDigest) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config digest does not match its header');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Padding\n// ---------------------------------------------------------------------------\n\n/** `u16be(len) || utf8(secret) || zeros`, total a multiple of 256 bytes. */\nexport function padProviderSecret(secret: string): Uint8Array<ArrayBuffer> {\n const bytes = new TextEncoder().encode(secret);\n if (bytes.byteLength === 0 || bytes.byteLength > PROVIDER_SECRET_MAX_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', `Provider secret must be 1 to ${PROVIDER_SECRET_MAX_BYTES} UTF-8 bytes`);\n }\n const total = Math.ceil((bytes.byteLength + 2) / PROVIDER_SECRET_PAD_BLOCK_BYTES) * PROVIDER_SECRET_PAD_BLOCK_BYTES;\n const out = new Uint8Array(total);\n out[0] = bytes.byteLength >> 8;\n out[1] = bytes.byteLength & 0xff;\n out.set(bytes, 2);\n return out;\n}\n\n/** Strict inverse of {@link padProviderSecret}: block size, bounds, zero padding, and fatal UTF-8 are all checked. */\nexport function unpadProviderSecret(padded: Uint8Array): string {\n if (\n padded.byteLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || padded.byteLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || padded.byteLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length');\n }\n const length = (padded[0]! << 8) | padded[1]!;\n if (length === 0 || length + 2 > padded.byteLength || padded.byteLength - (length + 2) >= PROVIDER_SECRET_PAD_BLOCK_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length prefix');\n }\n for (let index = length + 2; index < padded.byteLength; index += 1) {\n if (padded[index] !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has non-zero padding');\n }\n }\n try {\n return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(padded.subarray(2, length + 2));\n } catch {\n throw new ByokCoreError('sealed_secret_invalid', 'Provider secret is not valid UTF-8');\n }\n}\n\n// ---------------------------------------------------------------------------\n// One-shot seal / open\n// ---------------------------------------------------------------------------\n\nconst INFO_BYTES = (): Uint8Array => new TextEncoder().encode(PROVIDER_SECRET_HPKE_INFO);\n\nexport interface SealProviderProvisioningRequestInput {\n /** The header without its digest; the digest is computed here from `config`. */\n readonly header: Omit<ProviderProvisioningHeaderV1, 'configDigest'>;\n readonly config: ProviderProvisioningConfigV1;\n /** Required exactly for secret-bearing operations. */\n readonly recipient?: { readonly keyId: string; readonly publicJwk: SealingPublicJwk };\n /** Required exactly for secret-bearing operations. */\n readonly secret?: string;\n}\n\n/**\n * Build one immutable provisioning request. Secret-bearing operations are\n * sealed once, to a freshly generated ephemeral key; the key id is re-derived\n * from the public JWK so a claim whose id does not match its key is refused\n * before anything is encrypted.\n */\nexport async function sealProviderProvisioningRequest(\n input: SealProviderProvisioningRequestInput,\n): Promise<ProviderProvisioningRequestV1> {\n const configResult = safeParseTotal(ProviderProvisioningConfigV1Schema, input.config);\n if (!configResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n const config = configResult.data;\n const headerResult = safeParseTotal(ProviderProvisioningHeaderV1Schema, {\n ...input.header,\n configDigest: await providerProvisioningConfigDigest(config),\n });\n if (!headerResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning header is invalid');\n }\n const header = headerResult.data;\n const needsSecret = isSecretOperation(header.operation);\n if (needsSecret !== (input.secret !== undefined) || needsSecret !== (input.recipient !== undefined)) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n 'A secret and recipient are required exactly for configure and replace_secret',\n );\n }\n let sealed: SealedProviderSecretV1 | undefined;\n if (needsSecret) {\n const recipient = input.recipient!;\n const publicJwk = parseSealingPublicJwk(recipient.publicJwk);\n if ((await deriveSealingKeyId(publicJwk)) !== recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key id does not match its public key');\n }\n const { enc, ciphertext } = await hpkeSealBase({\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(header, recipient.keyId),\n plaintext: padProviderSecret(input.secret!),\n });\n sealed = {\n suite: PROVIDER_SECRET_HPKE_SUITE,\n keyId: recipient.keyId,\n enc: encodeBase64Url(enc),\n ciphertext: encodeBase64Url(ciphertext),\n };\n }\n return parseProviderProvisioningRequest({\n version: PROVIDER_PROVISIONING_REQUEST_VERSION,\n header,\n config,\n ...(sealed === undefined ? {} : { sealed }),\n });\n}\n\nexport interface ProviderSecretRecipient {\n readonly keyId: string;\n readonly publicJwk: SealingPublicJwk;\n /** Non-extractable ECDH private key; never leaves the device. */\n readonly privateKey: WebCryptoKey;\n}\n\n/**\n * Open the sealed secret of a request, in memory. Checks, in order: request\n * schema, suite (schema literal), recipient key id, config digest, ciphertext\n * length against the padding grammar, HPKE open under the request's own AAD,\n * then strict unpadding. Time windows, replay, and placement are not checked\n * here — they are device state.\n */\nexport async function openProviderProvisioningSecret(input: {\n readonly request: ProviderProvisioningRequestV1;\n readonly recipient: ProviderSecretRecipient;\n}): Promise<string> {\n const request = parseProviderProvisioningRequest(input.request);\n const sealed = request.sealed;\n if (sealed === undefined) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning request carries no sealed secret');\n }\n const publicJwk = parseSealingPublicJwk(input.recipient.publicJwk);\n if (sealed.keyId !== input.recipient.keyId || (await deriveSealingKeyId(publicJwk)) !== input.recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret is not addressed to this sealing key');\n }\n await assertProviderProvisioningConfigDigest(request);\n const ciphertext = decodeBase64Url(sealed.ciphertext, 'ciphertext');\n const paddedLength = ciphertext.byteLength - HPKE_AEAD_TAG_BYTES;\n if (\n paddedLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || paddedLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || paddedLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret ciphertext has an invalid length');\n }\n const padded = await hpkeOpenBase({\n recipientPrivateKey: input.recipient.privateKey,\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n enc: decodeBase64Url(sealed.enc, 'enc'),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(request.header, sealed.keyId),\n ciphertext,\n });\n try {\n return unpadProviderSecret(padded);\n } finally {\n padded.fill(0);\n }\n}\n","/**\n * Host-approved Agent memory intent — the identity digest.\n *\n * One `operationDigest` binds an intent to the tenant and device it was\n * approved for and to its exact operation. A Host computes it at approval; a\n * device recomputes it with its OWN enrolled tenant and device ids, so an\n * intent released to another tenant or device, or with any identity or\n * operation field changed, can never match. The digest never covers content:\n * `targetRevision` (the body digest) binds the body instead.\n *\n * Canonicalization is the shared RFC 8785 canonicalizer ({@link canonicalizeJsonBytes});\n * hashing is WebCrypto SHA-256, as for every other core digest.\n */\nimport { canonicalizeJsonBytes, type JsonObject } from './attestation';\nimport { webCryptoSubtle } from './webcrypto';\n\n/** Domain tag inside every agent memory intent operation digest. */\nexport const AGENT_MEMORY_INTENT_DIGEST_VERSION = 'byok-agent-memory-intent-v1' as const;\n\n/** Every field the operation digest covers. `targetRevision` is `null` exactly for `delete`. */\nexport interface AgentMemoryIntentDigestInput {\n readonly tenantId: string;\n readonly deviceId: string;\n readonly intentId: string;\n readonly agentRef: { readonly agentId: string; readonly profileRevision: string };\n readonly path: string;\n readonly operation: 'replace' | 'delete';\n readonly baseRevision: string;\n readonly targetRevision: string | null;\n readonly approvalRef: string;\n}\n\n/**\n * `sha256:<hex>` over\n * `canonicalizeJson({v, tenantId, deviceId, intentId, agentRef, path, operation, baseRevision, targetRevision, approvalRef})`.\n *\n * Only the listed fields are read (an extra property on `input` never changes\n * the digest); a missing field is `undefined`, which the canonicalizer refuses.\n */\nexport async function agentMemoryIntentOperationDigest(input: AgentMemoryIntentDigestInput): Promise<string> {\n const canonical: JsonObject = {\n v: AGENT_MEMORY_INTENT_DIGEST_VERSION,\n tenantId: input.tenantId,\n deviceId: input.deviceId,\n intentId: input.intentId,\n agentRef: { agentId: input.agentRef.agentId, profileRevision: input.agentRef.profileRevision },\n path: input.path,\n operation: input.operation,\n baseRevision: input.baseRevision,\n targetRevision: input.targetRevision,\n approvalRef: input.approvalRef,\n };\n const digest = new Uint8Array(\n await webCryptoSubtle().digest('SHA-256', new Uint8Array(canonicalizeJsonBytes(canonical))),\n );\n let hex = '';\n for (const byte of digest) hex += byte.toString(16).padStart(2, '0');\n return `sha256:${hex}`;\n}\n","/**\n * Nonce-signing domain separation for device token renewal (docs/protocol.md §6.2).\n *\n * S1 (GAP-004) put a domain tag in front of every challenge nonce a device\n * signs: the device key is a long-lived identity key that other planes (S6\n * device proof) also sign structured messages with, so without a tag a\n * signature produced for one purpose would be a valid signature for another.\n *\n * The tag started life as three separate literals — one in the daemon, one on\n * the hosted surface, one on the reference server — each with a comment saying\n * it was byte-identical to the others. That is a drift hazard written down, not\n * a design: three copies agree only until someone edits one. This module is the\n * single authority, and it lives in core for the same reason\n * {@link DEVICE_PROOF_DOMAIN_PREFIX} does — core is the one package all three\n * ends already depend on, it is Node-free and Workers-safe, and it holds no\n * crypto of its own. What travels is *bytes to sign*; who signs them, and with\n * which primitive, stays with each end.\n *\n * There is deliberately no dual mode and no grace window: a raw, unprefixed\n * nonce signature is simply invalid, and a device on an older encoding re-pairs.\n */\n\n/**\n * The domain-separation prefix a device signs along with a challenge nonce.\n *\n * Byte-frozen: `62 79 6f 6b 2d 6e 6f 6e 63 65 2d 76 31 0a` (14 bytes, UTF-8).\n * Changing it invalidates every deployed device's token-renewal path, so it is\n * a wire constant, not a tunable.\n */\nexport const NONCE_SIGNING_DOMAIN = 'byok-nonce-v1\\n';\n\n/**\n * The exact bytes a device signs for a challenge nonce, and the exact bytes a\n * verifier reconstructs: {@link NONCE_SIGNING_DOMAIN} followed by `nonce`,\n * UTF-8 encoded.\n *\n * `TextEncoder` is a platform global on Node and Workers alike, which is what\n * lets the one authority sit in a package that imports no `node:` builtin.\n */\nexport function nonceSigningBytes(nonce: string): Uint8Array {\n return new TextEncoder().encode(NONCE_SIGNING_DOMAIN + nonce);\n}\n","import { ByokCoreError } from '../errors';\nimport type { Clock } from '../stores';\nimport type { ContentHash } from '../blob';\nimport type { StorageReservation, TenantStorageUsage } from '../quota';\nimport type { TenantId } from '../tenant';\n\nexport interface ReservationRecord {\n readonly reservation: StorageReservation;\n readonly deduplicated: boolean;\n}\n/** Shared authority for reservations, object accounting and quota reads. */\nexport class InMemoryStorageLedger {\n readonly #usage = new Map<TenantId, TenantStorageUsage>();\n readonly #reservations = new Map<string, ReservationRecord>();\n readonly #committed = new Map<TenantId, Map<string, { kind: 'object' | 'inline'; bytes: bigint }>>();\n constructor(private readonly clock: Clock) {}\n readReservation(key: string): ReservationRecord | undefined { return this.#reservations.get(key); }\n writeReservation(key: string, record: ReservationRecord): void { this.#reservations.set(key, record); }\n deleteReservation(key: string): void { this.#reservations.delete(key); }\n reservations(): IterableIterator<[string, ReservationRecord]> { return this.#reservations.entries(); }\n readUsage(tenant: TenantId): TenantStorageUsage {\n let usage = this.#usage.get(tenant);\n if (usage === undefined) {\n usage = { committedObjectBytes: 0n, committedInlineBytes: 0n, reservedBytes: 0n, objectCount: 0n, updatedAt: this.clock.now().toISOString() };\n this.#usage.set(tenant, usage);\n }\n return usage;\n }\n writeUsage(tenant: TenantId, usage: TenantStorageUsage): void { this.#usage.set(tenant, usage); }\n isCounted(tenant: TenantId, hash: string): boolean { return this.#committed.get(tenant)?.has(hash) === true; }\n recordCommitted(tenant: TenantId, reservation: StorageReservation): void {\n let hashes = this.#committed.get(tenant);\n if (hashes === undefined) { hashes = new Map(); this.#committed.set(tenant, hashes); }\n hashes.set(reservation.contentHash, { kind: reservation.kind, bytes: reservation.expectedBytes });\n }\n hasReservedObject(tenant: TenantId, hash: ContentHash): boolean {\n for (const { reservation } of this.#reservations.values()) {\n if (reservation.tenantId === tenant && reservation.kind === 'object'\n && reservation.contentHash === hash && reservation.state === 'reserved') return true;\n }\n return false;\n }\n reservedObjectHashes(tenant: TenantId): readonly string[] {\n return [...this.#reservations.values()].filter(({ reservation }) => reservation.tenantId === tenant && reservation.kind === 'object' && reservation.state === 'reserved').map(({ reservation }) => reservation.contentHash);\n }\n prepareCollectedObjectRelease(tenant: TenantId, hash: ContentHash, byteSize: bigint, now: string): { readonly releasedBytes: bigint; readonly commit: () => void } {\n const hashes = this.#committed.get(tenant);\n const accounted = hashes?.get(hash);\n // Direct metadata commits and rows retained across a SQLite restart have\n // no charge in this process-local authority.\n if (accounted === undefined || accounted.kind === 'inline') return { releasedBytes: 0n, commit: () => {} };\n const usage = this.#usage.get(tenant);\n if (usage === undefined || accounted.bytes !== byteSize || usage.committedObjectBytes < accounted.bytes || usage.objectCount < 1n) {\n throw new ByokCoreError('storage_integrity_mismatch', 'Collected object accounting does not match the storage ledger.');\n }\n return { releasedBytes: accounted.bytes, commit: () => {\n hashes!.delete(hash);\n this.writeUsage(tenant, { ...usage, committedObjectBytes: usage.committedObjectBytes - accounted.bytes, objectCount: usage.objectCount - 1n, updatedAt: now });\n } };\n }\n releaseCollectedObject(tenant: TenantId, hash: ContentHash, byteSize: bigint, now: string): bigint {\n const release = this.prepareCollectedObjectRelease(tenant, hash, byteSize, now);\n release.commit();\n return release.releasedBytes;\n }\n}\n","import { ByokCoreError } from './errors';\nimport { assertCanonicalTimestamp } from './time';\n\nexport interface CollectExpiredInput {\n readonly now: string;\n readonly limit: number;\n}\nexport interface CollectExpiredCounts {\n readonly removed: number;\n readonly expired: number;\n readonly releasedBytes: bigint;\n}\nexport interface CollectExpiredResult extends CollectExpiredCounts {\n readonly more: boolean;\n}\nexport function assertCollectExpiredInput(input: CollectExpiredInput): void {\n assertCanonicalTimestamp(input.now, 'now');\n if (!Number.isSafeInteger(input.limit) || input.limit <= 0) {\n throw new ByokCoreError('retention_input_invalid', 'collectExpired limit must be a positive safe integer.');\n }\n}\n/** A committed partial result remains visible when external deletion fails. */\nexport class CollectExpiredFailure extends ByokCoreError {\n constructor(\n readonly committed: CollectExpiredCounts,\n readonly failedRows: number,\n readonly more?: boolean,\n options?: ErrorOptions,\n ) {\n super('retention_collect_failed', 'Retention collection did not complete.', options);\n }\n}\n","import { assertCollectExpiredInput, type CollectExpiredInput, type CollectExpiredResult } from '../retention';\n/**\n * In-memory {@link PresenceStore} reference (§12.3).\n *\n * Expiry is absence. A hint past its `expiresAt` is filtered out of every read\n * and lazily dropped, so no reader can ever observe a stale level and mistake\n * it for a live one. Both stores read time from the injected clock, which is\n * what lets the conformance suite assert expiry without sleeping.\n */\nimport { ByokCoreError } from '../errors';\nimport {\n freezePresenceRuntimeFact,\n type PresenceHint,\n type PresenceHintInput,\n type PresenceStore,\n} from '../presence';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\n\nfunction assertTtl(ttlMs: number): void {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new ByokCoreError(\n 'hint_ttl_invalid',\n `Hint ttl must be a positive number of milliseconds, received ${String(ttlMs)}.`,\n );\n }\n}\n\nfunction assertMinimumInterval(minimumIntervalMs: number): void {\n if (!Number.isFinite(minimumIntervalMs) || minimumIntervalMs < 0) {\n throw new ByokCoreError(\n 'hint_ttl_invalid',\n `Hint minimum interval must be a non-negative number of milliseconds, received ${String(minimumIntervalMs)}.`,\n );\n }\n}\n\nexport class InMemoryPresenceStore implements PresenceStore {\n readonly #hints = new Map<string, PresenceHint>();\n readonly #clock: Clock;\n\n constructor(clock: Clock) {\n this.#clock = clock;\n }\n\n async publish(tenant: TenantId, input: PresenceHintInput): Promise<PresenceHint> {\n assertTtl(input.ttlMs);\n assertMinimumInterval(input.minimumIntervalMs);\n const now = this.#clock.now();\n const key = tenantKey(tenant, input.deviceId);\n const existing = this.#hints.get(key);\n // A backward clock step has zero elapsed time: only positive intervals throttle.\n if (\n existing &&\n now.toISOString() < existing.expiresAt &&\n Math.max(0, Number(now) - Date.parse(existing.observedAt)) < input.minimumIntervalMs\n ) {\n throw new ByokCoreError(\n 'hint_rate_limited',\n `Presence for ${input.deviceId} was published more recently than the configured minimum interval.`,\n );\n }\n const hint: PresenceHint = {\n tenantId: tenant,\n deviceId: input.deviceId,\n level: input.level,\n ...(input.detail === undefined ? {} : { detail: input.detail }),\n ...(input.configuredToolsets === undefined\n ? {}\n : { configuredToolsets: Object.freeze([...input.configuredToolsets]) }),\n ...(input.clientVersion === undefined ? {} : { clientVersion: input.clientVersion }),\n ...(input.protocolVersions === undefined\n ? {}\n : { protocolVersions: Object.freeze([...input.protocolVersions]) }),\n ...(input.runtimes === undefined\n ? {}\n : {\n runtimes: Object.freeze(input.runtimes.map(freezePresenceRuntimeFact)),\n }),\n observedAt: now.toISOString(),\n expiresAt: new Date(now.getTime() + input.ttlMs).toISOString(),\n };\n this.#hints.set(key, hint);\n return hint;\n }\n\n async read(tenant: TenantId, deviceId: string): Promise<PresenceHint | undefined> {\n const key = tenantKey(tenant, deviceId);\n const hint = this.#hints.get(key);\n if (hint === undefined) return undefined;\n if (this.#isExpired(hint.expiresAt)) {\n this.#hints.delete(key);\n return undefined;\n }\n return hint;\n }\n\n async list(tenant: TenantId): Promise<readonly PresenceHint[]> {\n const prefix = tenantKey(tenant, '');\n const live: PresenceHint[] = [];\n for (const [key, hint] of [...this.#hints.entries()]) {\n if (!key.startsWith(prefix)) continue;\n if (this.#isExpired(hint.expiresAt)) {\n this.#hints.delete(key);\n continue;\n }\n live.push(hint);\n }\n live.sort((left, right) => left.deviceId.localeCompare(right.deviceId));\n return live;\n }\n\n async collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n let removed = 0, more = false;\n for (const [key, hint] of this.#hints) {\n if (hint.tenantId !== tenant || hint.expiresAt > input.now) continue;\n if (removed === input.limit) { more = true; break; }\n this.#hints.delete(key); removed++;\n }\n return { removed, expired: 0, releasedBytes: 0n, more };\n }\n\n #isExpired(expiresAt: string): boolean {\n return this.#clock.now().toISOString() >= expiresAt;\n }\n}\n","/**\n * In-memory {@link BoardStore} reference (§12.3).\n *\n * The claim path is the interesting one: because JavaScript resolves each\n * `await` boundary atomically here, N concurrent `claim` calls serialize and\n * exactly one finds `assignee === undefined`. A SQL composition gets the same\n * outcome from a conditional `UPDATE ... WHERE assignee IS NULL`; the\n * conformance suite asserts the outcome, not the mechanism.\n *\n * `boardSeq` is per tenant and bumps on every mutation, which is what makes\n * `list({ afterSeq })` an incremental feed that cannot leak another tenant's\n * write rate.\n */\nimport {\n isLegalBoardTransition,\n type BoardClaimInput,\n type BoardItem,\n type BoardItemInput,\n type BoardListQuery,\n type BoardPage,\n type BoardStatusUpdateInput,\n type BoardStore,\n type BoardUnclaimInput,\n} from '../board';\nimport { ByokCoreError, CoreConflictError } from '../errors';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\n\nconst DEFAULT_LIST_LIMIT = 50;\n\nexport class InMemoryBoardStore implements BoardStore {\n readonly #items = new Map<string, BoardItem>();\n readonly #seqByTenant = new Map<string, number>();\n readonly #clock: Clock;\n\n constructor(clock: Clock) {\n this.#clock = clock;\n }\n\n async create(tenant: TenantId, input: BoardItemInput): Promise<BoardItem> {\n const key = tenantKey(tenant, input.itemId);\n if (this.#items.has(key)) {\n throw new ByokCoreError(\n 'board_item_exists',\n `Board item ${input.itemId} already exists in this tenant.`,\n );\n }\n const now = this.#now();\n const item: BoardItem = {\n tenantId: tenant,\n itemId: input.itemId,\n channel: input.channel,\n title: input.title,\n status: input.status ?? 'todo',\n boardSeq: this.#nextSeq(tenant),\n createdAt: now,\n updatedAt: now,\n };\n this.#items.set(key, item);\n return item;\n }\n\n async get(tenant: TenantId, itemId: string): Promise<BoardItem | undefined> {\n return this.#items.get(tenantKey(tenant, itemId));\n }\n\n async list(tenant: TenantId, query: BoardListQuery): Promise<BoardPage> {\n const afterSeq = query.afterSeq ?? 0;\n const limit = query.limit ?? DEFAULT_LIST_LIMIT;\n const prefix = tenantKey(tenant, '');\n const matches: BoardItem[] = [];\n for (const [key, item] of this.#items.entries()) {\n if (!key.startsWith(prefix)) continue;\n if (item.boardSeq <= afterSeq) continue;\n if (query.channel !== undefined && item.channel !== query.channel) continue;\n if (query.status !== undefined && item.status !== query.status) continue;\n matches.push(item);\n }\n matches.sort((left, right) => left.boardSeq - right.boardSeq);\n const page = matches.slice(0, limit);\n return {\n items: page,\n nextSeq: page.at(-1)?.boardSeq ?? afterSeq,\n hasMore: matches.length > page.length,\n };\n }\n\n async remove(tenant: TenantId, itemId: string): Promise<void> {\n this.#items.delete(tenantKey(tenant, itemId));\n }\n\n async claim(tenant: TenantId, input: BoardClaimInput): Promise<BoardItem> {\n const item = this.#require(tenant, input.itemId);\n const expectedStatus = input.expectedStatus ?? 'todo';\n\n if (item.assignee !== undefined) {\n if (item.assignee.holderId === input.holderId) {\n // The same holder retrying is not a second winner. But an *explicit*\n // expectedStatus is a full CAS by contract, and skipping it here would\n // let the holder's retry succeed against a status it no longer believes\n // in — a CAS in name only. The default is not applied on this path: a\n // retry of a successful claim legitimately observes `in_progress`.\n if (input.expectedStatus !== undefined && item.status !== input.expectedStatus) {\n throw new CoreConflictError(\n 'board_status_conflict',\n `Board item ${input.itemId} is ${item.status}, not ${input.expectedStatus}.`,\n item,\n this.#now(),\n );\n }\n return item;\n }\n throw new CoreConflictError(\n 'board_claim_conflict',\n `Board item ${input.itemId} is held by ${item.assignee.holderId}.`,\n item,\n this.#now(),\n );\n }\n if (item.status !== expectedStatus) {\n throw new CoreConflictError(\n 'board_status_conflict',\n `Board item ${input.itemId} is ${item.status}, not ${expectedStatus}.`,\n item,\n this.#now(),\n );\n }\n if (item.status !== 'todo' && item.status !== 'in_progress') {\n throw new CoreConflictError(\n 'board_transition_invalid',\n `Board item ${input.itemId} cannot be claimed from ${item.status}.`,\n item,\n this.#now(),\n );\n }\n\n const now = this.#now();\n const claimed: BoardItem = {\n ...item,\n status: item.status === 'todo' ? 'in_progress' : item.status,\n assignee: { holderId: input.holderId, heldSince: now },\n boardSeq: this.#nextSeq(tenant),\n updatedAt: now,\n };\n this.#items.set(tenantKey(tenant, input.itemId), claimed);\n return claimed;\n }\n\n async unclaim(tenant: TenantId, input: BoardUnclaimInput): Promise<BoardItem> {\n const item = this.#require(tenant, input.itemId);\n if (item.assignee === undefined) {\n throw new ByokCoreError(\n 'board_not_held',\n `Board item ${input.itemId} is not held by anyone.`,\n );\n }\n if (item.assignee.holderId !== input.holderId) {\n throw new CoreConflictError(\n 'board_claim_conflict',\n `Board item ${input.itemId} is held by ${item.assignee.holderId}, not ${input.holderId}.`,\n item,\n this.#now(),\n );\n }\n const now = this.#now();\n const released: BoardItem = {\n tenantId: item.tenantId,\n itemId: item.itemId,\n channel: item.channel,\n title: item.title,\n status: item.status === 'in_progress' ? 'todo' : item.status,\n boardSeq: this.#nextSeq(tenant),\n createdAt: item.createdAt,\n updatedAt: now,\n };\n this.#items.set(tenantKey(tenant, input.itemId), released);\n return released;\n }\n\n async updateStatus(tenant: TenantId, input: BoardStatusUpdateInput): Promise<BoardItem> {\n const item = this.#require(tenant, input.itemId);\n if (item.status !== input.expectedStatus) {\n throw new CoreConflictError(\n 'board_status_conflict',\n `Board item ${input.itemId} is ${item.status}, not ${input.expectedStatus}.`,\n item,\n this.#now(),\n );\n }\n if (input.holderId !== undefined && item.assignee?.holderId !== input.holderId) {\n throw new CoreConflictError(\n 'board_claim_conflict',\n `Board item ${input.itemId} is not held by ${input.holderId}.`,\n item,\n this.#now(),\n );\n }\n if (!isLegalBoardTransition(input.expectedStatus, input.status)) {\n throw new CoreConflictError(\n 'board_transition_invalid',\n `${input.expectedStatus} to ${input.status} is not a legal board transition.`,\n item,\n this.#now(),\n );\n }\n const now = this.#now();\n const updated: BoardItem = {\n ...item,\n status: input.status,\n boardSeq: this.#nextSeq(tenant),\n updatedAt: now,\n };\n this.#items.set(tenantKey(tenant, input.itemId), updated);\n return updated;\n }\n\n #require(tenant: TenantId, itemId: string): BoardItem {\n const item = this.#items.get(tenantKey(tenant, itemId));\n if (item === undefined) {\n throw new ByokCoreError(\n 'board_item_not_found',\n `Board item ${itemId} does not exist in this tenant.`,\n );\n }\n return item;\n }\n\n #nextSeq(tenant: TenantId): number {\n const next = (this.#seqByTenant.get(tenant) ?? 0) + 1;\n this.#seqByTenant.set(tenant, next);\n return next;\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n","/**\n * Archive access to the in-memory core stores (#1120).\n *\n * The Host task archive in `@byok-sdk/cloud` rewrites acked and expired mailbox\n * bodies and removes object references in one synchronous step, which the\n * async ports cannot express. Adding methods to the port classes would put\n * them in the port inventory, and exporting functions would put them in this\n * package's API. Each in-memory store instead registers its access here, keyed\n * by the store instance, in a registry under a well-known global symbol. The\n * cloud package reads the same registry by the same key. Nothing here is\n * exported from the package entry.\n */\nimport type { MailboxBody, MailboxMessage } from '../mailbox';\nimport type { TenantId } from '../tenant';\n\nexport interface InMemoryMailboxArchiveAccess {\n /** The retained rows of one device. */\n messagesOf(tenant: TenantId, deviceId: string): readonly MailboxMessage[];\n /** Replaces one retained row's body. The row, its seq and its state stay. */\n replaceBody(tenant: TenantId, deviceId: string, seq: number, body: MailboxBody): void;\n}\n\nexport interface InMemoryObjectArchiveAccess {\n /** Removes every reference `(refKind, refId)` holds and returns how many went. */\n releaseReferences(tenant: TenantId, refKind: string, refId: string): number;\n}\n\n/** Keep identical to the key `@byok-sdk/cloud` reads. */\nconst REGISTRY_KEY = Symbol.for('@byok-sdk/in-memory-archive-access');\n\nfunction registry(): WeakMap<object, unknown> {\n const holder = globalThis as unknown as Record<symbol, WeakMap<object, unknown> | undefined>;\n return (holder[REGISTRY_KEY] ??= new WeakMap<object, unknown>());\n}\n\nexport function registerArchiveAccess(store: object, access: InMemoryMailboxArchiveAccess | InMemoryObjectArchiveAccess): void {\n registry().set(store, access);\n}\n","import { CollectExpiredFailure } from '../retention';\nimport { assertCollectExpiredInput, type CollectExpiredResult } from '../retention';\n/**\n * In-memory {@link MailboxStore} reference (§12.7.3).\n *\n * Every row lives under a `(tenant, device)` composite key, so a cross-tenant\n * read is not \"denied\" — it addresses a different key space and finds nothing.\n * That is the in-memory expression of §12.6.2 layer 3: there is no bare device\n * index to accidentally query.\n *\n * Mailbox bytes are never counted: usage is the sum over the retained\n * `pending` rows, and a `limited` append sums, checks and inserts without\n * yielding, so no append on another device of the same tenant can interleave\n * with the check.\n */\nimport { ByokCoreError, CoreConflictError } from '../errors';\nimport type {\n MailboxAdvanceCursorInput,\n MailboxAppendInput,\n MailboxCloseStreamInput,\n MailboxCursorState,\n MailboxMessage,\n MailboxPage,\n MailboxReadQuery,\n MailboxRecordDeliveryInput,\n MailboxCollectExpiredInput,\n MailboxExpirePendingInput,\n MailboxReopenStreamInput,\n MailboxStore,\n MailboxStreamCloseCause,\n MailboxUsage,\n} from '../mailbox';\nimport { MailboxStreamClosedError } from '../mailbox';\nimport type { QuotaStore } from '../quota';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport { registerArchiveAccess } from './archive-access';\nimport { assertCanonicalTimestamp } from '../time';\n\nconst DEFAULT_READ_LIMIT = 50;\n\ninterface DeviceMailbox {\n nextSeq: number;\n deliveredSeq: number;\n ackedSeq: number;\n cursorUpdatedAt: string;\n closed: { readonly at: string; readonly cause: MailboxStreamCloseCause } | undefined;\n mutationTail: Promise<void>;\n readonly messages: MailboxMessage[];\n readonly byMessageId: Map<string, MailboxMessage>;\n}\n\nexport class InMemoryMailboxStore implements MailboxStore {\n readonly #devices = new Map<string, DeviceMailbox>();\n readonly #clock: Clock;\n readonly #quota: Pick<QuotaStore, 'readEntitlement'>;\n\n /** The mailbox reads its limit from quota; quota never reads the mailbox. */\n constructor(clock: Clock, quota: Pick<QuotaStore, 'readEntitlement'>) {\n this.#clock = clock;\n this.#quota = quota;\n registerArchiveAccess(this, {\n messagesOf: (tenant, deviceId) => this.#devices.get(tenantKey(tenant, deviceId))?.messages ?? [],\n replaceBody: (tenant, deviceId, seq, body) => {\n const device = this.#devices.get(tenantKey(tenant, deviceId));\n const index = device?.messages.findIndex((message) => message.seq === seq) ?? -1;\n if (device === undefined || index < 0) return;\n const replaced: MailboxMessage = { ...device.messages[index]!, ...body };\n device.messages[index] = replaced;\n device.byMessageId.set(replaced.messageId, replaced);\n },\n });\n }\n\n async append(tenant: TenantId, input: MailboxAppendInput): Promise<MailboxMessage> {\n const device = this.#device(tenant, input.deviceId);\n const appended = device.mutationTail.then(async () => {\n if (device.closed !== undefined) throw new MailboxStreamClosedError(input.deviceId, device.closed.cause);\n const existing = device.byMessageId.get(input.messageId);\n if (existing !== undefined) return existing;\n\n // Anything but the one exempt class is limited: an unknown admission\n // fails closed instead of skipping the check.\n const limit =\n input.admission === 'cancellation' ? undefined : await this.#mailboxLimit(tenant);\n const seq = device.nextSeq;\n const materialized = await input.materialize(seq);\n // No await from here to the push: the sum, the check and the insert are\n // one synchronous step, so the check is exact across devices.\n if (limit !== undefined) {\n const used = this.#usedBytes(tenant);\n if (used + materialized.byteSize > limit) {\n throw new ByokCoreError(\n 'storage_quota_exceeded',\n `Mailbox would reach ${String(used + materialized.byteSize)} bytes, over the limit of ${String(limit)} bytes.`,\n );\n }\n }\n const message: MailboxMessage = {\n tenantId: tenant,\n deviceId: input.deviceId,\n seq,\n messageId: input.messageId,\n ...materialized,\n state: 'pending',\n appendedAt: this.#now(),\n };\n device.nextSeq += 1;\n device.messages.push(message);\n device.byMessageId.set(message.messageId, message);\n return message;\n });\n // A failed materializer rejects its own append but must not poison the\n // per-device serializer; the next append starts from the same sequence.\n device.mutationTail = appended.then(\n () => undefined,\n () => undefined,\n );\n return appended;\n }\n\n async readUsage(tenant: TenantId): Promise<MailboxUsage> {\n return { bytes: this.#usedBytes(tenant) };\n }\n\n async readAfter(tenant: TenantId, query: MailboxReadQuery): Promise<MailboxPage> {\n const device = this.#devices.get(tenantKey(tenant, query.deviceId));\n const limit = query.limit ?? DEFAULT_READ_LIMIT;\n if (device === undefined) {\n // A device with no mailbox has lost nothing, so cursor 0 is inside its\n // (empty) window rather than behind a floor it could never have met.\n return { messages: [], nextSeq: query.afterSeq, hasMore: false, recoverableFrom: 1 };\n }\n const pending = device.messages\n .filter((message) => message.state === 'pending' && message.seq > query.afterSeq)\n .sort((left, right) => left.seq - right.seq);\n const page = pending.slice(0, limit);\n const last = page.at(-1);\n return {\n messages: page,\n // Reading is not acknowledging: the returned position is a *read* cursor.\n // Nothing above was mutated, so an identical call replays the same page.\n nextSeq: last?.seq ?? query.afterSeq,\n hasMore: pending.length > page.length,\n // Computed over the WHOLE mailbox, not the queried slice: the floor is a\n // property of the device's history, and reporting it relative to\n // `afterSeq` would make every cursor look recoverable from itself.\n recoverableFrom: this.#recoverableFrom(device),\n };\n }\n\n async advanceCursor(\n tenant: TenantId,\n input: MailboxAdvanceCursorInput,\n ): Promise<MailboxCursorState> {\n const device = this.#device(tenant, input.deviceId);\n const advanced = device.mutationTail.then(() => {\n if (input.ackedSeq < device.ackedSeq) {\n throw new CoreConflictError(\n 'mailbox_cursor_regression',\n `Cursor for device ${input.deviceId} is at ${device.ackedSeq}; refusing to move it back to ${input.ackedSeq}.`,\n this.#cursorState(tenant, input.deviceId, device),\n this.#now(),\n );\n }\n if (input.ackedSeq > device.deliveredSeq) {\n throw new CoreConflictError(\n 'mailbox_cursor_ahead_of_delivery',\n `Cursor for device ${input.deviceId} was delivered through ${device.deliveredSeq}; refusing to acknowledge future cursor ${input.ackedSeq}.`,\n this.#cursorState(tenant, input.deviceId, device),\n this.#now(),\n );\n }\n device.ackedSeq = input.ackedSeq;\n device.cursorUpdatedAt = this.#now();\n for (const [index, message] of device.messages.entries()) {\n if (message.state === 'pending' && message.seq <= input.ackedSeq) {\n device.messages[index] = { ...message, state: 'acked' };\n device.byMessageId.set(message.messageId, device.messages[index]!);\n }\n }\n return this.#cursorState(tenant, input.deviceId, device);\n });\n device.mutationTail = advanced.then(\n () => undefined,\n () => undefined,\n );\n return advanced;\n }\n\n async recordDelivery(\n tenant: TenantId,\n input: MailboxRecordDeliveryInput,\n ): Promise<MailboxCursorState> {\n const device = this.#device(tenant, input.deviceId);\n const recorded = device.mutationTail.then(() => {\n if (input.deliveredSeq > device.deliveredSeq) {\n device.deliveredSeq = input.deliveredSeq;\n }\n return this.#cursorState(tenant, input.deviceId, device);\n });\n device.mutationTail = recorded.then(\n () => undefined,\n () => undefined,\n );\n return recorded;\n }\n\n async readCursor(tenant: TenantId, deviceId: string): Promise<MailboxCursorState> {\n const device = this.#devices.get(tenantKey(tenant, deviceId));\n if (device === undefined) {\n return { tenantId: tenant, deviceId, deliveredSeq: 0, ackedSeq: 0, updatedAt: this.#now() };\n }\n return this.#cursorState(tenant, deviceId, device);\n }\n\n async collectExpired(tenant: TenantId, input: MailboxCollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n assertCanonicalTimestamp(input.ackedBefore, 'ackedBefore');\n assertCanonicalTimestamp(input.expireUnackedBefore, 'expireUnackedBefore');\n assertCanonicalTimestamp(input.reapDeadLettersBefore, 'reapDeadLettersBefore');\n let removed = 0, expired = 0, more = false;\n // The reap runs before this call's expiry, so only rows that were already\n // `expired` qualify, and never the device's highest-seq dead letter: that\n // row is the recoverableFrom floor.\n const reapable = (device: DeviceMailbox, message: MailboxMessage): boolean =>\n message.state === 'expired' && message.appendedAt < input.reapDeadLettersBefore\n && device.messages.some((other) => other.state === 'expired' && other.seq > message.seq);\n try {\n phases: for (const phase of ['acked', 'reap', 'pending'] as const) {\n for (const [key, device] of this.#devices) {\n if (!key.startsWith(tenantKey(tenant, ''))) continue;\n const collected = device.mutationTail.then(() => {\n for (let index = 0; index < device.messages.length;) {\n const message = device.messages[index]!;\n const eligible = phase === 'reap'\n ? reapable(device, message)\n : message.state === phase\n && message.appendedAt < (phase === 'acked' ? input.ackedBefore : input.expireUnackedBefore);\n if (!eligible) { index++; continue; }\n if (removed + expired === input.limit) { more = true; return; }\n if (phase === 'pending') {\n const retired: MailboxMessage = { ...message, state: 'expired' };\n device.messages[index] = retired;\n device.byMessageId.set(retired.messageId, retired);\n expired++; index++;\n } else {\n device.messages.splice(index, 1);\n device.byMessageId.delete(message.messageId);\n removed++;\n }\n }\n });\n device.mutationTail = collected.then(() => undefined, () => undefined);\n await collected;\n if (more) break phases;\n }\n }\n // This call's expiry can leave rows reapable for the next call.\n if (!more) {\n more = [...this.#devices].some(([key, device]) => key.startsWith(tenantKey(tenant, ''))\n && device.messages.some((message) => reapable(device, message)));\n }\n } catch (cause) {\n throw new CollectExpiredFailure({ removed, expired, releasedBytes: 0n }, 0, undefined, { cause });\n }\n // Mailbox usage is the pending rows, never a mutable accounting counter, so no phase moves it.\n return { removed, expired, releasedBytes: 0n, more };\n }\n\n async expirePending(tenant: TenantId, input: MailboxExpirePendingInput): Promise<{ readonly expired: number }> {\n const device = this.#devices.get(tenantKey(tenant, input.deviceId));\n if (device === undefined) return { expired: 0 };\n const selected = new Set(input.seqs);\n return this.#serialize(device, () => expirePendingMessages(device, (message) => selected.has(message.seq)));\n }\n\n async closeStream(tenant: TenantId, input: MailboxCloseStreamInput): Promise<{ readonly expired: number }> {\n const device = this.#device(tenant, input.deviceId);\n return this.#serialize(device, () => {\n device.closed = { at: device.closed?.at ?? this.#now(), cause: input.cause };\n return expirePendingMessages(device, () => true);\n });\n }\n\n async reopenStream(tenant: TenantId, input: MailboxReopenStreamInput): Promise<void> {\n const device = this.#devices.get(tenantKey(tenant, input.deviceId));\n if (device === undefined) return;\n await this.#serialize(device, () => {\n device.closed = undefined;\n });\n }\n\n /** Runs one synchronous step on the device's chain, whatever the previous step's outcome. */\n #serialize<T>(device: DeviceMailbox, step: () => T): Promise<T> {\n const run = device.mutationTail.then(step);\n device.mutationTail = run.then(() => undefined, () => undefined);\n return run;\n }\n\n async #mailboxLimit(tenant: TenantId): Promise<bigint> {\n const entitlement = await this.#quota.readEntitlement(tenant);\n if (entitlement === undefined) {\n throw new ByokCoreError(\n 'storage_entitlement_missing',\n 'No storage entitlement has been issued for this tenant.',\n );\n }\n return entitlement.mailboxLimitBytes;\n }\n\n /**\n * Every `pending` row of the tenant, on any device. Acked and dead-lettered\n * rows are retained but hold no quota (#1115).\n */\n #usedBytes(tenant: TenantId): bigint {\n const prefix = tenantKey(tenant, '');\n let bytes = 0n;\n for (const [key, device] of this.#devices.entries()) {\n if (!key.startsWith(prefix)) continue;\n for (const message of device.messages) {\n if (message.state === 'pending') bytes += message.byteSize;\n }\n }\n return bytes;\n }\n\n #device(tenant: TenantId, deviceId: string): DeviceMailbox {\n if (deviceId.length === 0) {\n throw new ByokCoreError('mailbox_message_not_found', 'Device id must not be empty.');\n }\n const key = tenantKey(tenant, deviceId);\n const existing = this.#devices.get(key);\n if (existing !== undefined) return existing;\n const created: DeviceMailbox = {\n nextSeq: 1,\n deliveredSeq: 0,\n ackedSeq: 0,\n cursorUpdatedAt: this.#now(),\n closed: undefined,\n mutationTail: Promise.resolve(),\n messages: [],\n byMessageId: new Map(),\n };\n this.#devices.set(key, created);\n return created;\n }\n\n /**\n * One past the highest row this device lost, which is exactly the highest\n * `expired` seq: dead-lettered rows are kept rather than deleted (§12.7.5),\n * so the loss stays observable and needs no column of its own to remember it.\n *\n * `acked` is deliberately not counted. A consumed row is not a lost one, and\n * counting it would turn a daemon re-polling from an old cursor — which the\n * at-least-once contract explicitly allows — into a hard failure.\n */\n #recoverableFrom(device: DeviceMailbox): number {\n let lost = 0;\n for (const message of device.messages) {\n if (message.state === 'expired' && message.seq > lost) lost = message.seq;\n }\n return lost + 1;\n }\n\n #cursorState(\n tenant: TenantId,\n deviceId: string,\n device: DeviceMailbox,\n ): MailboxCursorState {\n return {\n tenantId: tenant,\n deviceId,\n deliveredSeq: device.deliveredSeq,\n ackedSeq: device.ackedSeq,\n updatedAt: device.cursorUpdatedAt,\n };\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n\n/** Moves the selected `pending` rows to `expired`; nothing else changes. */\nfunction expirePendingMessages(device: DeviceMailbox, selected: (message: MailboxMessage) => boolean): { readonly expired: number } {\n let expired = 0;\n for (const [index, message] of device.messages.entries()) {\n if (message.state !== 'pending' || !selected(message)) continue;\n const dead: MailboxMessage = { ...message, state: 'expired' };\n device.messages[index] = dead;\n device.byMessageId.set(dead.messageId, dead);\n expired++;\n }\n return { expired };\n}\n","import { InMemoryStorageLedger } from './storage-ledger';\nimport { assertCollectExpiredInput, CollectExpiredFailure, type CollectExpiredResult } from '../retention';\nimport type { ObjectCollectExpiredInput } from '../blob';\n/**\n * In-memory {@link ObjectStore} reference (§12.7.4, §12.7.8).\n *\n * Metadata only — there are no bytes here, and there are none in the Postgres\n * composition either: the manifest is the transaction authority and the object\n * store holds the payload. `refCount` is derived from the reference rows rather\n * than incremented in place, so a double `addReference` for the same\n * `(refKind, refId)` cannot inflate it and strand an object forever.\n */\nimport {\n isLegalObjectTransition,\n type ContentHash,\n type ObjectCommitInput,\n type ObjectListQuery,\n type ObjectManifestEntry,\n type ObjectManifestInput,\n type ObjectReference,\n type ObjectReferenceInput,\n type ObjectStore,\n} from '../blob';\nimport { ByokCoreError } from '../errors';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport { assertCanonicalTimestamp } from '../time';\nimport { registerArchiveAccess } from './archive-access';\n\nconst DEFAULT_LIST_LIMIT = 100;\n\nexport class InMemoryObjectStore implements ObjectStore {\n readonly #manifest = new Map<string, ObjectManifestEntry>();\n readonly #references = new Map<string, ObjectReference>();\n readonly #clock: Clock;\n readonly #deleteCursor = new Map<TenantId, string>();\n\n constructor(clock: Clock, private readonly maintenance: { readonly ledger: InMemoryStorageLedger; readonly bytes: InMemoryObjectBytes }) {\n this.#clock = clock;\n if (maintenance === undefined || maintenance.ledger === undefined ||\n typeof maintenance.bytes?.deleteObject !== 'function') {\n throw new ByokCoreError('retention_input_invalid', 'ObjectStore requires its shared ledger and an explicit byte authority.');\n }\n registerArchiveAccess(this, {\n releaseReferences: (tenant, refKind, refId) => {\n const hashes = new Set<ContentHash>();\n let released = 0;\n for (const [key, reference] of this.#references) {\n if (reference.tenantId !== tenant || reference.refKind !== refKind || reference.refId !== refId) continue;\n this.#references.delete(key);\n hashes.add(reference.hash);\n released += 1;\n }\n for (const hash of hashes) {\n const entry = this.#manifest.get(tenantKey(tenant, hash));\n if (entry !== undefined) this.#recount(tenant, entry);\n }\n return released;\n },\n });\n }\n\n async putManifest(\n tenant: TenantId,\n input: ObjectManifestInput,\n ): Promise<ObjectManifestEntry> {\n const key = tenantKey(tenant, input.hash);\n const existing = this.#manifest.get(key);\n if (existing !== undefined && existing.state !== 'deleted') return existing;\n\n const now = this.#now();\n const entry: ObjectManifestEntry = {\n tenantId: tenant,\n hash: input.hash,\n byteSize: input.byteSize,\n contentType: input.contentType,\n state: 'pending',\n refCount: 0,\n createdAt: now,\n updatedAt: now,\n };\n this.#manifest.set(key, entry);\n return entry;\n }\n\n async commit(tenant: TenantId, input: ObjectCommitInput): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, input.hash);\n if (\n entry.byteSize !== input.observedByteSize ||\n entry.contentType !== input.observedContentType\n ) {\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Observed object ${input.hash} (${String(input.observedByteSize)} bytes, ${input.observedContentType}) does not match the declared manifest.`,\n );\n }\n if (entry.state === 'committed') return entry;\n return this.#transition(tenant, entry, 'committed');\n }\n\n async get(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry | undefined> {\n return this.#manifest.get(tenantKey(tenant, hash));\n }\n\n async list(\n tenant: TenantId,\n query: ObjectListQuery,\n ): Promise<readonly ObjectManifestEntry[]> {\n // The cutoff is compared against `deletePendingAt` as a string below, which\n // only equals a time comparison for the canonical form. A GC sweep reading\n // a mis-parsed cutoff would either miss tombstones or take live ones.\n if (query.deletePendingBefore !== undefined) {\n assertCanonicalTimestamp(query.deletePendingBefore, 'deletePendingBefore');\n }\n const prefix = tenantKey(tenant, '');\n const matches: ObjectManifestEntry[] = [];\n for (const [key, entry] of this.#manifest.entries()) {\n if (!key.startsWith(prefix)) continue;\n if (query.state !== undefined && entry.state !== query.state) continue;\n if (query.deletePendingBefore !== undefined) {\n if (entry.deletePendingAt === undefined) continue;\n if (entry.deletePendingAt >= query.deletePendingBefore) continue;\n }\n matches.push(entry);\n }\n matches.sort((left, right) => left.hash.localeCompare(right.hash));\n return matches.slice(0, query.limit ?? DEFAULT_LIST_LIMIT);\n }\n\n async addReference(\n tenant: TenantId,\n input: ObjectReferenceInput,\n ): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, input.hash);\n if (entry.state !== 'committed') {\n throw new ByokCoreError(\n 'object_state_invalid',\n `Only committed objects can be referenced; ${input.hash} is ${entry.state}.`,\n );\n }\n const refKey = tenantKey(tenant, input.hash, input.refKind, input.refId);\n if (!this.#references.has(refKey)) {\n this.#references.set(refKey, {\n tenantId: tenant,\n hash: input.hash,\n refKind: input.refKind,\n refId: input.refId,\n createdAt: this.#now(),\n });\n }\n return this.#recount(tenant, entry);\n }\n\n async removeReference(\n tenant: TenantId,\n input: ObjectReferenceInput,\n ): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, input.hash);\n this.#references.delete(tenantKey(tenant, input.hash, input.refKind, input.refId));\n return this.#recount(tenant, entry);\n }\n\n async markDeletePending(\n tenant: TenantId,\n hash: ContentHash,\n ): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, hash);\n if (entry.refCount !== 0) {\n throw new ByokCoreError(\n 'object_state_invalid',\n `Object ${hash} still has ${entry.refCount} reference(s).`,\n );\n }\n return this.#transition(tenant, entry, 'delete_pending');\n }\n\n async markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, hash);\n return this.#transition(tenant, entry, 'deleted');\n }\n\n async collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n assertCanonicalTimestamp(input.orphanBefore, 'orphanBefore');\n const eligible = (entry: ObjectManifestEntry): boolean => entry.tenantId === tenant && entry.refCount === 0\n && !this.maintenance.ledger.hasReservedObject(tenant, entry.hash)\n && (entry.state === 'delete_pending' || ((entry.state === 'pending' || entry.state === 'committed') && entry.updatedAt < input.orphanBefore));\n let removed = 0, releasedBytes = 0n, more = false, visited = 0, failures = 0;\n let firstFailure: unknown;\n const cursor = this.#deleteCursor.get(tenant) ?? '';\n // Retry tombstones first. Each distinct object consumes one shared slot.\n const entries = [...this.#manifest.values()].filter(eligible);\n const pending = entries.filter(entry => entry.state === 'delete_pending').sort((a, b) => a.hash.localeCompare(b.hash));\n const first = pending.filter(entry => entry.hash > cursor).slice(0, input.limit);\n const fresh = entries.filter(entry => entry.state !== 'delete_pending').sort((a, b) => a.updatedAt.localeCompare(b.updatedAt) || a.hash.localeCompare(b.hash)).slice(0, input.limit - first.length);\n const wrapped = pending.filter(entry => entry.hash <= cursor).slice(0, input.limit - first.length - fresh.length);\n const candidates = [...first, ...fresh, ...wrapped];\n more = entries.length > candidates.length;\n for (const candidate of candidates) {\n if (visited++ === input.limit) { more = true; break; }\n const entry = this.#manifest.get(tenantKey(tenant, candidate.hash))!;\n if (!eligible(entry)) continue;\n const pending = entry.state === 'delete_pending' ? entry : { ...entry, state: 'delete_pending' as const, deletePendingAt: input.now, updatedAt: input.now };\n this.#manifest.set(tenantKey(tenant, entry.hash), pending);\n try {\n // No await may split protection, byte deletion and accounting.\n const release = this.maintenance.ledger.prepareCollectedObjectRelease(tenant, entry.hash, entry.byteSize, input.now);\n this.maintenance.bytes.deleteObject(tenant, entry.hash);\n release.commit();\n const released = release.releasedBytes;\n this.#manifest.set(tenantKey(tenant, entry.hash), { ...pending, state: 'deleted', updatedAt: input.now });\n removed++; releasedBytes += released;\n } catch (cause) {\n failures++; firstFailure ??= cause;\n }\n }\n this.#deleteCursor.set(tenant, wrapped.at(-1)?.hash ?? first.at(-1)?.hash ?? '');\n if (failures > 0) throw new CollectExpiredFailure({ removed, expired: 0, releasedBytes }, failures, true, { cause: firstFailure });\n return { removed, expired: 0, releasedBytes, more };\n }\n\n #transition(\n tenant: TenantId,\n entry: ObjectManifestEntry,\n next: ObjectManifestEntry['state'],\n ): ObjectManifestEntry {\n if (!isLegalObjectTransition(entry.state, next)) {\n throw new ByokCoreError(\n 'object_state_invalid',\n `${entry.state} to ${next} is not a legal object manifest transition.`,\n );\n }\n const now = this.#now();\n const updated: ObjectManifestEntry = {\n ...entry,\n state: next,\n updatedAt: now,\n ...(next === 'delete_pending' ? { deletePendingAt: now } : {}),\n };\n this.#manifest.set(tenantKey(tenant, entry.hash), updated);\n return updated;\n }\n\n #recount(tenant: TenantId, entry: ObjectManifestEntry): ObjectManifestEntry {\n const refPrefix = tenantKey(tenant, entry.hash, '');\n let refCount = 0;\n for (const key of this.#references.keys()) {\n if (key.startsWith(refPrefix)) refCount += 1;\n }\n const updated: ObjectManifestEntry = { ...entry, refCount, updatedAt: this.#now() };\n this.#manifest.set(tenantKey(tenant, entry.hash), updated);\n return updated;\n }\n\n #require(tenant: TenantId, hash: ContentHash): ObjectManifestEntry {\n const entry = this.#manifest.get(tenantKey(tenant, hash));\n if (entry === undefined) {\n throw new ByokCoreError(\n 'object_not_found',\n `Object ${hash} has no manifest row in this tenant.`,\n );\n }\n return entry;\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n\nexport interface InMemoryObjectBytes {\n deleteObject(tenant: TenantId, hash: ContentHash): void;\n}\n","import { CollectExpiredFailure } from '../retention';\nimport { InMemoryStorageLedger, type ReservationRecord } from './storage-ledger';\nimport { assertCollectExpiredInput, type CollectExpiredResult } from '../retention';\nimport type { QuotaCollectExpiredInput } from '../quota';\n/**\n * In-memory {@link QuotaStore} reference (§12.7.6-12.7.7).\n *\n * The invariant this file exists to hold is\n * `committed + reserved + expected <= hardLimitBytes`, checked inside\n * {@link InMemoryQuotaStore.reserve} before any bytes are handed out. A\n * Postgres composition does the same check inside a row-locked transaction;\n * both must reject the same set of concurrent reservations, which is what the\n * conformance suite asserts.\n *\n * Per-tenant hash deduplication lives here rather than in the object manifest\n * because usage accounting is what deduplication is *for* (§12.7.6: same\n * tenant, same hash, counted once). In SQL this set is a join against\n * `object_manifest`; here it is an explicit set, and the observable behavior is\n * identical: finalizing an already-committed hash releases the reservation and\n * adds nothing.\n */\nimport { ByokCoreError, CoreConflictError } from '../errors';\nimport type { ObjectStore } from '../blob';\nimport type {\n StorageFinalizeInput,\n StorageFinalizeResult,\n StorageReservation,\n StorageReservationInput,\n StorageStatus,\n StorageWritePosture,\n QuotaStore,\n TenantStorageEntitlement,\n TenantStorageEntitlementInput,\n TenantStorageUsage,\n} from '../quota';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport { assertCanonicalTimestamp } from '../time';\n\n/** Warning threshold from §12.7.8: 80% of the hard limit. */\nconst WARNING_NUMERATOR = 80n;\nconst WARNING_DENOMINATOR = 100n;\n\n\n\nexport class InMemoryQuotaStore implements QuotaStore {\n readonly #entitlements = new Map<string, TenantStorageEntitlement>();\n readonly #clock: Clock;\n readonly #objects: ObjectStore;\n\n constructor(clock: Clock, objects: ObjectStore, private readonly ledger: InMemoryStorageLedger) {\n this.#clock = clock;\n this.#objects = objects;\n }\n\n async readEntitlement(tenant: TenantId): Promise<TenantStorageEntitlement | undefined> {\n return this.#entitlements.get(tenant);\n }\n\n async writeEntitlement(\n tenant: TenantId,\n input: TenantStorageEntitlementInput,\n ): Promise<TenantStorageEntitlement> {\n // Validated before the version CAS: an unusable deadline is a bad write\n // regardless of which version wins, and `readStatus` compares this field as\n // a string (canonical form is what makes that equal a time comparison).\n if (input.downgradeGraceUntil !== undefined) {\n assertCanonicalTimestamp(input.downgradeGraceUntil, 'downgradeGraceUntil');\n }\n const existing = this.#entitlements.get(tenant);\n if (existing !== undefined && input.version <= existing.version) {\n throw new CoreConflictError(\n 'storage_entitlement_version_conflict',\n `Entitlement is at version ${String(existing.version)}; refusing to apply version ${String(input.version)}.`,\n existing,\n this.#now(),\n );\n }\n const entitlement: TenantStorageEntitlement = {\n tenantId: tenant,\n version: input.version,\n hardLimitBytes: input.hardLimitBytes,\n maxObjectBytes: input.maxObjectBytes,\n maxInlineBytes: input.maxInlineBytes,\n mailboxLimitBytes: input.mailboxLimitBytes,\n retentionPolicyId: input.retentionPolicyId,\n ...(input.downgradeGraceUntil === undefined\n ? {}\n : { downgradeGraceUntil: input.downgradeGraceUntil }),\n };\n this.#entitlements.set(tenant, entitlement);\n return entitlement;\n }\n\n async readUsage(tenant: TenantId): Promise<TenantStorageUsage> {\n return this.#usageOf(tenant);\n }\n\n async readStatus(tenant: TenantId): Promise<StorageStatus> {\n const entitlement = this.#requireEntitlement(tenant);\n const usage = this.#usageOf(tenant);\n const used = this.#usedBytes(usage);\n const graceActive =\n entitlement.downgradeGraceUntil !== undefined &&\n this.#now() < entitlement.downgradeGraceUntil;\n return {\n entitlement,\n usage,\n posture: this.#posture(entitlement, usage, graceActive),\n availableBytes:\n used >= entitlement.hardLimitBytes ? 0n : entitlement.hardLimitBytes - used,\n graceActive,\n };\n }\n\n async readReservation(\n tenant: TenantId,\n reservationId: string,\n ): Promise<StorageReservation | undefined> {\n return this.ledger.readReservation(tenantKey(tenant, reservationId))?.reservation;\n }\n\n async reserve(\n tenant: TenantId,\n input: StorageReservationInput,\n ): Promise<StorageReservation> {\n const entitlement = this.#requireEntitlement(tenant);\n // Admission is the bounded product-side reap point. A daemon may die\n // after receiving a grant and never call finalize/abort; expired holds\n // therefore have to be settled before they can deny the next write.\n // Exhaust the same expiry iterator used by the bounded maintenance pass.\n await Array.from(this.#expireReservations(tenant));\n const key = tenantKey(tenant, input.reservationId);\n const existing = this.ledger.readReservation(key);\n if (existing !== undefined) {\n if (existing.reservation.state === 'reserved') {\n if (\n existing.reservation.kind !== input.kind ||\n existing.reservation.expectedBytes !== input.expectedBytes ||\n existing.reservation.contentHash !== input.contentHash ||\n existing.reservation.contentType !== input.contentType\n ) {\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Reservation ${input.reservationId} already binds a different storage declaration.`,\n );\n }\n return existing.reservation;\n }\n throw new ByokCoreError(\n 'storage_reservation_expired',\n `Reservation ${input.reservationId} is already ${existing.reservation.state}.`,\n );\n }\n\n const usage = this.#usageOf(tenant);\n const graceActive =\n entitlement.downgradeGraceUntil !== undefined &&\n this.#now() < entitlement.downgradeGraceUntil;\n if (this.#posture(entitlement, usage, graceActive) === 'suspended') {\n throw new ByokCoreError(\n 'storage_write_suspended',\n 'Tenant is over its hard limit and its downgrade grace has ended; durable writes are suspended.',\n );\n }\n\n const perObjectLimit =\n input.kind === 'object' ? entitlement.maxObjectBytes : entitlement.maxInlineBytes;\n if (input.expectedBytes > perObjectLimit) {\n throw new ByokCoreError(\n 'storage_object_too_large',\n `${String(input.expectedBytes)} bytes exceeds the ${input.kind} limit of ${String(perObjectLimit)} bytes.`,\n );\n }\n if (this.#usedBytes(usage) + input.expectedBytes > entitlement.hardLimitBytes) {\n throw new ByokCoreError(\n 'storage_quota_exceeded',\n `Reserving ${String(input.expectedBytes)} bytes would exceed the hard limit of ${String(entitlement.hardLimitBytes)} bytes.`,\n );\n }\n\n const now = this.#now();\n const reservation: StorageReservation = {\n tenantId: tenant,\n reservationId: input.reservationId,\n state: 'reserved',\n kind: input.kind,\n expectedBytes: input.expectedBytes,\n contentHash: input.contentHash,\n contentType: input.contentType,\n createdAt: now,\n expiresAt: new Date(this.#clock.now().getTime() + input.ttlMs).toISOString(),\n };\n this.ledger.writeReservation(key, { reservation, deduplicated: false });\n this.#setUsage(tenant, { ...usage, reservedBytes: usage.reservedBytes + input.expectedBytes });\n return reservation;\n }\n\n async finalizeReservation(\n tenant: TenantId,\n input: StorageFinalizeInput,\n ): Promise<StorageFinalizeResult> {\n const key = tenantKey(tenant, input.reservationId);\n const record = this.#requireReservation(tenant, input.reservationId);\n const reservation = record.reservation;\n\n if (reservation.state === 'committed') {\n return {\n reservation,\n usage: this.#usageOf(tenant),\n deduplicated: record.deduplicated,\n };\n }\n if (reservation.state !== 'reserved') {\n throw new ByokCoreError(\n 'storage_reservation_expired',\n `Reservation ${input.reservationId} is ${reservation.state}.`,\n );\n }\n if (this.#now() >= reservation.expiresAt) {\n this.#settle(tenant, key, record, 'expired');\n throw new ByokCoreError(\n 'storage_reservation_expired',\n `Reservation ${input.reservationId} expired at ${reservation.expiresAt}.`,\n );\n }\n if (\n input.observedByteSize !== reservation.expectedBytes ||\n input.observedContentType !== reservation.contentType\n ) {\n // §12.7.7 step 6: a failed finalize releases the bytes; the uploaded\n // object becomes an orphan candidate for the GC worker.\n this.#settle(tenant, key, record, 'aborted');\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Observed object does not match reservation ${input.reservationId}.`,\n );\n }\n\n if (reservation.kind === 'object') {\n try {\n await this.#objects.commit(tenant, {\n hash: reservation.contentHash,\n observedByteSize: input.observedByteSize,\n observedContentType: input.observedContentType,\n });\n } catch (error) {\n this.#settle(tenant, key, record, 'aborted');\n if (\n error instanceof ByokCoreError &&\n (error.code === 'object_not_found' || error.code === 'object_state_invalid')\n ) {\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Reservation ${input.reservationId} has no committable object manifest.`,\n { cause: error },\n );\n }\n throw error;\n }\n }\n\n // Same tenant, same hash, counted once (§12.7.6). `#settle` has already\n // released the reserved bytes, so a deduplicated finalize adds nothing.\n const deduplicated = this.ledger.isCounted(tenant, reservation.contentHash);\n const settled = this.#settle(tenant, key, record, 'committed', deduplicated);\n\n if (!deduplicated) {\n this.ledger.recordCommitted(tenant, reservation);\n const current = this.#usageOf(tenant);\n this.#setUsage(tenant, {\n ...current,\n committedObjectBytes:\n reservation.kind === 'object'\n ? current.committedObjectBytes + reservation.expectedBytes\n : current.committedObjectBytes,\n committedInlineBytes:\n reservation.kind === 'inline'\n ? current.committedInlineBytes + reservation.expectedBytes\n : current.committedInlineBytes,\n objectCount:\n reservation.kind === 'object' ? current.objectCount + 1n : current.objectCount,\n });\n }\n\n return { reservation: settled, usage: this.#usageOf(tenant), deduplicated };\n }\n\n async abortReservation(\n tenant: TenantId,\n reservationId: string,\n ): Promise<StorageReservation> {\n const key = tenantKey(tenant, reservationId);\n const record = this.#requireReservation(tenant, reservationId);\n if (record.reservation.state !== 'reserved') return record.reservation;\n return this.#settle(tenant, key, record, 'aborted');\n }\n\n *#expireReservations(tenant: TenantId, now = this.#now(), limit = Number.MAX_SAFE_INTEGER): IterableIterator<StorageReservation> {\n const prefix = tenantKey(tenant, '');\n let expired = 0;\n for (const [key, record] of this.ledger.reservations()) {\n if (!key.startsWith(prefix) || record.reservation.state !== 'reserved' || now < record.reservation.expiresAt) continue;\n yield this.#settle(tenant, key, record, 'expired', false, now);\n if (++expired === limit) return;\n }\n }\n\n async collectExpired(tenant: TenantId, input: QuotaCollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n assertCanonicalTimestamp(input.settledBefore, 'settledBefore');\n let expired = 0, releasedBytes = 0n, removed = 0, more = false;\n try {\n for (const reservation of this.#expireReservations(tenant, input.now, input.limit)) {\n expired++;\n releasedBytes += reservation.expectedBytes;\n }\n } catch (cause) {\n throw new CollectExpiredFailure({ removed, expired, releasedBytes }, 1, true, { cause });\n }\n const prefix = tenantKey(tenant, '');\n try {\n for (const [key, record] of this.ledger.reservations()) {\n if (!key.startsWith(prefix)) continue;\n const row = record.reservation;\n const shouldExpire = row.state === 'reserved' && row.expiresAt <= input.now;\n const shouldRemove = (row.state === 'expired' || row.state === 'aborted') && row.settledAt !== undefined && row.settledAt < input.settledBefore;\n if (!shouldExpire && !shouldRemove) continue;\n if (shouldExpire || removed + expired === input.limit) { more = true; continue; }\n this.ledger.deleteReservation(key); removed++;\n }\n } catch (cause) {\n throw new CollectExpiredFailure({ removed, expired, releasedBytes }, 0, undefined, { cause });\n }\n return { removed, expired, releasedBytes, more };\n }\n\n #settle(\n tenant: TenantId,\n key: string,\n record: ReservationRecord,\n state: Exclude<StorageReservation['state'], 'reserved'>,\n deduplicated = false,\n settledAt = this.#now(),\n ): StorageReservation {\n const settled: StorageReservation = {\n ...record.reservation,\n state,\n settledAt,\n };\n const usage = this.#usageOf(tenant);\n if (usage.reservedBytes < record.reservation.expectedBytes) {\n throw new ByokCoreError('storage_integrity_mismatch', 'Reservation settlement would underflow reserved usage.');\n }\n this.ledger.writeReservation(key, { reservation: settled, deduplicated });\n this.#setUsage(tenant, { ...usage, reservedBytes: usage.reservedBytes - record.reservation.expectedBytes });\n return settled;\n }\n\n #posture(\n entitlement: TenantStorageEntitlement,\n usage: TenantStorageUsage,\n graceActive: boolean,\n ): StorageWritePosture {\n const used = this.#usedBytes(usage);\n if (used >= entitlement.hardLimitBytes) {\n // A tenant that was downgraded gets its configured grace window; once it\n // ends and usage is still over the limit, the tenant is read-only (423)\n // rather than merely unable to add bytes (507).\n const graceConfigured = entitlement.downgradeGraceUntil !== undefined;\n return graceConfigured && !graceActive ? 'suspended' : 'blocked';\n }\n if (\n entitlement.hardLimitBytes > 0n &&\n used * WARNING_DENOMINATOR >= entitlement.hardLimitBytes * WARNING_NUMERATOR\n ) {\n return 'warning';\n }\n return 'normal';\n }\n\n #usedBytes(usage: TenantStorageUsage): bigint {\n return usage.committedObjectBytes + usage.committedInlineBytes + usage.reservedBytes;\n }\n\n #usageOf(tenant: TenantId): TenantStorageUsage { return this.ledger.readUsage(tenant); }\n #setUsage(tenant: TenantId, usage: TenantStorageUsage): void {\n this.ledger.writeUsage(tenant, { ...usage, updatedAt: this.#now() });\n }\n\n #requireEntitlement(tenant: TenantId): TenantStorageEntitlement {\n const entitlement = this.#entitlements.get(tenant);\n if (entitlement === undefined) {\n throw new ByokCoreError(\n 'storage_entitlement_missing',\n 'No storage entitlement has been issued for this tenant.',\n );\n }\n return entitlement;\n }\n\n #requireReservation(tenant: TenantId, reservationId: string): ReservationRecord {\n const record = this.ledger.readReservation(tenantKey(tenant, reservationId));\n if (record === undefined) {\n throw new ByokCoreError(\n 'storage_reservation_not_found',\n `Reservation ${reservationId} does not exist in this tenant.`,\n );\n }\n return record;\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n","/**\n * In-memory {@link SkillPackStore} reference (plan `skill-pack-delivery-channel`).\n *\n * The interesting property is what `publish` refuses. This store cannot hash —\n * core has no crypto — so it is NOT the integrity authority for a pack, and it\n * does not pretend to be: the publisher mints the addresses and the installing\n * device re-derives and verifies every one of them. What this store CAN check\n * without crypto, it checks, and rejects rather than storing a pack whose\n * manifest and bytes already disagree at publish time: the declared path set\n * must be exactly the delivered path set, and every delivered file's UTF-8 byte\n * length must equal what its row declared.\n *\n * Storing that pair unchecked would be the worse failure mode by far — the\n * device would fetch, verify, reject, and have no way to tell a corrupt\n * publication from a tampered response.\n */\nimport {\n SKILL_PACK_ENTRY_PATH,\n checkSkillPackEntry,\n checkSkillPackManifest,\n type SkillPackFileContent,\n type SkillPackListQuery,\n type SkillPackManifest,\n type SkillPackPublishInput,\n type SkillPackStore,\n} from '../skill-pack';\nimport { ByokCoreError } from '../errors';\nimport { tenantKey, type TenantId } from '../tenant';\n\nconst DEFAULT_LIST_LIMIT = 50;\n\ninterface StoredPack {\n readonly manifest: SkillPackManifest;\n readonly contents: ReadonlyMap<string, string>;\n}\n\nexport class InMemorySkillPackStore implements SkillPackStore {\n readonly #packs = new Map<string, StoredPack>();\n\n async publish(tenant: TenantId, input: SkillPackPublishInput): Promise<SkillPackManifest> {\n const { manifest } = input;\n const structural = checkSkillPackManifest(manifest);\n if (!structural.ok) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${structural.reason} — ${structural.detail}`,\n );\n }\n\n const contents = new Map<string, string>();\n for (const file of input.files) {\n if (contents.has(file.path)) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(file.path)} was supplied twice.`,\n );\n }\n contents.set(file.path, file.content);\n }\n\n for (const declared of manifest.files) {\n const content = contents.get(declared.path);\n if (content === undefined) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(declared.path)} is declared but was not supplied.`,\n );\n }\n const bytes = new TextEncoder().encode(content).length;\n if (bytes !== declared.byteSize) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(declared.path)} declares ${declared.byteSize} bytes and supplies ${bytes}.`,\n );\n }\n }\n if (contents.size !== manifest.files.length) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${contents.size} files were supplied for ${manifest.files.length} declared rows.`,\n );\n }\n\n const entry = checkSkillPackEntry(manifest, contents.get(SKILL_PACK_ENTRY_PATH)!);\n if (!entry.ok) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${entry.reason} — ${entry.detail}`,\n );\n }\n\n this.#packs.set(tenantKey(tenant, manifest.name), { manifest, contents });\n return manifest;\n }\n\n async get(tenant: TenantId, name: string): Promise<SkillPackManifest | undefined> {\n return this.#packs.get(tenantKey(tenant, name))?.manifest;\n }\n\n async list(tenant: TenantId, query: SkillPackListQuery): Promise<readonly SkillPackManifest[]> {\n const prefix = tenantKey(tenant, '');\n const manifests: SkillPackManifest[] = [];\n for (const [key, pack] of this.#packs.entries()) {\n if (!key.startsWith(prefix)) continue;\n manifests.push(pack.manifest);\n }\n manifests.sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0));\n return manifests.slice(0, query.limit ?? DEFAULT_LIST_LIMIT);\n }\n\n async readFile(\n tenant: TenantId,\n name: string,\n path: string,\n ): Promise<SkillPackFileContent | undefined> {\n const pack = this.#packs.get(tenantKey(tenant, name));\n if (pack === undefined) return undefined;\n const declared = pack.manifest.files.find((file) => file.path === path);\n const content = pack.contents.get(path);\n if (declared === undefined || content === undefined) return undefined;\n return {\n path: declared.path,\n contentHash: declared.contentHash,\n byteSize: declared.byteSize,\n content,\n };\n }\n}\n","/**\n * In-memory {@link TruthStore} reference (§12.3, §12.6.4).\n *\n * Two write models, one storage shape. The terminal path is first-write-wins\n * with hash-equality replay; the snapshot path is `expectedRev` CAS. Neither\n * ever merges bodies — a conflict hands back the record it lost to and stops,\n * because the device holding the context is the only party that can decide what\n * the merged truth should be.\n */\nimport { CoreConflictError } from '../errors';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport type {\n SnapshotWriteInput,\n TerminalWriteInput,\n TruthManifestEntry,\n TruthManifestQuery,\n TruthRecord,\n TruthRecordSelector,\n TruthStore,\n} from '../truth';\n\nconst DEFAULT_MANIFEST_LIMIT = 100;\n\nexport class InMemoryTruthStore implements TruthStore {\n readonly #records = new Map<string, TruthRecord>();\n readonly #clock: Clock;\n\n constructor(clock: Clock) {\n this.#clock = clock;\n }\n\n async writeTerminal(tenant: TenantId, input: TerminalWriteInput): Promise<TruthRecord> {\n const key = tenantKey(tenant, 'task.terminal', input.taskId);\n const existing = this.#records.get(key);\n if (existing !== undefined) {\n if (existing.contentHash === input.contentHash) {\n // Exact replay of a committed fact: return the original, unchanged.\n return existing;\n }\n throw new CoreConflictError(\n 'terminal_conflict',\n `Task ${input.taskId} already has an immutable terminal record with a different hash.`,\n existing,\n this.#now(),\n );\n }\n const record: TruthRecord = {\n tenantId: tenant,\n kind: 'task.terminal',\n recordKey: input.taskId,\n rev: 1,\n contentHash: input.contentHash,\n byteSize: input.byteSize,\n body: input.body,\n ...(input.label === undefined ? {} : { label: input.label }),\n ...(input.requestId === undefined ? {} : { requestId: input.requestId }),\n writtenAt: this.#now(),\n };\n this.#records.set(key, record);\n return record;\n }\n\n async writeSnapshot(tenant: TenantId, input: SnapshotWriteInput): Promise<TruthRecord> {\n const key = tenantKey(tenant, input.kind, input.recordKey);\n const existing = this.#records.get(key);\n const currentRev = existing?.rev ?? 0;\n if (input.expectedRev !== currentRev) {\n throw new CoreConflictError<TruthRecord | undefined>(\n 'truth_revision_conflict',\n `Record ${input.kind}/${input.recordKey} is at rev ${currentRev}, not ${input.expectedRev}.`,\n existing,\n this.#now(),\n );\n }\n const record: TruthRecord = {\n tenantId: tenant,\n kind: input.kind,\n recordKey: input.recordKey,\n rev: currentRev + 1,\n contentHash: input.contentHash,\n byteSize: input.byteSize,\n body: input.body,\n ...(input.label === undefined ? {} : { label: input.label }),\n ...(input.requestId === undefined ? {} : { requestId: input.requestId }),\n writtenAt: this.#now(),\n };\n this.#records.set(key, record);\n return record;\n }\n\n async getRecord(\n tenant: TenantId,\n selector: TruthRecordSelector,\n ): Promise<TruthRecord | undefined> {\n return this.#records.get(tenantKey(tenant, selector.kind, selector.recordKey));\n }\n\n async listManifest(\n tenant: TenantId,\n query: TruthManifestQuery,\n ): Promise<readonly TruthManifestEntry[]> {\n const prefix = tenantKey(tenant, '');\n const entries: TruthManifestEntry[] = [];\n for (const [key, record] of this.#records.entries()) {\n if (!key.startsWith(prefix)) continue;\n if (query.kind !== undefined && record.kind !== query.kind) continue;\n if (query.keyPrefix !== undefined && !record.recordKey.startsWith(query.keyPrefix)) {\n continue;\n }\n entries.push({\n kind: record.kind,\n recordKey: record.recordKey,\n rev: record.rev,\n contentHash: record.contentHash,\n byteSize: record.byteSize,\n ...(record.label === undefined ? {} : { label: record.label }),\n updatedAt: record.writtenAt,\n });\n }\n entries.sort(\n (left, right) =>\n left.kind.localeCompare(right.kind) || left.recordKey.localeCompare(right.recordKey),\n );\n return entries.slice(0, query.limit ?? DEFAULT_MANIFEST_LIMIT);\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n","/**\n * A deterministic clock for the in-memory reference and the conformance suite.\n *\n * TTL behavior (presence expiry, activity expiry, reservation expiry) is part\n * of the contract, and asserting it against a wall clock means either sleeping\n * or accepting flakes. A composition under test injects one of these and moves\n * time explicitly.\n */\nimport type { MutableClock } from '../stores';\n\n/** Fixed start instant, so golden-ish assertions in the suite read the same on every run. */\nexport const IN_MEMORY_CLOCK_EPOCH = '2026-01-01T00:00:00.000Z';\n\nexport function createMutableClock(start: Date = new Date(IN_MEMORY_CLOCK_EPOCH)): MutableClock {\n let current = start.getTime();\n return {\n now(): Date {\n return new Date(current);\n },\n advance(ms: number): void {\n current += ms;\n },\n set(instant: Date): void {\n current = instant.getTime();\n },\n };\n}\n","import { assertCollectExpiredInput, type CollectExpiredInput, type CollectExpiredResult } from '../retention';\nimport type { TenantId } from '../tenant';\nimport type {\n DeviceAssertionReplayConsumeInput,\n DeviceAssertionReplayAuthority,\n} from '../device-assertion';\n\n/**\n * The reference key, in the SAME segment order as the durable primary key\n * (`deploy/sql/0022_task_assertion_replay_schema.sql`):\n * `(tenant_id, issuer, product_id, device_id, audience, schema, jti)`.\n *\n * The `schema` segment is what contract §8.2(2) requires: one `jti` presented\n * as a device assertion and as a task assertion produces two distinct keys, so\n * each lane is consumed exactly once and neither occupies the other's slot.\n * Order matters only in that it must match the SQL key — a reference authority\n * that keyed differently from the durable one would let the two implementations\n * disagree about which credentials collide.\n */\nfunction replayKey(input: DeviceAssertionReplayConsumeInput): string {\n return JSON.stringify([\n input.tenantId,\n input.issuer,\n input.productId,\n input.deviceId,\n input.audience,\n input.schema,\n input.jti,\n ]);\n}\n\n/** Process-local reference authority. Production runtimes need durable atomic storage. */\nexport class InMemoryDeviceAssertionReplayAuthority implements DeviceAssertionReplayAuthority {\n readonly #expiresAtByKey = new Map<string, number>();\n\n async consume(input: DeviceAssertionReplayConsumeInput): Promise<boolean> {\n const expiresAt = Date.parse(input.expiresAt);\n if (!Number.isFinite(expiresAt)) throw new Error('device assertion replay expiry is invalid');\n const key = replayKey(input);\n if (this.#expiresAtByKey.has(key)) return false;\n this.#expiresAtByKey.set(key, expiresAt);\n return true;\n }\n\n async collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n const cutoff = Date.parse(input.now);\n let removed = 0, more = false;\n for (const [key, expiresAt] of this.#expiresAtByKey) {\n if (JSON.parse(key)[0] !== tenant || expiresAt > cutoff) continue;\n if (removed === input.limit) { more = true; break; }\n this.#expiresAtByKey.delete(key); removed++;\n }\n return { removed, expired: 0, releasedBytes: 0n, more };\n }\n}\n","import { InMemoryStorageLedger } from './storage-ledger';\nimport type { InMemoryObjectBytes } from './blob';\n/**\n * The in-memory reference composition.\n *\n * This exists to be the first thing that passes the conformance suite, and to\n * stay the cheapest way to run it. It is a reference, not a production store:\n * everything lives in process memory and nothing survives a restart. What it\n * *does* guarantee is that the behavior the suite asserts is achievable without\n * a database, which is what makes the same assertions meaningful when a\n * Postgres + R2 composition runs them later.\n */\nimport { InMemoryPresenceStore } from './presence';\nimport { InMemoryBoardStore } from './board';\nimport { InMemoryMailboxStore } from './mailbox';\nimport { InMemoryObjectStore } from './blob';\nimport { InMemoryQuotaStore } from './quota';\nimport { InMemorySkillPackStore } from './skill-pack';\nimport { InMemoryTruthStore } from './truth';\nimport { createMutableClock } from './clock';\nimport type { Clock, CoreStores, MutableClock } from '../stores';\n\nexport { createMutableClock, IN_MEMORY_CLOCK_EPOCH } from './clock';\nexport { InMemoryMailboxStore } from './mailbox';\nexport { InMemoryBoardStore } from './board';\nexport { InMemoryTruthStore } from './truth';\nexport { InMemoryPresenceStore } from './presence';\nexport { InMemoryObjectStore } from './blob';\nexport { InMemoryQuotaStore } from './quota';\nexport { InMemorySkillPackStore } from './skill-pack';\nexport { InMemoryDeviceAssertionReplayAuthority } from './device-assertion-replay';\n\nexport interface InMemoryCoreOptions {\n readonly objectBytes: InMemoryObjectBytes;\n /** Defaults to a fresh {@link createMutableClock}, so TTL behavior is deterministic. */\n readonly clock?: Clock;\n}\n\nexport interface InMemoryCoreComposition {\n readonly stores: CoreStores;\n /** The clock the stores read. Mutable only when the caller did not inject its own. */\n readonly clock: Clock;\n}\n\nexport function createInMemoryCoreStores(\n options: InMemoryCoreOptions,\n): InMemoryCoreComposition {\n const clock: Clock = options.clock ?? createMutableClock();\n const ledger = new InMemoryStorageLedger(clock);\n const objects = new InMemoryObjectStore(clock, { ledger, bytes: options.objectBytes });\n const quota = new InMemoryQuotaStore(clock, objects, ledger);\n const stores: CoreStores = {\n mailbox: new InMemoryMailboxStore(clock, quota),\n board: new InMemoryBoardStore(clock),\n truth: new InMemoryTruthStore(clock),\n presence: new InMemoryPresenceStore(clock),\n objects,\n quota,\n skillPacks: new InMemorySkillPackStore(),\n };\n return { stores, clock };\n}\n\n/** Convenience for tests that need to move time: returns the composition and its mutable clock. */\nexport function createInMemoryCoreCompositionWithClock(objectBytes: InMemoryObjectBytes): {\n readonly stores: CoreStores;\n readonly clock: MutableClock;\n} {\n const clock = createMutableClock();\n return { stores: createInMemoryCoreStores({ clock, objectBytes }).stores, clock };\n}\n\nexport { InMemoryStorageLedger } from './storage-ledger';\nexport type { InMemoryObjectBytes } from './blob';\n","import { ByokCoreError } from './errors';\n\nexport const ROUTINE_DAYS_OF_WEEK = Object.freeze(['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] as const);\nexport type RoutineDayOfWeek = (typeof ROUTINE_DAYS_OF_WEEK)[number];\n\n/**\n * One local time per matching day. No daysOfWeek and no dayOfMonth: every\n * day. daysOfWeek: those weekdays only. dayOfMonth: that day of every month,\n * or of `month` only. daysOfWeek and dayOfMonth never appear together;\n * `month` needs `dayOfMonth`.\n */\nexport interface RoutineSchedule {\n readonly minute: number;\n readonly hour: number;\n readonly daysOfWeek?: readonly RoutineDayOfWeek[];\n readonly dayOfMonth?: number;\n readonly month?: number;\n readonly tz: string;\n}\n/**\n * 368 days: a yearly date can be 366 days plus a DST shift apart (leap year\n * in between, DST state flips). The embedded wake limit must match this value.\n */\nexport const ROUTINE_HORIZON_MS = 368 * 86_400_000;\n/**\n * Supported `now`: [2000-01-01T00:00Z, 2200-01-01T00:00Z). Before 1972 some\n * zones have second-level offsets (Africa/Monrovia); past 2200 tz rules are\n * projections. Date and Intl themselves cover ±8.64e15 ms.\n */\nexport const ROUTINE_MIN_NOW = Date.UTC(2000, 0, 1);\nexport const ROUTINE_MAX_NOW = Date.UTC(2200, 0, 1);\nexport type RoutineScheduleIssueCode = 'schedule_invalid' | 'schedule_unreachable' | 'schedule_beyond_horizon' | 'tz_invalid';\nexport type RoutineScheduleCheck = { readonly ok: true } | { readonly ok: false; readonly code: RoutineScheduleIssueCode; readonly message: string };\n\nconst KEYS = new Set(['minute', 'hour', 'daysOfWeek', 'dayOfMonth', 'month', 'tz']);\n/** Days in each month of a common year; February 29 is handled apart. */\nconst COMMON_YEAR_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst TZ_NAME = /^[A-Za-z][A-Za-z0-9_+-]*(?:\\/[A-Za-z0-9_+-]+)*$/;\nconst DAY_MS = 86_400_000;\n/** Date.getUTCDay() index (0 = Sunday) to the schedule's day name. */\nconst UTC_DAY_NAME: readonly RoutineDayOfWeek[] = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];\n\ninterface Parsed { minute: number; hour: number; days?: Set<RoutineDayOfWeek>; dayOfMonth?: number; month?: number; tz: string }\nclass ScheduleError extends Error {\n readonly code: RoutineScheduleIssueCode;\n constructor(code: RoutineScheduleIssueCode, message: string) { super(message); this.code = code; }\n}\nconst invalid = (message: string) => new ScheduleError('schedule_invalid', message);\n\nfunction integer(value: unknown, name: string, min: number, max: number): number {\n if (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max) throw invalid(`${name} must be an integer ${min}-${max}`);\n return value;\n}\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\nfunction formatter(tz: string): Intl.DateTimeFormat {\n let f = formatters.get(tz);\n if (!f) {\n f = new Intl.DateTimeFormat('en-US', { timeZone: tz, hourCycle: 'h23', year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' });\n if (formatters.size >= 64) formatters.delete(formatters.keys().next().value!);\n formatters.set(tz, f);\n }\n return f;\n}\n\nfunction checkTz(tz: unknown): string {\n if (typeof tz !== 'string' || !TZ_NAME.test(tz)) throw new ScheduleError('tz_invalid', `${JSON.stringify(tz)} is not an IANA zone name`);\n try { formatter(tz); } catch { throw new ScheduleError('tz_invalid', `\"${tz}\" is not a known IANA zone`); }\n return tz;\n}\n\nfunction parse(schedule: RoutineSchedule): Parsed {\n if (schedule === null || typeof schedule !== 'object' || Array.isArray(schedule)) throw invalid('schedule must be an object');\n for (const key of Object.keys(schedule)) if (!KEYS.has(key)) throw invalid(`unknown field ${key}`);\n const p: Parsed = { minute: integer(schedule.minute, 'minute', 0, 59), hour: integer(schedule.hour, 'hour', 0, 23), tz: checkTz(schedule.tz) };\n const s = schedule as { daysOfWeek?: unknown; dayOfMonth?: unknown; month?: unknown };\n if (s.daysOfWeek !== undefined && s.dayOfMonth !== undefined) throw invalid('daysOfWeek and dayOfMonth cannot both appear');\n if (s.month !== undefined && s.dayOfMonth === undefined) throw invalid('month needs dayOfMonth');\n if (s.daysOfWeek !== undefined) {\n if (!Array.isArray(s.daysOfWeek) || s.daysOfWeek.length < 1 || s.daysOfWeek.length > 7) throw invalid('daysOfWeek must list 1-7 days');\n for (const d of s.daysOfWeek) if (!(ROUTINE_DAYS_OF_WEEK as readonly unknown[]).includes(d)) throw invalid(`unknown day ${JSON.stringify(d)}`);\n p.days = new Set(s.daysOfWeek as RoutineDayOfWeek[]); // duplicates collapse\n }\n if (s.dayOfMonth !== undefined) {\n p.dayOfMonth = integer(s.dayOfMonth, 'dayOfMonth', 1, 31);\n if (s.month !== undefined) {\n p.month = integer(s.month, 'month', 1, 12);\n if (p.month === 2 && p.dayOfMonth === 29) {\n throw new ScheduleError('schedule_beyond_horizon', 'February 29 exists only in leap years; the next one can be up to 8 years away, beyond the 368-day horizon');\n }\n if (p.dayOfMonth > COMMON_YEAR_DAYS[p.month - 1]!) {\n throw new ScheduleError('schedule_unreachable', `month ${p.month} has no day ${p.dayOfMonth}`);\n }\n }\n }\n return p;\n}\n\n/** Validation only. The Host calls it when it applies create_routine / update_routine. */\nexport function checkRoutineSchedule(schedule: RoutineSchedule): RoutineScheduleCheck {\n try { parse(schedule); return { ok: true }; } catch (e) {\n if (e instanceof ScheduleError) return { ok: false, code: e.code, message: e.message };\n throw e;\n }\n}\n\n/** Local wall-clock fields of an instant, written as a UTC epoch (\"local as UTC\"). */\nfunction localAsUtc(tz: string, instant: number): number {\n const p: Record<string, number> = {};\n for (const part of formatter(tz).formatToParts(instant)) if (part.type !== 'literal') p[part.type] = Number(part.value);\n return Date.UTC(p.year!, p.month! - 1, p.day!, p.hour!, p.minute!, p.second!);\n}\nconst offsetAt = (tz: string, instant: number) => localAsUtc(tz, instant) - Math.floor(instant / 1000) * 1000;\n\n/**\n * Local wall time to instant, as Temporal `disambiguation: 'compatible'`:\n * a repeated time takes the earlier instant; a skipped time moves later by\n * the length of the gap.\n */\nfunction resolve(tz: string, local: number): { instant: number; shifted: boolean } {\n const before = offsetAt(tz, local - DAY_MS);\n const offsets = new Set([before, offsetAt(tz, local), offsetAt(tz, local + DAY_MS)]);\n const valid = [...offsets].map(o => local - o).filter(i => offsetAt(tz, i) === local - i);\n return valid.length ? { instant: Math.min(...valid), shifted: false } : { instant: local - before, shifted: true };\n}\n\nfunction matchesDate(p: Parsed, y: number, m: number, d: number): boolean {\n if (p.days) return p.days.has(UTC_DAY_NAME[new Date(Date.UTC(y, m - 1, d)).getUTCDay()]!);\n if (p.dayOfMonth !== undefined) return d === p.dayOfMonth && (p.month === undefined || m === p.month);\n return true;\n}\n\n/**\n * The first occurrence strictly after `now` (epoch ms): the instant at which\n * the zone's wall clock shows the schedule's whole local minute on a matching\n * date. Null when none falls within ROUTINE_HORIZON_MS. Throws on an invalid\n * schedule.\n *\n * Scan from the local date before `now`; keep the running minimum `best` of\n * candidates after `now`; stop at the first unshifted candidate, because a\n * later local time never resolves earlier. Assumes a gap is at most one day.\n */\nexport function nextRoutineOccurrence(schedule: RoutineSchedule, now: number): number | null {\n if (!Number.isSafeInteger(now) || now < ROUTINE_MIN_NOW || now >= ROUTINE_MAX_NOW) {\n throw new RangeError('now must be a safe integer epoch ms in [2000-01-01, 2200-01-01)');\n }\n let p: Parsed;\n try { p = parse(schedule); } catch (error) {\n if (error instanceof ScheduleError) throw new ByokCoreError('routine_schedule_invalid', error.message);\n throw error;\n }\n const start = localAsUtc(p.tz, now);\n const day0 = Date.UTC(new Date(start).getUTCFullYear(), new Date(start).getUTCMonth(), new Date(start).getUTCDate());\n let best = Infinity;\n for (let k = -1; k <= 368; k += 1) {\n const day = new Date(day0 + k * DAY_MS);\n const y = day.getUTCFullYear(), m = day.getUTCMonth() + 1, d = day.getUTCDate();\n if (!matchesDate(p, y, m, d)) continue;\n const { instant, shifted } = resolve(p.tz, Date.UTC(y, m - 1, d, p.hour, p.minute));\n if (instant <= now) continue;\n best = Math.min(best, instant);\n if (!shifted) break; // a later local time can never resolve earlier than an unshifted one\n }\n return best - now <= ROUTINE_HORIZON_MS ? best : null;\n}\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/tenant.ts","../src/principals.ts","../src/time.ts","../src/mailbox.ts","../src/board.ts","../src/truth.ts","../src/presence.ts","../src/blob.ts","../src/quota.ts","../src/capabilities.ts","../src/skill-pack.ts","../src/stores.ts","../src/ports-contract.ts","../src/attestation.ts","../src/device-assertion.ts","../src/webcrypto.ts","../src/hpke.ts","../src/total-parse.ts","../src/sealed-provider-secret.ts","../src/agent-memory-intent.ts","../src/pairing.ts","../src/in-memory/storage-ledger.ts","../src/retention.ts","../src/in-memory/presence.ts","../src/in-memory/board.ts","../src/in-memory/archive-access.ts","../src/in-memory/mailbox.ts","../src/in-memory/blob.ts","../src/in-memory/quota.ts","../src/in-memory/skill-pack.ts","../src/in-memory/truth.ts","../src/in-memory/clock.ts","../src/in-memory/device-assertion-replay.ts","../src/in-memory/index.ts","../src/routine-schedule.ts"],"names":["hex","z","parts","DEFAULT_LIST_LIMIT","pending"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The one error taxonomy for `@byok-sdk/core`.\n *\n * Two rules the rest of the package is built around:\n *\n * 1. **One class, code-based branching.** Consumers switch on `error.code`, not\n * on class identity — the same idiom `@byok-sdk/keys` uses. A composition that\n * maps core errors onto HTTP does it with a code table, so adding a code is\n * an additive change instead of a new `instanceof` chain everywhere.\n * 2. **Every conflict carries the current snapshot.** A CAS failure that\n * reports only \"conflict\" forces the caller into a second round trip and\n * invites last-write-wins retries. {@link CoreConflictError} therefore\n * carries `current` — the authoritative state the caller lost to — plus the\n * `observedAt` instant it was read at.\n *\n * This module imports nothing. It is the graph sink: `quota.ts` narrows\n * {@link StorageErrorCode} out of this union and maps it to HTTP status, and\n * every port module documents which codes it can raise. That keeps the code\n * list in one place while letting each domain own its own status mapping.\n */\n\n/**\n * Every error code this package can raise.\n *\n * Codes are stable strings. Two groups are additionally **wire-stable** — a\n * composition is expected to surface them verbatim to clients, so renaming one\n * is a breaking change:\n *\n * - `terminal_conflict` (§12.6.4, HTTP 409)\n * - the five `storage_*` codes (§12.7.7, see `quota.ts`)\n */\nexport const CORE_ERROR_CODES = {\n routine_schedule_invalid: 'routine_schedule_invalid',\n retention_input_invalid: 'retention_input_invalid',\n retention_collect_failed: 'retention_collect_failed',\n // identity + content addressing\n tenant_id_invalid: 'tenant_id_invalid',\n content_hash_invalid: 'content_hash_invalid',\n\n // caller-supplied instants (see `time.ts`)\n timestamp_not_canonical: 'timestamp_not_canonical',\n\n // capability declaration (ADR-010)\n capability_declaration_invalid: 'capability_declaration_invalid',\n capability_unavailable: 'capability_unavailable',\n\n // device proof (§12.6.3)\n proof_envelope_invalid: 'proof_envelope_invalid',\n proof_canonicalization_failed: 'proof_canonicalization_failed',\n\n // device assertion (plan device-assertion-broker) — deliberately its own\n // code rather than reusing `proof_envelope_invalid`: the two envelopes are\n // non-interchangeable by design, and one shared \"envelope was bad\" code is\n // exactly how a log stops being able to say which authentication surface was\n // probed.\n assertion_envelope_invalid: 'assertion_envelope_invalid',\n\n // sealed provider provisioning (plan web-sealed-provisioning). Messages\n // never carry plaintext, ciphertext, or key material — only which check\n // failed.\n webcrypto_unavailable: 'webcrypto_unavailable',\n sealed_secret_invalid: 'sealed_secret_invalid',\n sealed_secret_open_failed: 'sealed_secret_open_failed',\n provider_provisioning_request_invalid: 'provider_provisioning_request_invalid',\n\n // mailbox (§12.7.3)\n mailbox_message_not_found: 'mailbox_message_not_found',\n mailbox_cursor_regression: 'mailbox_cursor_regression',\n mailbox_cursor_ahead_of_delivery: 'mailbox_cursor_ahead_of_delivery',\n mailbox_stream_closed: 'mailbox_stream_closed',\n\n // board coordination (§12.3)\n board_item_not_found: 'board_item_not_found',\n board_item_exists: 'board_item_exists',\n board_transition_invalid: 'board_transition_invalid',\n board_status_conflict: 'board_status_conflict',\n board_claim_conflict: 'board_claim_conflict',\n board_not_held: 'board_not_held',\n\n // truth records (§12.3, §12.6.4)\n truth_record_not_found: 'truth_record_not_found',\n terminal_conflict: 'terminal_conflict',\n truth_revision_conflict: 'truth_revision_conflict',\n\n // presence + activity hints (§12.3)\n activity_capacity_invalid: 'activity_capacity_invalid',\n activity_batch_invalid: 'activity_batch_invalid',\n hint_ttl_invalid: 'hint_ttl_invalid',\n hint_rate_limited: 'hint_rate_limited',\n\n // object manifest (§12.7.4, §12.7.8)\n object_key_prefix_invalid: 'object_key_prefix_invalid',\n object_not_found: 'object_not_found',\n object_state_invalid: 'object_state_invalid',\n\n // storage entitlement / usage / reservation (§12.7.6-12.7.7)\n storage_entitlement_missing: 'storage_entitlement_missing',\n storage_entitlement_version_conflict: 'storage_entitlement_version_conflict',\n storage_reservation_not_found: 'storage_reservation_not_found',\n storage_object_too_large: 'storage_object_too_large',\n storage_quota_exceeded: 'storage_quota_exceeded',\n storage_reservation_expired: 'storage_reservation_expired',\n storage_integrity_mismatch: 'storage_integrity_mismatch',\n storage_write_suspended: 'storage_write_suspended',\n\n // skill packs (plan `skill-pack-delivery-channel`)\n skill_pack_manifest_invalid: 'skill_pack_manifest_invalid',\n skill_pack_frontmatter_invalid: 'skill_pack_frontmatter_invalid',\n} as const;\n\nexport type CoreErrorCode = (typeof CORE_ERROR_CODES)[keyof typeof CORE_ERROR_CODES];\n\n/** Base error for every failure this package raises. */\nexport class ByokCoreError extends Error {\n public readonly code: CoreErrorCode;\n\n constructor(code: CoreErrorCode, message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = 'ByokCoreError';\n this.code = code;\n }\n}\n\n/**\n * A compare-and-set failure.\n *\n * `current` is the authoritative state at the moment the write was rejected —\n * the board item whose status moved, the terminal record already committed, the\n * entitlement row at a newer version. The caller re-decides against it; the\n * store never merges (§12.3: \"不做 silent last-write-wins\", §12.6.4: 不覆写第一份事实).\n */\nexport class CoreConflictError<TCurrent> extends ByokCoreError {\n public readonly current: TCurrent;\n public readonly observedAt: string;\n\n constructor(\n code: CoreErrorCode,\n message: string,\n current: TCurrent,\n observedAt: string,\n options?: ErrorOptions,\n ) {\n super(code, message, options);\n this.name = 'CoreConflictError';\n this.current = current;\n this.observedAt = observedAt;\n }\n}\n\n/** Narrows an unknown thrown value to a core error, optionally to one code. */\nexport function isCoreError(value: unknown, code?: CoreErrorCode): value is ByokCoreError {\n if (!(value instanceof ByokCoreError)) return false;\n return code === undefined || value.code === code;\n}\n\n/** Narrows an unknown thrown value to a conflict error carrying a snapshot. */\nexport function isCoreConflictError<TCurrent>(\n value: unknown,\n code?: CoreErrorCode,\n): value is CoreConflictError<TCurrent> {\n if (!(value instanceof CoreConflictError)) return false;\n return code === undefined || value.code === code;\n}\n","/**\n * Tenant identity — layer 1 of the six-layer isolation model\n * (`docs/architecture/sdk-architecture.md` §12.6.2).\n *\n * `TenantId` is a branded string and this module is the **only** place that may\n * produce one: every other module receives a `TenantId` it cannot forge without\n * calling {@link tenantId}. The brand carries no runtime value — it exists so a\n * bare `string` (a path segment, a claim from an unverified proof, a\n * device-supplied query parameter) can never silently slide into a store port's\n * first parameter.\n *\n * `src/__tests__/constraints.test.ts` greps the package for `as TenantId`: this\n * file and test fixtures are the only allowed sites. A module that needs a\n * `TenantId` takes one as a parameter or mints it here.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * A validated tenant identifier.\n *\n * Nominal by construction: structurally a `string`, but the phantom brand makes\n * it unassignable from an arbitrary string. Assignment the other way\n * (`TenantId` → `string`) stays legal on purpose, so composition code can pass\n * it as a SQL parameter or key prefix without a cast.\n */\nexport type TenantId = string & { readonly __byokTenantId: unique symbol };\n\n/**\n * Upper bound on tenant id length. Not a security boundary — a bound so a\n * pathological id cannot become an unbounded key prefix inside a store.\n */\nexport const TENANT_ID_MAX_LENGTH = 200;\n\n/**\n * Separator for flat composite keys. `NUL` cannot appear in a tenant id that a\n * control plane can express in a URL, a header, or a SQL identifier, and\n * {@link tenantId} rejects it outright — so a composite key is never ambiguous\n * between `(a, bc)` and `(ab, c)`.\n */\nexport const TENANT_KEY_SEPARATOR = '\\u0000';\n\n/**\n * The single mint point for {@link TenantId}.\n *\n * Fail-closed: empty, whitespace-padded, over-long, non-string, or\n * `NUL`-bearing values are rejected rather than normalized. Normalizing here\n * would create a second source of truth for \"which tenant is this\", because the\n * control plane that issued the id would then disagree with the SDK about its\n * canonical form.\n *\n * @throws {ByokCoreError} code `tenant_id_invalid`.\n */\nexport function tenantId(value: string): TenantId {\n const candidate: unknown = value;\n if (typeof candidate !== 'string') {\n throw new ByokCoreError(\n 'tenant_id_invalid',\n `Tenant id must be a string, received ${typeof candidate}.`,\n );\n }\n if (candidate.length === 0) {\n throw new ByokCoreError('tenant_id_invalid', 'Tenant id must not be empty.');\n }\n if (candidate.trim() !== candidate) {\n throw new ByokCoreError(\n 'tenant_id_invalid',\n 'Tenant id must not have leading or trailing whitespace.',\n );\n }\n if (candidate.length > TENANT_ID_MAX_LENGTH) {\n throw new ByokCoreError(\n 'tenant_id_invalid',\n `Tenant id must be at most ${TENANT_ID_MAX_LENGTH} characters.`,\n );\n }\n if (candidate.includes(TENANT_KEY_SEPARATOR)) {\n throw new ByokCoreError('tenant_id_invalid', 'Tenant id must not contain a NUL character.');\n }\n return candidate as TenantId;\n}\n\n/**\n * Non-throwing form of {@link tenantId}, for surfaces that must answer \"is this\n * a tenant id?\" without building an error (route matching, log redaction).\n * Accepts exactly what {@link tenantId} accepts, never more.\n */\nexport function isTenantId(value: unknown): value is TenantId {\n if (typeof value !== 'string') return false;\n return (\n value.length > 0 &&\n value.trim() === value &&\n value.length <= TENANT_ID_MAX_LENGTH &&\n !value.includes(TENANT_KEY_SEPARATOR)\n );\n}\n\n/**\n * Composite key helper for compositions that need a flat key space (in-memory\n * maps, KV namespaces). SQL compositions use a tenant-prefixed composite\n * primary key instead — §12.6.2 layer 3 forbids a bare device/task index\n * regardless of which representation a composition picks.\n */\nexport function tenantKey(tenant: TenantId, ...parts: readonly string[]): string {\n return [tenant as string, ...parts].join(TENANT_KEY_SEPARATOR);\n}\n","/**\n * Authenticated principals — layer 2 of the isolation model (§12.6.2).\n *\n * A handler never receives a raw tenant string; it receives a principal that\n * already carries a minted {@link TenantId}. The two principal shapes are\n * deliberately not one type with an optional `deviceId`: a control-plane caller\n * that can write entitlements and a device that can write truth records have\n * different authority, and a discriminated union makes a handler state which\n * one it accepts.\n *\n * `keyId`/`keyEpoch` are **not** here. They are device-proof semantics\n * (`plans/sprints/…sprint.md` §S6.2): the signing key's identity and rotation\n * generation, resolved by looking up the device row during proof verification.\n * Putting them on the principal would create permanently-empty fields on every\n * principal minted by a non-proof path.\n */\nimport type { TenantId } from './tenant';\n\n/** Principal kinds. A composition may not invent a third without a contract change. */\nexport const PRINCIPAL_KINDS = ['device', 'control-plane'] as const;\nexport type PrincipalKind = (typeof PRINCIPAL_KINDS)[number];\n\n/**\n * A paired device acting inside one tenant/product.\n *\n * Built only from a device row loaded with the tenant as part of the lookup key\n * (§12.6.2 layer 5) — never from claims a device asserted about itself.\n */\nexport interface DevicePrincipal {\n readonly kind: 'device';\n readonly tenantId: TenantId;\n readonly productId: string;\n readonly deviceId: string;\n}\n\n/**\n * The host's control plane acting on a tenant: entitlement writes, retention\n * policy, administrative reads. Carries the operator identity for audit, which\n * is opaque to the SDK.\n */\nexport interface ControlPlanePrincipal {\n readonly kind: 'control-plane';\n readonly tenantId: TenantId;\n readonly operatorId: string;\n}\n\n/** Anything that can address a tenant-scoped store. */\nexport type Principal = DevicePrincipal | ControlPlanePrincipal;\n\nexport function isDevicePrincipal(principal: Principal): principal is DevicePrincipal {\n return principal.kind === 'device';\n}\n\nexport function isControlPlanePrincipal(\n principal: Principal,\n): principal is ControlPlanePrincipal {\n return principal.kind === 'control-plane';\n}\n\n/**\n * The tenant every store call must be scoped to.\n *\n * Exists so a handler cannot accidentally read `principal.tenantId` off one\n * principal and pass a different tenant to a store: the facade that binds\n * stores to a tenant takes this, not a loose string.\n */\nexport function principalTenant(principal: Principal): TenantId {\n return principal.tenantId;\n}\n","/**\n * The one timestamp format this package accepts across every composition.\n *\n * Every instant that crosses a store port is an ISO-8601 UTC string, and the\n * in-memory reference compares those strings with `<` / `>=` — a downgrade\n * grace deadline, a retention cutoff, a reservation expiry. Lexicographic\n * order equals chronological order **only** for the canonical\n * `YYYY-MM-DDTHH:mm:ss.sssZ` shape that `Date.prototype.toISOString` emits.\n * Feed the same store `2026-08-08T00:00:00+08:00` and the string comparison\n * silently answers a different question than a SQL `timestamptz` comparison\n * would, so the in-memory and Postgres compositions would diverge on an input\n * the conformance suite never sees.\n *\n * The fix is a format contract rather than a normalizer: a caller-supplied\n * timestamp that is not already canonical is **rejected**, not rewritten.\n * Rewriting would make this module a second authority on what instant the\n * caller meant, and an offset-bearing or second-precision string is exactly the\n * case where that guess is worth refusing.\n *\n * Store-produced timestamps are canonical by construction (they come from\n * `Clock.now().toISOString()`); this module guards the *inbound* direction —\n * `downgradeGraceUntil`, `deletePendingBefore`, `ackedBefore`,\n * `expireUnackedBefore`, `reapDeadLettersBefore`.\n *\n * No `node:` import and no clock read: validation is pure, so a Workers\n * composition and the constraint test (`Date.now()` is banned package-wide)\n * both stay happy. `Date.parse` is used for *calendar validity only* — the\n * pattern is what pins the shape.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * Exactly what `toISOString()` produces: four-digit year, `T` separator,\n * millisecond precision, literal `Z`. No offsets, no omitted milliseconds, no\n * expanded-year form — each of those breaks the lexicographic-order property.\n */\nexport const CANONICAL_TIMESTAMP_PATTERN =\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/;\n\n/**\n * True when `value` is a canonical ISO-8601 UTC instant.\n *\n * Two checks, in order: the pattern pins the *shape*, then a round trip\n * through `Date` pins *calendar validity* — `2026-02-30T00:00:00.000Z` matches\n * the pattern and is not an instant.\n */\nexport function isCanonicalTimestamp(value: unknown): value is string {\n if (typeof value !== 'string') return false;\n if (!CANONICAL_TIMESTAMP_PATTERN.test(value)) return false;\n const parsed = Date.parse(value);\n if (!Number.isFinite(parsed)) return false;\n return new Date(parsed).toISOString() === value;\n}\n\n/**\n * Fail-closed gate for a caller-supplied instant.\n *\n * @param value The timestamp as received from the caller.\n * @param field Field name, so the failure names the contract that was missed\n * rather than just the bad string.\n * @returns The same string, so call sites can validate and assign in one step.\n * @throws {ByokCoreError} code `timestamp_not_canonical`.\n */\nexport function assertCanonicalTimestamp(value: string, field: string): string {\n if (!isCanonicalTimestamp(value)) {\n throw new ByokCoreError(\n 'timestamp_not_canonical',\n `${field} must be a canonical ISO-8601 UTC instant (YYYY-MM-DDTHH:mm:ss.sssZ), received ${JSON.stringify(value)}.`,\n );\n }\n return value;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Hosted mailbox contract (§12.7.3).\n *\n * The load-bearing rule of this file: **reading is not acknowledging.**\n * `readAfter` never mutates the cursor. The only ack is the cursor the daemon\n * brings back on its next poll, after it has durably appended the envelope to\n * its local journal. \"领走即弃\" means *cursor-advanced-then-deleted*, not\n * *read-then-deleted* — read-deletes would break the frozen at-least-once\n * semantics the client's stall recovery is built on (§8.3).\n *\n * The mailbox transports opaque envelope bytes and is **not** an\n * execution-state authority. `body` is a string here rather than a parsed\n * message because core is protocol-free: the frozen v1 shape lives in\n * `@byok-sdk/protocol`, and core must not grow an edge to it (§12.1 invariant).\n */\nimport type { ContentHash } from './blob';\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\n/**\n * Row lifecycle. `pending` and `acked` are derived from the device cursor;\n * `expired` is the dead-letter state for rows that aged out before ever being\n * acked — §12.7.5 requires those to be visible, not silently dropped.\n */\nexport const MAILBOX_MESSAGE_STATES = ['pending', 'acked', 'expired'] as const;\nexport type MailboxMessageState = (typeof MAILBOX_MESSAGE_STATES)[number];\n\n/** One mailbox row. `seq` is monotonic per (tenant, device) — never global. */\nexport interface MailboxMessage {\n readonly tenantId: TenantId;\n readonly deviceId: string;\n readonly seq: number;\n readonly messageId: string;\n /** Opaque encoded envelope. Core never parses it. */\n readonly body: string;\n readonly bodyHash: ContentHash;\n readonly byteSize: bigint;\n readonly state: MailboxMessageState;\n readonly appendedAt: string;\n}\n\n/** Opaque bytes produced after the mailbox has atomically reserved their delivery sequence. */\nexport interface MailboxBody {\n readonly body: string;\n readonly bodyHash: ContentHash;\n readonly byteSize: bigint;\n}\n\n/**\n * How an append is admitted against the tenant's `mailboxLimitBytes`.\n *\n * Mailbox bytes have one authority: the retained rows. Usage is the tenant's\n * `SUM(byteSize)` over its `pending` rows, and the limit is checked in the same\n * serialized unit that inserts the row — there is no counter for a writer to\n * forget, so acking, dead-lettering or deleting a row needs no accounting.\n * `acked` and `expired` rows stay retained for retention and §12.7.5\n * visibility but hold no quota, so undelivered-and-lost work can never wedge\n * a tenant at its limit.\n *\n * - `limited`: refused with `storage_quota_exceeded` when `used + byteSize`\n * exceeds the limit, and with `storage_entitlement_missing` when the tenant\n * has no entitlement. A refused append consumes no `seq`.\n * - `cancellation`: always admitted and still counted. Reserved for the one\n * cancellation row a task can own, so a full mailbox never blocks\n * `cancelTask`.\n */\nexport type MailboxAdmission = 'limited' | 'cancellation';\n\nexport interface MailboxAppendInput {\n readonly deviceId: string;\n /**\n * Producer-supplied idempotency key. A second append with the same\n * `messageId` returns the existing row instead of enqueuing a duplicate.\n */\n readonly messageId: string;\n /**\n * Builds the opaque body around the sequence reserved by this append.\n *\n * The store invokes this only for a new row and commits the returned bytes\n * at exactly that `seq`. Allocation, materialization, and insertion are one\n * per-device serialized operation; otherwise concurrent offers could commit\n * out of order and let an ack skip a late lower sequence.\n */\n readonly materialize: (seq: number) => MailboxBody | Promise<MailboxBody>;\n /**\n * Limit admission for a NEW row. An existing `messageId` returns its row\n * before any capacity check, so a retry is never refused for capacity. A\n * closed stream refuses before even that (see {@link MailboxStore.closeStream}).\n */\n readonly admission: MailboxAdmission;\n}\n\n/** Tenant mailbox usage, derived from the retained rows on every read. */\nexport interface MailboxUsage {\n /** `SUM(byteSize)` over the retained `pending` rows. */\n readonly bytes: bigint;\n}\n\nexport interface MailboxReadQuery {\n readonly deviceId: string;\n /** Exclusive lower bound. `0` reads from the beginning of the retained window. */\n readonly afterSeq: number;\n readonly limit?: number;\n}\n\nexport interface MailboxPage {\n readonly messages: readonly MailboxMessage[];\n /**\n * The seq to poll after next. Equal to `afterSeq` when the page is empty —\n * reading never moves the ack cursor, so a caller that only reads can replay\n * the same page forever without losing anything.\n */\n readonly nextSeq: number;\n readonly hasMore: boolean;\n /**\n * The earliest seq a reader can still recover from: one past the highest row\n * this device LOST. A caller at `recoverableFrom - 1` can still be handed\n * the first row it has any claim to; a caller below that has a gap it cannot\n * see, and resuming it would hand back a partial tail indistinguishable from\n * a complete one.\n *\n * Lost means `expired` — a row that aged out before anyone acked it. An\n * `acked` row is consumed, not lost, so acking never moves this and never\n * turns a re-poll from an old cursor into a failure; that distinction is the\n * whole point of the field.\n *\n * `1` for a mailbox that has lost nothing, so a fresh device's cursor `0` is\n * always inside the window. Monotonic: `collectExpired` reaps old dead\n * letters but always keeps each device's highest-seq one, which is the\n * evidence this floor is read from.\n *\n * This is a READ of the retained window, never a second retention authority:\n * `collectExpired` decides what is retained, this reports what it cost.\n */\n readonly recoverableFrom: number;\n}\n\nexport interface MailboxAdvanceCursorInput {\n readonly deviceId: string;\n /** Highest seq the device has durably journaled. */\n readonly ackedSeq: number;\n}\n\n/** Server-owned proof that a cursor was returned to this device. */\nexport interface MailboxRecordDeliveryInput {\n readonly deviceId: string;\n /** Highest cursor the server has returned to this device. */\n readonly deliveredSeq: number;\n}\n\n/** The device's durable delivery and acknowledgement positions. */\nexport interface MailboxCursorState {\n readonly tenantId: TenantId;\n readonly deviceId: string;\n /** Highest cursor the server has returned to this device. */\n readonly deliveredSeq: number;\n readonly ackedSeq: number;\n readonly updatedAt: string;\n}\n\n/**\n * Retention cutoffs.\n *\n * All three instants must be **canonical ISO-8601 UTC** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`. A retention sweep\n * deletes rows, so an offset-bearing string that a string comparison and a SQL\n * `timestamptz` comparison read differently is the worst place to guess — see\n * `time.ts`.\n */\nexport interface MailboxCollectExpiredInput extends CollectExpiredInput {\n /** Acked rows appended before this instant are deleted. */\n readonly ackedBefore: string;\n /** Unacked rows appended before this instant move to `expired`. */\n readonly expireUnackedBefore: string;\n /**\n * Dead letters (`expired` rows) appended before this instant are deleted,\n * except each device's highest-seq dead letter: that row is the evidence for\n * `recoverableFrom`, so a reap never moves the floor. Only rows that were\n * already `expired` when the call started are eligible; a row this call\n * expires waits for the next call. Reaped rows count in `removed`.\n */\n readonly reapDeadLettersBefore: string;\n}\n\n/**\n * Which of one device's `pending` rows {@link MailboxStore.expirePending}\n * dead-letters. A listed seq that is not `pending` (acked, already expired, or\n * never written) is skipped.\n */\nexport interface MailboxExpirePendingInput {\n readonly deviceId: string;\n readonly seqs: readonly number[];\n}\n\n/** Why a device's stream was closed: the device it addressed was retired. */\nexport const MAILBOX_STREAM_CLOSE_CAUSES = ['device_revoked', 'device_superseded'] as const;\nexport type MailboxStreamCloseCause = (typeof MAILBOX_STREAM_CLOSE_CAUSES)[number];\n\n/** An append refused because its device's stream was closed when the device was retired. */\nexport class MailboxStreamClosedError extends ByokCoreError {\n public readonly deviceId: string;\n public readonly closeCause: MailboxStreamCloseCause;\n\n constructor(deviceId: string, closeCause: MailboxStreamCloseCause, options?: ErrorOptions) {\n super('mailbox_stream_closed', `The mailbox stream of device ${deviceId} is closed (${closeCause}).`, options);\n this.name = 'MailboxStreamClosedError';\n this.deviceId = deviceId;\n this.closeCause = closeCause;\n }\n}\n\nexport interface MailboxCloseStreamInput {\n readonly deviceId: string;\n readonly cause: MailboxStreamCloseCause;\n}\n\nexport interface MailboxReopenStreamInput {\n readonly deviceId: string;\n}\n\n/**\n * Mailbox port. Tenant-first, async.\n *\n * Raises: `mailbox_cursor_regression` (an ack that moves the cursor backwards,\n * which would silently re-deliver already-journaled work),\n * `mailbox_cursor_ahead_of_delivery` (an ack beyond the highest cursor the\n * server has returned to that device),\n * `timestamp_not_canonical` (a retention cutoff that is not a canonical\n * ISO-8601 UTC instant), `storage_quota_exceeded` and\n * `storage_entitlement_missing` (a `limited` append refused at admission), and\n * `mailbox_stream_closed` ({@link MailboxStreamClosedError}, any append to a\n * closed stream).\n */\nexport interface MailboxStore {\n append(tenant: TenantId, input: MailboxAppendInput): Promise<MailboxMessage>;\n /** The tenant's mailbox bytes, summed from the retained `pending` rows. */\n readUsage(tenant: TenantId): Promise<MailboxUsage>;\n /** Pure read. Never advances the cursor, never deletes, never marks acked. */\n readAfter(tenant: TenantId, query: MailboxReadQuery): Promise<MailboxPage>;\n /** Records the highest cursor a device-facing response is about to return. */\n recordDelivery(\n tenant: TenantId,\n input: MailboxRecordDeliveryInput,\n ): Promise<MailboxCursorState>;\n /** The one and only ack. Monotonic and bounded by the recorded delivery watermark. */\n advanceCursor(\n tenant: TenantId,\n input: MailboxAdvanceCursorInput,\n ): Promise<MailboxCursorState>;\n readCursor(tenant: TenantId, deviceId: string): Promise<MailboxCursorState>;\n /** Retention hook: delete acked rows, reap old dead letters below the floor, dead-letter unacked ones. */\n collectExpired(\n tenant: TenantId,\n input: MailboxCollectExpiredInput,\n ): Promise<CollectExpiredResult>;\n /**\n * Dead-letters the listed undelivered rows of a task the Host abandoned,\n * without waiting for retention. Only `pending` rows move, and only to\n * `expired`: nothing is deleted, no row returns to `pending`, the cursor is\n * untouched, and the device's `seq` allocator keeps counting. The moved rows\n * stop holding mailbox quota and raise `recoverableFrom` exactly as a\n * retention sweep would. Serialized with the device's appends and acks.\n */\n expirePending(tenant: TenantId, input: MailboxExpirePendingInput): Promise<{ readonly expired: number }>;\n /**\n * Closes a retired device's stream and dead-letters every `pending` row on\n * it, as one step serialized with the device's appends: an append ordered\n * before it has its row expired here, and every append ordered after it is\n * refused with `mailbox_stream_closed`, whatever its admission and even for\n * a known `messageId`. The stream need not exist yet; closing creates it\n * closed. Closing a closed stream keeps its first close instant, records the\n * new cause and still expires pending rows. Cursor, `seq` and\n * `recoverableFrom` move exactly as {@link expirePending} moves them.\n */\n closeStream(tenant: TenantId, input: MailboxCloseStreamInput): Promise<{ readonly expired: number }>;\n /**\n * Reopens a stream for a device registered again under the same id. Rows,\n * cursor, `seq` and `recoverableFrom` are untouched, so delivery stays\n * monotonic across the close. A no-op on an open or absent stream.\n */\n reopenStream(tenant: TenantId, input: MailboxReopenStreamInput): Promise<void>;\n}\n","/**\n * Board coordination state (§12.3).\n *\n * This is the *human and multi-device* collaboration lifecycle, and it is a\n * separate vocabulary from the frozen wire execution vocabulary on purpose. One\n * run attempt is not one work item: an item can outlive several attempts, and a\n * finished attempt does not mean a human accepted the result. The constraint\n * test asserts that no wire execution state name appears in this file — if the\n * two vocabularies ever merge, status sniffing comes back and the board becomes\n * a second, unreliable execution authority.\n *\n * Three invariants the ports below encode:\n *\n * - **assignee and status are two fields**, not one enum. \"Who holds it\" and\n * \"where it is\" change independently.\n * - **every mutation is a CAS.** `claim` compares against \"unheld\"; every status\n * move carries `expectedStatus`. There is no last-write-wins path.\n * - **conflicts return the snapshot they lost to**, so the caller re-decides\n * against real state instead of retrying blind.\n */\nimport type { TenantId } from './tenant';\n\n/** The five board statuses. `closed` means \"terminated, unaccepted\" (§12.3). */\nexport const BOARD_STATUSES = ['todo', 'in_progress', 'in_review', 'done', 'closed'] as const;\nexport type BoardStatus = (typeof BOARD_STATUSES)[number];\n\n/**\n * Legal transitions, transcribed from the §12.3 state diagram.\n *\n * `in_review → done` is the human acceptance step: a device reporting a\n * terminal record can push an item to `in_review`, never straight to `done`.\n * `done` and `closed` are sinks — if archival semantics are ever needed, §12.3\n * pins the answer to an `archivedAt` field, not a sixth status.\n */\nexport const BOARD_TRANSITIONS: Readonly<Record<BoardStatus, readonly BoardStatus[]>> = {\n todo: ['in_progress', 'closed'],\n in_progress: ['todo', 'in_review', 'closed'],\n in_review: ['in_progress', 'done', 'closed'],\n done: [],\n closed: [],\n};\n\nexport function isLegalBoardTransition(from: BoardStatus, to: BoardStatus): boolean {\n return BOARD_TRANSITIONS[from].includes(to);\n}\n\n/** Who currently holds the item. Separate from {@link BoardItem.status}. */\nexport interface BoardAssignee {\n readonly holderId: string;\n readonly heldSince: string;\n}\n\n/**\n * One work item.\n *\n * `boardSeq` is monotonic **per tenant** and bumps on every mutation, which is\n * what makes incremental list polling possible without a cross-tenant sequence\n * (a global sequence would leak other tenants' write rate).\n */\nexport interface BoardItem {\n readonly tenantId: TenantId;\n readonly itemId: string;\n readonly channel: string;\n readonly title: string;\n readonly status: BoardStatus;\n readonly assignee?: BoardAssignee;\n readonly boardSeq: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport interface BoardItemInput {\n readonly itemId: string;\n readonly channel: string;\n readonly title: string;\n /** Defaults to `todo`. Creating directly into a sink status is legal but explicit. */\n readonly status?: BoardStatus;\n}\n\nexport interface BoardListQuery {\n /** Exclusive lower bound on `boardSeq`, for incremental polling. */\n readonly afterSeq?: number;\n readonly channel?: string;\n readonly status?: BoardStatus;\n readonly limit?: number;\n}\n\nexport interface BoardPage {\n readonly items: readonly BoardItem[];\n /** Highest `boardSeq` in this page, or the requested `afterSeq` when empty. */\n readonly nextSeq: number;\n readonly hasMore: boolean;\n}\n\nexport interface BoardClaimInput {\n readonly itemId: string;\n readonly holderId: string;\n /**\n * Status the claimer believes the item is in. Defaults to `todo`; supplying\n * it explicitly makes the claim a full CAS rather than an assignee-only one.\n *\n * The CAS holds on the idempotent path too: a re-claim by the current holder\n * that supplies a stale `expectedStatus` fails with `board_status_conflict`\n * and the current item. The default is *not* applied there — a retry of a\n * successful claim legitimately observes `in_progress`.\n */\n readonly expectedStatus?: BoardStatus;\n}\n\nexport interface BoardUnclaimInput {\n readonly itemId: string;\n /** Must match the current holder — releasing someone else's item is not a legal move. */\n readonly holderId: string;\n}\n\nexport interface BoardStatusUpdateInput {\n readonly itemId: string;\n readonly expectedStatus: BoardStatus;\n readonly status: BoardStatus;\n /** Optional holder assertion, for transitions only the holder may make. */\n readonly holderId?: string;\n}\n\n/**\n * Board port. Tenant-first, async.\n *\n * Raises: `board_item_not_found`, `board_claim_conflict` (loser gets the\n * winner's holder snapshot), `board_status_conflict` (`expectedStatus` missed —\n * carries the current item), `board_transition_invalid` (move not in\n * {@link BOARD_TRANSITIONS} — also carries the current item), `board_not_held`.\n */\nexport interface BoardStore {\n create(tenant: TenantId, input: BoardItemInput): Promise<BoardItem>;\n get(tenant: TenantId, itemId: string): Promise<BoardItem | undefined>;\n list(tenant: TenantId, query: BoardListQuery): Promise<BoardPage>;\n /** CAS on \"unheld\". Exactly one concurrent caller wins; losers get the holder snapshot. */\n claim(tenant: TenantId, input: BoardClaimInput): Promise<BoardItem>;\n unclaim(tenant: TenantId, input: BoardUnclaimInput): Promise<BoardItem>;\n updateStatus(tenant: TenantId, input: BoardStatusUpdateInput): Promise<BoardItem>;\n /** Removes the item; an absent item is not an error. The Host archive step (#1120) is the caller. */\n remove(tenant: TenantId, itemId: string): Promise<void>;\n}\n","/**\n * Truth records: attested metadata with two different write models (§12.3, §12.6.4).\n *\n * | kind | write model | conflict model |\n * | --------------- | ------------------------------ | --------------------------------------- |\n * | `task.terminal` | first write per task, immutable | different hash → `terminal_conflict` |\n * | `profile` | per-key snapshot | `expectedRev` CAS |\n * | `memory` | per-key snapshot | `expectedRev` CAS |\n *\n * The store is deliberately dumb about content. It can match, sort, and return\n * by tenant/kind/key/rev/hash, and that is the whole of its authority: no\n * summarizing, no merging, no relevance ranking (§12.3). Merge decisions belong\n * to the device that holds the context, which is why a conflict hands back the\n * current snapshot and stops.\n *\n * The manifest listing returns metadata only — never bodies. Selecting which\n * bodies to fetch is a local decision (§S6.4), so shipping bodies in the list\n * response would both defeat that and make the response unbounded.\n */\nimport type { ContentHash } from './blob';\nimport type { TenantId } from './tenant';\n\nexport const TRUTH_RECORD_KINDS = ['task.terminal', 'profile', 'memory'] as const;\nexport type TruthRecordKind = (typeof TRUTH_RECORD_KINDS)[number];\n\n/**\n * Where the record body lives. Small payloads may be inline and still count\n * against tenant usage (§12.7.6); larger ones are an object reference.\n */\nexport type TruthBodyRef =\n | { readonly kind: 'inline'; readonly body: string }\n | { readonly kind: 'object'; readonly hash: ContentHash };\n\nexport interface TruthRecord {\n readonly tenantId: TenantId;\n readonly kind: TruthRecordKind;\n /** For `task.terminal` this is the task id; for snapshots, the host's key. */\n readonly recordKey: string;\n /** `1` for the first write. Terminal records never advance past `1`. */\n readonly rev: number;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly body: TruthBodyRef;\n readonly label?: string;\n /** Idempotency key of the accepted write, for replay detection. */\n readonly requestId?: string;\n readonly writtenAt: string;\n}\n\n/** Manifest projection: everything needed to decide *whether* to fetch a body. */\nexport interface TruthManifestEntry {\n readonly kind: TruthRecordKind;\n readonly recordKey: string;\n readonly rev: number;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly label?: string;\n readonly updatedAt: string;\n}\n\nexport interface TerminalWriteInput {\n readonly taskId: string;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly body: TruthBodyRef;\n readonly label?: string;\n readonly requestId?: string;\n}\n\nexport interface SnapshotWriteInput {\n readonly kind: 'profile' | 'memory';\n readonly recordKey: string;\n /** `0` asserts \"no record yet\". Any other value must equal the stored `rev`. */\n readonly expectedRev: number;\n readonly contentHash: ContentHash;\n readonly byteSize: bigint;\n readonly body: TruthBodyRef;\n readonly label?: string;\n readonly requestId?: string;\n}\n\nexport interface TruthRecordSelector {\n readonly kind: TruthRecordKind;\n readonly recordKey: string;\n}\n\nexport interface TruthManifestQuery {\n readonly kind?: TruthRecordKind;\n readonly keyPrefix?: string;\n readonly limit?: number;\n}\n\n/**\n * Truth port. Tenant-first, async.\n *\n * Raises: `terminal_conflict` (same task, different hash — carries the record\n * already committed), `truth_revision_conflict` (`expectedRev` missed — carries\n * the current record), `truth_record_not_found`.\n */\nexport interface TruthStore {\n /**\n * Writes the first terminal record for a task.\n *\n * Replaying the identical hash returns the original record unchanged, so a\n * retry after a lost response is safe. A different hash for the same task is\n * a conflict: the first fact is never overwritten.\n */\n writeTerminal(tenant: TenantId, input: TerminalWriteInput): Promise<TruthRecord>;\n /** Per-key snapshot write under `expectedRev` CAS. The store never merges bodies. */\n writeSnapshot(tenant: TenantId, input: SnapshotWriteInput): Promise<TruthRecord>;\n getRecord(tenant: TenantId, selector: TruthRecordSelector): Promise<TruthRecord | undefined>;\n /** Metadata only — key/rev/hash/size/label, no bodies. */\n listManifest(\n tenant: TenantId,\n query: TruthManifestQuery,\n ): Promise<readonly TruthManifestEntry[]>;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Presence hints (§12.3).\n *\n * Presence is lossy, TTL-bounded, unsigned, and never authoritative. Expiry means\n * *absence*, not a stale value: a hint past its TTL is invisible to readers, so\n * nothing downstream can mistake an old level for a live one.\n *\n * These hints must never be used to derive coordination state, execution state,\n * authorization, billing, or recovery — which is why this module shares no\n * vocabulary with `board.ts` and no vocabulary with the frozen wire states. The\n * constraint test enforces that separation by scanning this file for those\n * names. A device that looks busy is not evidence that any particular work item\n * moved anywhere.\n *\n */\nimport type { TenantId } from './tenant';\n\n/** The five presence levels. */\nexport const PRESENCE_LEVELS = ['online', 'thinking', 'working', 'error', 'offline'] as const;\nexport type PresenceLevel = (typeof PRESENCE_LEVELS)[number];\n\n/**\n * The capability matrix a daemon reported for one runtime: the shape of\n * `@byok-sdk/protocol`'s `RuntimeCapabilities` (#1103). Omitted fields are unknown.\n */\nexport interface PresenceRuntimeCapabilities {\n readonly steer?: boolean;\n readonly resume?: boolean;\n readonly approvalInteractive?: boolean;\n readonly mcpToolsets?: boolean;\n readonly messageDraft?: boolean;\n readonly toolAuthorizationAuto?: boolean;\n readonly durableLane?: boolean;\n readonly preparedLane?: boolean;\n readonly isolation?: {\n readonly userContext?: boolean;\n readonly userMcpServers?: boolean;\n readonly sessionPersistence?: boolean;\n };\n}\n\n/** Runtime facts observed by a daemon's real local probe. Omitted fields are unknown. */\nexport interface PresenceRuntimeFact {\n readonly id: string;\n readonly version?: string;\n readonly authPresent?: boolean;\n readonly capabilities?: PresenceRuntimeCapabilities;\n}\n\n/** Copies the defined boolean flags named by `keys`; a stored row holds no other keys. */\nfunction definedFlags<T extends object, K extends keyof T>(source: T, keys: readonly K[]): Pick<T, K> {\n const flags: Partial<Pick<T, K>> = {};\n for (const key of keys) if (source[key] !== undefined) flags[key] = source[key];\n return flags as Pick<T, K>;\n}\n\n/** A frozen copy of one runtime fact holding only the known fields; every presence store returns this. */\nexport function freezePresenceRuntimeFact(runtime: PresenceRuntimeFact): PresenceRuntimeFact {\n const capabilities = runtime.capabilities;\n return Object.freeze({\n id: runtime.id,\n ...(runtime.version === undefined ? {} : { version: runtime.version }),\n ...(runtime.authPresent === undefined ? {} : { authPresent: runtime.authPresent }),\n ...(capabilities === undefined ? {} : {\n capabilities: Object.freeze({\n ...definedFlags(capabilities, ['steer', 'resume', 'approvalInteractive', 'mcpToolsets', 'messageDraft', 'toolAuthorizationAuto', 'durableLane', 'preparedLane']),\n ...(capabilities.isolation === undefined ? {} : {\n isolation: Object.freeze(definedFlags(capabilities.isolation, ['userContext', 'userMcpServers', 'sessionPersistence'])),\n }),\n }),\n }),\n });\n}\n\n/** Unexpired presence facts nested in the tenant aggregate. */\nexport interface TenantReadinessPresence {\n readonly level: PresenceLevel;\n readonly detail?: string;\n readonly configuredToolsets?: readonly string[];\n readonly clientVersion?: string;\n readonly protocolVersions?: readonly number[];\n readonly runtimes?: readonly PresenceRuntimeFact[];\n readonly observedAt: string;\n readonly expiresAt: string;\n}\n\n/** Durable device state plus its optional live observation, scoped to one tenant. */\nexport interface TenantReadinessDevice {\n readonly deviceId: string;\n readonly productId: string;\n readonly deviceName: string;\n /** Retained but invariant: revocation deletes the row, so this is never `true`. */\n readonly revoked: boolean;\n /** Omitted when absent/expired or when the durable device is revoked. */\n readonly presence?: TenantReadinessPresence;\n}\n\n/** SDK-owned tenant read model; this is observation, never an execution gate. */\nexport interface TenantReadiness {\n readonly tenantId: TenantId;\n readonly activePairedDeviceCount: number;\n /** Retained but invariant: always 0, since a revoked device leaves no row to count. */\n readonly revokedDeviceCount: number;\n readonly observedPresenceCount: number;\n readonly observedPresenceByLevel: Readonly<Record<PresenceLevel, number>>;\n readonly devices: readonly TenantReadinessDevice[];\n}\n\n/** A device-level hint. `expiresAt` is authoritative: past it, the hint does not exist. */\nexport interface PresenceHint {\n readonly tenantId: TenantId;\n readonly deviceId: string;\n readonly level: PresenceLevel;\n /** Free-form host label, bounded by the composition. Never parsed by core. */\n readonly detail?: string;\n /**\n * Logical MCP toolset IDs this daemon reported as configured. Discovery\n * only: local task acceptance remains the fail-closed authority. Omission\n * means legacy/unknown; an empty array means known-none.\n */\n readonly configuredToolsets?: readonly string[];\n /** The U4a Local Agent release version, when the daemon supplied it. */\n readonly clientVersion?: string;\n /** Protocol versions actually advertised by this daemon. */\n readonly protocolVersions?: readonly number[];\n /** Runtime/auth facts from a real local probe; unknown facts are omitted. */\n readonly runtimes?: readonly PresenceRuntimeFact[];\n readonly observedAt: string;\n readonly expiresAt: string;\n}\n\nexport interface PresenceHintInput {\n readonly deviceId: string;\n readonly level: PresenceLevel;\n readonly detail?: string;\n /** Validated logical IDs only; executable connector definitions never belong here. */\n readonly configuredToolsets?: readonly string[];\n /** The U4a Local Agent release version, when available. */\n readonly clientVersion?: string;\n /** Protocol versions actually advertised by this daemon. */\n readonly protocolVersions?: readonly number[];\n /** Runtime/auth facts from a real local probe; unknown facts are omitted. */\n readonly runtimes?: readonly PresenceRuntimeFact[];\n /** Hint lifetime. §12.7.5 suggests 60-120s for presence. */\n readonly ttlMs: number;\n /** Minimum time between accepted publications for this device. `0` explicitly disables throttling. */\n readonly minimumIntervalMs: number;\n}\n\n/**\n * Presence port. Tenant-first, async.\n *\n * Reads filter expired hints out rather than returning them with a flag: an\n * expired hint is indistinguishable from one that was never written.\n */\nexport interface PresenceStore {\n collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult>;\n publish(tenant: TenantId, input: PresenceHintInput): Promise<PresenceHint>;\n read(tenant: TenantId, deviceId: string): Promise<PresenceHint | undefined>;\n list(tenant: TenantId): Promise<readonly PresenceHint[]>;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Content addressing and the object manifest (§12.7.4, §12.7.8).\n *\n * This module is **metadata only**. No byte transport, no presigning, no\n * hashing: R2/S3 URL signing and digest computation are composition concerns\n * that need platform crypto, and core stays Node-free. What core owns is the\n * shape everyone must agree on — the hash format, the manifest state machine,\n * and reference counting — so that Postgres, D1, and the in-memory reference\n * cannot disagree about when an object is safe to delete.\n *\n * Object keys are tenant-scoped by construction ({@link tenantObjectKey}).\n * A global `sha256/<hex>` key space would turn object existence into a\n * cross-tenant oracle, which is why §12.7.4 forbids it even though it would\n * deduplicate better.\n */\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\n/** `sha256:<64 lowercase hex>`. The only content-address form core accepts. */\nexport const CONTENT_HASH_PATTERN = /^sha256:[0-9a-f]{64}$/;\n\n/** A validated content address. Branded so an unvalidated digest cannot stand in for one. */\nexport type ContentHash = string & { readonly __byokContentHash: unique symbol };\n\n/**\n * The single mint point for {@link ContentHash}.\n *\n * Fail-closed on uppercase hex: accepting both cases would make the same bytes\n * addressable under two keys, which breaks per-tenant deduplication and the\n * \"count each hash once\" billing rule (§12.7.6).\n *\n * @throws {ByokCoreError} code `content_hash_invalid`.\n */\nexport function contentHash(value: string): ContentHash {\n if (!CONTENT_HASH_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'content_hash_invalid',\n `Content hash must match ${CONTENT_HASH_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ContentHash;\n}\n\n/** Non-throwing form of {@link contentHash}. */\nexport function isContentHash(value: unknown): value is ContentHash {\n return typeof value === 'string' && CONTENT_HASH_PATTERN.test(value);\n}\n\n/**\n * What a deployment-level key namespace may look like: slash-joined segments of\n * lowercase alphanumerics, `.`, `_`, and `-`, each starting with an\n * alphanumeric. No leading or trailing slash, and therefore no empty segment.\n *\n * Narrow on purpose, and narrower than S3 keys allow. A prefix is spliced into\n * every key this SDK ever writes, so the only prefixes worth accepting are the\n * ones that reach the object store spelled exactly as configured: anything\n * requiring percent-encoding would give the deployment's objects two names, and\n * anything with an empty segment would make `a//b` and `a/b` the same key at\n * rest but different strings in config. Case is folded out for the same reason\n * {@link contentHash} refuses uppercase hex — one address, one spelling.\n */\nexport const OBJECT_KEY_PREFIX_PATTERN = /^[a-z0-9][a-z0-9._-]*(\\/[a-z0-9][a-z0-9._-]*)*$/;\n\n/** A validated deployment key namespace. Branded, so only the mint point below can produce one. */\nexport type ObjectKeyPrefix = string & { readonly __byokObjectKeyPrefix: unique symbol };\n\n/**\n * The single mint point for {@link ObjectKeyPrefix}.\n *\n * There is no \"empty means no prefix\" spelling here: a composition that has no\n * prefix omits the option, and one that passes `''` has misconfigured something\n * (an unset environment variable is the usual way). Accepting it silently would\n * make the two indistinguishable at exactly the moment the difference decides\n * where a deployment's objects live.\n *\n * @throws {ByokCoreError} code `object_key_prefix_invalid`.\n */\nexport function objectKeyPrefix(value: string): ObjectKeyPrefix {\n if (!OBJECT_KEY_PREFIX_PATTERN.test(value)) {\n throw new ByokCoreError(\n 'object_key_prefix_invalid',\n `Object key prefix must match ${OBJECT_KEY_PREFIX_PATTERN.source}, received ${JSON.stringify(value)}.`,\n );\n }\n return value as ObjectKeyPrefix;\n}\n\n/**\n * Tenant-scoped object key, e.g.\n * `tenants/<tenantId>/objects/sha256/<hex>` (§12.7.4).\n *\n * `prefix` namespaces the whole layout — `<prefix>/tenants/...` — so one bucket\n * can hold several deployments without either of them owning the bucket root.\n * Omitting it produces the unprefixed key verbatim, which is what makes the\n * option safe to add: every object already at rest was written without one.\n *\n * The prefix is an IMMUTABLE property of a deployment. It is spliced in here\n * and nowhere else, and nothing reads a key back under a second layout: change\n * a live deployment's prefix and its existing objects become unaddressable.\n * See `R2BlobStoreOptions.keyPrefix` in `@byok-sdk/cloud-dataplane` for the full\n * operational contract.\n */\nexport function tenantObjectKey(\n tenant: TenantId,\n hash: ContentHash,\n prefix?: ObjectKeyPrefix,\n): string {\n const hex = hash.slice('sha256:'.length);\n const key = `tenants/${tenant as string}/objects/sha256/${hex}`;\n return prefix === undefined ? key : `${prefix as string}/${key}`;\n}\n\n/**\n * Object manifest lifecycle (§12.7.8).\n *\n * `pending` exists because Postgres and R2 have no shared transaction: the row\n * is written before the bytes land, and only `committed` rows may be referenced\n * by a truth record. `delete_pending` is the tombstone the GC worker drives, so\n * a failed R2 delete is retryable instead of leaving usage silently wrong.\n */\nexport const OBJECT_STATES = ['pending', 'committed', 'delete_pending', 'deleted'] as const;\nexport type ObjectState = (typeof OBJECT_STATES)[number];\n\n/** Legal manifest transitions. Anything else raises `object_state_invalid`. */\nexport const OBJECT_STATE_TRANSITIONS: Readonly<Record<ObjectState, readonly ObjectState[]>> = {\n pending: ['committed', 'delete_pending'],\n committed: ['delete_pending'],\n delete_pending: ['deleted', 'committed'],\n deleted: [],\n};\n\nexport function isLegalObjectTransition(from: ObjectState, to: ObjectState): boolean {\n return OBJECT_STATE_TRANSITIONS[from].includes(to);\n}\n\n/** One row of `object_manifest` (§12.7.6). */\nexport interface ObjectManifestEntry {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n /** Declared at reservation time, re-verified at commit against the store's `HEAD`. */\n readonly byteSize: bigint;\n readonly contentType: string;\n readonly state: ObjectState;\n /** Number of live {@link ObjectReference} rows. `0` makes the object GC-eligible after grace. */\n readonly refCount: number;\n readonly createdAt: string;\n readonly updatedAt: string;\n /** Set when the row entered `delete_pending`; the grace window is measured from here. */\n readonly deletePendingAt?: string;\n}\n\n/** What references an object. `refKind`/`refId` are opaque to core. */\nexport interface ObjectReference {\n readonly tenantId: TenantId;\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n readonly createdAt: string;\n}\n\nexport interface ObjectManifestInput {\n readonly hash: ContentHash;\n readonly byteSize: bigint;\n readonly contentType: string;\n}\n\n/**\n * Finalize input. `byteSize`/`contentType` are what the composition actually\n * observed on the object store, not what the client declared — the whole point\n * of the check is that the two can differ (§12.7.7 step 4).\n */\nexport interface ObjectCommitInput {\n readonly hash: ContentHash;\n readonly observedByteSize: bigint;\n readonly observedContentType: string;\n}\n\nexport interface ObjectReferenceInput {\n readonly hash: ContentHash;\n readonly refKind: string;\n readonly refId: string;\n}\n\nexport interface ObjectListQuery {\n readonly state?: ObjectState;\n /**\n * Only rows whose `deletePendingAt` is at or before this instant.\n *\n * Must be a **canonical ISO-8601 UTC instant** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`, because the\n * in-memory composition compares it as a string and a SQL composition\n * compares it as a `timestamptz` — see `time.ts`.\n */\n readonly deletePendingBefore?: string;\n readonly limit?: number;\n}\n\n/**\n * Object manifest port. Tenant-first, async, metadata only.\n *\n * Raises: `object_not_found`, `object_state_invalid`,\n * `storage_integrity_mismatch` (commit observed size/type disagreeing with the\n * declared manifest row), `timestamp_not_canonical` (a `list` query whose\n * `deletePendingBefore` is not a canonical ISO-8601 UTC instant).\n */\nexport interface ObjectStore {\n collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult>;\n /** Creates or returns the `pending` row for `hash`. Idempotent per (tenant, hash). */\n putManifest(tenant: TenantId, input: ObjectManifestInput): Promise<ObjectManifestEntry>;\n /** `pending` → `committed` after verifying observed size/type. */\n commit(tenant: TenantId, input: ObjectCommitInput): Promise<ObjectManifestEntry>;\n get(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry | undefined>;\n list(tenant: TenantId, query: ObjectListQuery): Promise<readonly ObjectManifestEntry[]>;\n /** Idempotent per (tenant, hash, refKind, refId) — re-adding does not double-count. */\n addReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n removeReference(tenant: TenantId, input: ObjectReferenceInput): Promise<ObjectManifestEntry>;\n /** Tombstone step 1: only legal at `refCount === 0`. */\n markDeletePending(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n /** Tombstone step 3: the object store delete succeeded. */\n markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry>;\n}\n\nexport interface ObjectCollectExpiredInput extends CollectExpiredInput { readonly orphanBefore: string; }\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Tenant storage entitlement, usage, reservation and retention (§12.7.6-12.7.7).\n *\n * The SDK does not know what a plan is. It never sees `free`, `pro`, a price, a\n * currency, or a purchase flow — those belong to the host SaaS. What crosses\n * this boundary is a *numeric, versioned* entitlement the host issues, and the\n * constraint test asserts this file contains no plan-name or price vocabulary.\n * The moment the SDK hardcodes a tier, every host is stuck with the SDK's\n * commercial model.\n *\n * Byte counts are `bigint`. Serialization is a composition concern: JSON has no\n * bigint, so a cloud handler renders them as decimal strings on the wire. Using\n * `number` here would put a silent 2^53 ceiling into a storage quota contract.\n *\n * Reservation exists because Postgres and R2 have no shared transaction\n * (§12.7.7). Every durable write reserves first, uploads second, finalizes\n * third; the invariant `committed + reserved + expected <= hardLimit` is\n * checked under the reservation lock, which is what makes concurrent uploads\n * unable to oversell the tenant.\n */\nimport type { ContentHash } from './blob';\nimport type { CoreErrorCode } from './errors';\nimport type { TenantId } from './tenant';\n\n/**\n * The host-issued numeric entitlement (§12.7.6, verbatim).\n *\n * `version` is monotonic and CAS-checked on write: a delayed control-plane\n * update must not resurrect an older plan over a newer one.\n */\nexport interface TenantStorageEntitlement {\n tenantId: TenantId;\n version: bigint;\n hardLimitBytes: bigint;\n maxObjectBytes: bigint;\n maxInlineBytes: bigint;\n mailboxLimitBytes: bigint;\n retentionPolicyId: string;\n /** Canonical ISO-8601 UTC instant — see {@link TenantStorageEntitlementInput}. */\n downgradeGraceUntil?: string;\n}\n\n/**\n * Measured tenant usage (§12.7.6, verbatim).\n *\n * Carries no `tenantId` because it is always read through a tenant-scoped port\n * call — the tenant is the query, not a field of the answer.\n */\nexport interface TenantStorageUsage {\n committedObjectBytes: bigint;\n committedInlineBytes: bigint;\n reservedBytes: bigint;\n objectCount: bigint;\n updatedAt: string;\n}\n\n/** Entitlement write payload. `tenantId` comes from the port's first parameter. */\nexport interface TenantStorageEntitlementInput {\n readonly version: bigint;\n readonly hardLimitBytes: bigint;\n readonly maxObjectBytes: bigint;\n readonly maxInlineBytes: bigint;\n readonly mailboxLimitBytes: bigint;\n readonly retentionPolicyId: string;\n /**\n * Deadline after which an over-limit tenant is suspended rather than blocked.\n *\n * Must be a **canonical ISO-8601 UTC instant** (`YYYY-MM-DDTHH:mm:ss.sssZ`);\n * anything else is rejected with `timestamp_not_canonical`. The in-memory\n * composition compares this deadline as a string and a SQL composition\n * compares it as a `timestamptz`, and those two agree only on the canonical\n * form — see `time.ts`.\n */\n readonly downgradeGraceUntil?: string;\n}\n\n/** Durable write classes a reservation can cover. */\nexport const STORAGE_WRITE_KINDS = ['object', 'inline'] as const;\nexport type StorageWriteKind = (typeof STORAGE_WRITE_KINDS)[number];\n\nexport const STORAGE_RESERVATION_STATES = [\n 'reserved',\n 'committed',\n 'aborted',\n 'expired',\n] as const;\nexport type StorageReservationState = (typeof STORAGE_RESERVATION_STATES)[number];\n\nexport interface StorageReservation {\n readonly tenantId: TenantId;\n readonly reservationId: string;\n readonly state: StorageReservationState;\n readonly kind: StorageWriteKind;\n readonly expectedBytes: bigint;\n readonly contentHash: ContentHash;\n readonly contentType: string;\n readonly createdAt: string;\n readonly expiresAt: string;\n readonly settledAt?: string;\n}\n\nexport interface StorageReservationInput {\n readonly reservationId: string;\n readonly kind: StorageWriteKind;\n readonly expectedBytes: bigint;\n readonly contentHash: ContentHash;\n readonly contentType: string;\n readonly ttlMs: number;\n}\n\n/**\n * Finalize payload. Size/type are what the composition observed on the object\n * store, not what the client promised — disagreement is\n * `storage_integrity_mismatch`.\n *\n * Hash identity stays on the reservation as the authenticated daemon's\n * declaration (ADR-024). Object-store HEAD does not independently observe a\n * SHA-256 digest, so accepting one here would turn a copied declaration into a\n * false verification claim.\n */\nexport interface StorageFinalizeInput {\n readonly reservationId: string;\n readonly observedByteSize: bigint;\n readonly observedContentType: string;\n}\n\nexport interface StorageFinalizeResult {\n readonly reservation: StorageReservation;\n readonly usage: TenantStorageUsage;\n /**\n * True when this tenant already had the same content hash committed. The\n * reserved bytes are released and nothing is added: same tenant, same hash,\n * counted once (§12.7.6). Cross-tenant sharing never happens — usage is\n * per-tenant even when the bytes are identical.\n */\n readonly deduplicated: boolean;\n}\n\n/** Effective write posture derived from entitlement + usage + clock (§12.7.8). */\nexport const STORAGE_WRITE_POSTURES = ['normal', 'warning', 'blocked', 'suspended'] as const;\nexport type StorageWritePosture = (typeof STORAGE_WRITE_POSTURES)[number];\n\nexport interface StorageStatus {\n readonly entitlement: TenantStorageEntitlement;\n readonly usage: TenantStorageUsage;\n readonly posture: StorageWritePosture;\n /** `committed + reserved` against `hardLimitBytes`, for host UI. */\n readonly availableBytes: bigint;\n readonly graceActive: boolean;\n}\n\n/**\n * The five wire-stable storage error codes (§12.7.7). Renaming one is a\n * breaking change for every host that branches on them.\n */\nexport const STORAGE_ERROR_CODES = [\n 'storage_object_too_large',\n 'storage_quota_exceeded',\n 'storage_reservation_expired',\n 'storage_integrity_mismatch',\n 'storage_write_suspended',\n] as const satisfies readonly CoreErrorCode[];\n\nexport type StorageErrorCode = (typeof STORAGE_ERROR_CODES)[number];\n\n/** HTTP status mapping from §12.7.7. Compositions render these verbatim. */\nexport const STORAGE_ERROR_HTTP_STATUS = {\n storage_object_too_large: 413,\n storage_quota_exceeded: 507,\n storage_reservation_expired: 409,\n storage_integrity_mismatch: 422,\n storage_write_suspended: 423,\n} as const satisfies Record<StorageErrorCode, number>;\n\n/**\n * Quota port. Tenant-first, async.\n *\n * Raises: `storage_entitlement_missing`,\n * `storage_entitlement_version_conflict` (carries the current entitlement),\n * `storage_reservation_not_found`, and the five wire-stable codes above.\n */\nexport interface QuotaStore {\n collectExpired(tenant: TenantId, input: QuotaCollectExpiredInput): Promise<CollectExpiredResult>;\n readEntitlement(tenant: TenantId): Promise<TenantStorageEntitlement | undefined>;\n /**\n * Version CAS: a write at or below the stored version is rejected with the\n * current row. Raises `timestamp_not_canonical` when `downgradeGraceUntil` is\n * not a canonical ISO-8601 UTC instant.\n */\n writeEntitlement(\n tenant: TenantId,\n input: TenantStorageEntitlementInput,\n ): Promise<TenantStorageEntitlement>;\n readUsage(tenant: TenantId): Promise<TenantStorageUsage>;\n readStatus(tenant: TenantId): Promise<StorageStatus>;\n /** Tenant-scoped lookup used to bind a finalize request to its reservation. */\n readReservation(tenant: TenantId, reservationId: string): Promise<StorageReservation | undefined>;\n /**\n * Atomically checks `committed + reserved + expected <= hardLimitBytes` and,\n * on success, adds `expectedBytes` to `reservedBytes`.\n */\n reserve(tenant: TenantId, input: StorageReservationInput): Promise<StorageReservation>;\n /**\n * Moves reserved bytes to committed after verifying the observed object.\n * For object reservations, the composition commits the matching manifest in\n * the same authority step as reservation/accounting settlement.\n */\n finalizeReservation(\n tenant: TenantId,\n input: StorageFinalizeInput,\n ): Promise<StorageFinalizeResult>;\n /** Idempotent release. Already-settled reservations return their settled row. */\n abortReservation(tenant: TenantId, reservationId: string): Promise<StorageReservation>;\n\n}\n\nexport interface QuotaCollectExpiredInput extends CollectExpiredInput { readonly settledBefore: string; }\n","/**\n * Capability declaration (ADR-010).\n *\n * A client learns what a deployment supports by reading a declaration, never by\n * probing endpoints and interpreting 404/405/501. Status-code sniffing conflates\n * \"this build does not have that feature\" with \"that request was wrong\" and\n * with \"a proxy ate it\", and every consumer ends up with its own guess.\n *\n * The schema is intentionally the minimum that supports that rule: an opaque\n * string set plus a monotonic declaration version. Capability names are host and\n * deployment vocabulary — core validates their shape, never their meaning, so a\n * new capability never requires a core release.\n */\nimport { z } from 'zod';\nimport { ByokCoreError } from './errors';\n\nexport const CAPABILITY_DECLARATION_SCHEMA_ID = 'byok-capabilities-v1';\n\n/** Capability names: lowercase dotted segments, e.g. `board.sse`, `storage.reservations`. */\nexport const CAPABILITY_NAME_PATTERN = /^[a-z0-9]+(?:[._-][a-z0-9]+)*$/;\n\nexport const CapabilityDeclarationSchema = z\n .object({\n schema: z.literal(CAPABILITY_DECLARATION_SCHEMA_ID),\n /** Monotonic per deployment. Lets a client cache and detect a rollout. */\n version: z.number().int().nonnegative(),\n capabilities: z.array(z.string().regex(CAPABILITY_NAME_PATTERN)),\n })\n .superRefine((declaration, ctx) => {\n const seen = new Set<string>();\n for (const [index, name] of declaration.capabilities.entries()) {\n if (seen.has(name)) {\n ctx.addIssue({\n code: 'custom',\n path: ['capabilities', index],\n message: `Duplicate capability ${JSON.stringify(name)}.`,\n });\n }\n seen.add(name);\n }\n });\n\nexport type CapabilityDeclaration = z.infer<typeof CapabilityDeclarationSchema>;\n\n/**\n * Parses a declaration fail-closed.\n *\n * @throws {ByokCoreError} code `capability_declaration_invalid`.\n */\nexport function parseCapabilityDeclaration(input: unknown): CapabilityDeclaration {\n const result = CapabilityDeclarationSchema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'capability_declaration_invalid',\n `Invalid capability declaration: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\nexport function hasCapability(\n declaration: CapabilityDeclaration,\n capability: string,\n): boolean {\n return declaration.capabilities.includes(capability);\n}\n\n/**\n * The enforcement point ADR-010 exists for: a caller asserts the capability up\n * front and gets a named failure, instead of issuing the request and guessing\n * what the status code meant.\n *\n * @throws {ByokCoreError} code `capability_unavailable`.\n */\nexport function assertCapability(\n declaration: CapabilityDeclaration,\n capability: string,\n): void {\n if (!hasCapability(declaration, capability)) {\n throw new ByokCoreError(\n 'capability_unavailable',\n `Capability ${JSON.stringify(capability)} is not declared by this deployment.`,\n );\n }\n}\n","/**\n * Skill packs: declarative content a SaaS deployment distributes to a paired\n * device (plan `skill-pack-delivery-channel`, Phase 1).\n *\n * A pack is an `agentskills.io`-shaped `SKILL.md` plus its static companion\n * files. That is the WHOLE of it, and the narrowness is the design:\n *\n * 1. **No executable surface, by schema.** {@link SkillPackManifestSchema} is a\n * `strictObject`, so an unknown key is a rejection rather than a field\n * someone's tooling might later start honoring, and\n * {@link SKILL_PACK_FORBIDDEN_FIELDS} names the specific ones — `exec`,\n * `env`, `credential`, `hooks`, `allowed-tools` — that get their own\n * rejection message. The credential-isolation rule this SDK is built around\n * (§9.1) cannot be enforced downstream if the manifest can carry a command\n * to run or an environment to run it in, so it is enforced here, once.\n * 2. **Every declared limit has an evaluation point in this file.** A size cap\n * that nothing measures, a path rule that nothing checks, and a content hash\n * that nothing verifies are the same failure: a security claim with no\n * enforcement behind it. {@link checkSkillPackManifest} evaluates the\n * manifest-level limits and {@link checkSkillPackFileContent} evaluates the\n * byte-level ones, both returning a named rejection instead of a boolean, so\n * a caller can say which limit fired.\n * 3. **Hashing lives outside core.** Core has no `node:` import and no crypto\n * (the same rule `blob.ts` and `attestation.ts` follow), so this module owns\n * the canonical bytes a hash is taken over ({@link skillPackContentHashInput})\n * and the comparison, never the digest itself. The installer supplies what it\n * observed; core decides whether that is acceptable.\n *\n * Distribution is hosted HTTP (`@byok-sdk/cloud`'s `GET /byok/skill-packs`),\n * declared through ADR-010 as `skills.pack`. Nothing here touches the frozen v1\n * wire envelope, and there is deliberately no new message type: a pack is\n * content a device PULLS after reading a declaration, not a message a server\n * pushes into a task stream.\n */\nimport { z } from 'zod';\nimport { CONTENT_HASH_PATTERN, contentHash, type ContentHash } from './blob';\nimport { ByokCoreError } from './errors';\nimport type { TenantId } from './tenant';\n\nexport const SKILL_PACK_MANIFEST_SCHEMA_ID = 'byok-skill-pack-v1';\n\n/**\n * Pack names: lowercase, starting alphanumeric — the same shape\n * `OBJECT_KEY_PREFIX_PATTERN` accepts per segment, for the same reason. A pack\n * name becomes a directory name on a real device filesystem, so the accepted\n * set is the one that reaches disk spelled exactly as declared: no case folding\n * to collide over, no separator, no leading dot, nothing needing escaping.\n */\nexport const SKILL_PACK_NAME_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;\nexport const SKILL_PACK_NAME_MAX_LENGTH = 64;\nexport const SKILL_PACK_DESCRIPTION_MAX_LENGTH = 1024;\n\n/** `MAJOR.MINOR.PATCH`. A pack version orders two publications of one name; it is not a range language. */\nexport const SKILL_PACK_VERSION_PATTERN = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)$/;\n\n/**\n * Relative POSIX paths only: slash-joined segments of alphanumerics, `.`, `_`\n * and `-`, each STARTING with an alphanumeric.\n *\n * That single \"starts with an alphanumeric\" rule is what closes the traversal\n * class rather than a blocklist of spellings: `..` cannot match (a segment may\n * not begin with `.`), an absolute path cannot match (no leading slash), an\n * empty segment cannot match (`a//b`), a Windows drive or UNC path cannot match\n * (no `:`, no `\\`), a home-relative path cannot match (no `~`), and a dotfile\n * cannot match either. A blocklist would have to anticipate every encoding of\n * the same idea; this allowlist has nothing to anticipate.\n */\nexport const SKILL_PACK_FILE_PATH_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*(\\/[A-Za-z0-9][A-Za-z0-9._-]*)*$/;\nexport const SKILL_PACK_FILE_PATH_MAX_LENGTH = 200;\n\n/** The entry file every pack must carry, spelled as `agentskills.io` spells it. */\nexport const SKILL_PACK_ENTRY_PATH = 'SKILL.md';\n\n/** Per-file ceiling, measured in BYTES over the observed content — never in characters. */\nexport const SKILL_PACK_FILE_MAX_BYTES = 262_144;\n/** Whole-pack ceiling, over the sum of the observed file sizes. */\nexport const SKILL_PACK_MAX_BYTES = 1_048_576;\nexport const SKILL_PACK_MAX_FILES = 64;\n\n/**\n * Manifest keys that must never exist, listed so the prohibition is testable\n * rather than implied.\n *\n * `strictObject` already rejects every unknown key, so this list adds no new\n * authority — it adds a NAMED rejection for the subset that matters: an\n * operator who sees `unrecognized key: \"env\"` learns nothing about why, and a\n * reviewer reading the schema cannot tell whether the omission was a decision\n * or an oversight. Pinned from both directions by\n * `__tests__/skill-pack.test.ts`.\n */\nexport const SKILL_PACK_FORBIDDEN_FIELDS = [\n 'exec',\n 'command',\n 'entrypoint',\n 'run',\n 'script',\n 'shell',\n 'env',\n 'environment',\n 'credential',\n 'credentials',\n 'secret',\n 'secrets',\n 'token',\n 'apiKey',\n 'api_key',\n 'allowedTools',\n 'allowed-tools',\n 'hooks',\n 'preinstall',\n 'postinstall',\n] as const;\n\nconst ContentHashSchema = z\n .string()\n .regex(CONTENT_HASH_PATTERN)\n .transform((value) => contentHash(value));\n\n/** One file in a pack: where it goes, what it must hash to, and how big it is. */\nexport const SkillPackFileSchema = z.strictObject({\n path: z.string().min(1).max(SKILL_PACK_FILE_PATH_MAX_LENGTH).regex(SKILL_PACK_FILE_PATH_PATTERN),\n contentHash: ContentHashSchema,\n byteSize: z.number().int().nonnegative().max(SKILL_PACK_FILE_MAX_BYTES),\n});\n\nexport type SkillPackFile = z.infer<typeof SkillPackFileSchema>;\n\n/**\n * The published description of one pack.\n *\n * `contentHash` addresses the manifest AS A WHOLE — see\n * {@link skillPackContentHashInput} — which is what makes an install\n * content-addressed: two publications that differ in any field a device can\n * observe land in two directories, and re-installing an unchanged pack is a\n * no-op rather than a partial overwrite.\n */\nexport const SkillPackManifestSchema = z.strictObject({\n schema: z.literal(SKILL_PACK_MANIFEST_SCHEMA_ID),\n name: z.string().min(1).max(SKILL_PACK_NAME_MAX_LENGTH).regex(SKILL_PACK_NAME_PATTERN),\n version: z.string().regex(SKILL_PACK_VERSION_PATTERN),\n description: z.string().min(1).max(SKILL_PACK_DESCRIPTION_MAX_LENGTH),\n files: z.array(SkillPackFileSchema).min(1).max(SKILL_PACK_MAX_FILES),\n contentHash: ContentHashSchema,\n});\n\nexport type SkillPackManifest = z.infer<typeof SkillPackManifestSchema>;\n\n/**\n * Parses a manifest fail-closed.\n *\n * @throws {ByokCoreError} code `skill_pack_manifest_invalid`.\n */\nexport function parseSkillPackManifest(input: unknown): SkillPackManifest {\n if (typeof input === 'object' && input !== null) {\n const present = SKILL_PACK_FORBIDDEN_FIELDS.filter((field) =>\n Object.prototype.hasOwnProperty.call(input, field),\n );\n if (present.length > 0) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `A skill pack manifest carries no executable or credential surface; refusing ${present\n .map((field) => JSON.stringify(field))\n .join(', ')}.`,\n );\n }\n }\n const result = SkillPackManifestSchema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Invalid skill pack manifest: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * The exact bytes `manifest.contentHash` is the sha256 of.\n *\n * Written out here, in core, because both ends have to agree on it and neither\n * end may derive its own version: the publisher hashes this string to mint the\n * address, the installer hashes it again to verify what it fetched, and a\n * disagreement between the two would make every install either falsely\n * accepted or unconditionally rejected. Newline-delimited and terminated so no\n * field's content can be shifted into the next field's position, and the file\n * rows are sorted by path so two publishers that enumerate a directory in\n * different orders still mint the same address.\n */\nexport function skillPackContentHashInput(manifest: {\n readonly name: string;\n readonly version: string;\n readonly description: string;\n readonly files: readonly SkillPackFile[];\n}): string {\n const rows = [...manifest.files]\n .sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0))\n .map((file) => `${file.path}\\n${file.contentHash as string}\\n${file.byteSize}\\n`);\n return [\n `${SKILL_PACK_MANIFEST_SCHEMA_ID}\\n`,\n `${manifest.name}\\n`,\n `${manifest.version}\\n`,\n `${manifest.description.length}\\n`,\n `${manifest.description}\\n`,\n `${manifest.files.length}\\n`,\n ...rows,\n ].join('');\n}\n\n/** Every way a pack can be refused. One name per declared limit — see {@link SkillPackCheck}. */\nexport const SKILL_PACK_REJECTIONS = [\n 'path-unsafe',\n 'duplicate-path',\n 'entry-missing',\n 'file-count-over-cap',\n 'file-over-cap',\n 'pack-over-cap',\n 'size-mismatch',\n 'hash-mismatch',\n 'name-mismatch',\n] as const;\nexport type SkillPackRejection = (typeof SKILL_PACK_REJECTIONS)[number];\n\n/**\n * Outcome of a check. `bytes` is the measured total on the accept path so a\n * caller can record what it admitted; a rejection always names WHICH limit\n * fired, because \"the pack was rejected\" is not an operable message.\n */\nexport type SkillPackCheck =\n | { readonly ok: true; readonly bytes: number }\n | { readonly ok: false; readonly reason: SkillPackRejection; readonly detail: string };\n\n/** Non-throwing path-safety predicate — the one authority on what a pack may name. */\nexport function isSkillPackPathSafe(path: string): boolean {\n return (\n path.length > 0 &&\n path.length <= SKILL_PACK_FILE_PATH_MAX_LENGTH &&\n SKILL_PACK_FILE_PATH_PATTERN.test(path)\n );\n}\n\n/**\n * The manifest-level limits, evaluated.\n *\n * Runs over a manifest that has already parsed, so the per-field caps zod owns\n * are not re-litigated here. What is left is everything zod cannot see: the\n * relationships BETWEEN files (a duplicate path, a missing entry file, a total\n * that clears every per-file cap and still blows the pack cap).\n */\nexport function checkSkillPackManifest(manifest: SkillPackManifest): SkillPackCheck {\n if (manifest.files.length > SKILL_PACK_MAX_FILES) {\n return {\n ok: false,\n reason: 'file-count-over-cap',\n detail: `${manifest.files.length} files exceeds the ${SKILL_PACK_MAX_FILES} file limit.`,\n };\n }\n\n const seen = new Set<string>();\n let bytes = 0;\n for (const file of manifest.files) {\n if (!isSkillPackPathSafe(file.path)) {\n return { ok: false, reason: 'path-unsafe', detail: `${JSON.stringify(file.path)} is not a safe relative path.` };\n }\n if (seen.has(file.path)) {\n return { ok: false, reason: 'duplicate-path', detail: `${JSON.stringify(file.path)} is declared twice.` };\n }\n seen.add(file.path);\n if (file.byteSize > SKILL_PACK_FILE_MAX_BYTES) {\n return {\n ok: false,\n reason: 'file-over-cap',\n detail: `${JSON.stringify(file.path)} declares ${file.byteSize} bytes, over the ${SKILL_PACK_FILE_MAX_BYTES} byte per-file limit.`,\n };\n }\n bytes += file.byteSize;\n }\n\n if (!seen.has(SKILL_PACK_ENTRY_PATH)) {\n return {\n ok: false,\n reason: 'entry-missing',\n detail: `A skill pack must carry ${SKILL_PACK_ENTRY_PATH}.`,\n };\n }\n if (bytes > SKILL_PACK_MAX_BYTES) {\n return {\n ok: false,\n reason: 'pack-over-cap',\n detail: `${bytes} declared bytes exceeds the ${SKILL_PACK_MAX_BYTES} byte pack limit.`,\n };\n }\n return { ok: true, bytes };\n}\n\n/** What an installer actually measured for one file, as opposed to what the manifest declared. */\nexport interface ObservedSkillPackFile {\n readonly byteSize: number;\n readonly contentHash: ContentHash;\n}\n\n/**\n * The byte-level limits, evaluated against what was actually fetched.\n *\n * The asymmetry with {@link checkSkillPackManifest} is the point: the declared\n * size is a claim by the publisher and the observed size is a fact about the\n * bytes on the device, so the cap is enforced on the OBSERVED value. A check\n * that only ever measured the declaration would pass a 4 KiB manifest row\n * attached to a 40 MiB response.\n */\nexport function checkSkillPackFileContent(\n declared: SkillPackFile,\n observed: ObservedSkillPackFile,\n): SkillPackCheck {\n if (!isSkillPackPathSafe(declared.path)) {\n return { ok: false, reason: 'path-unsafe', detail: `${JSON.stringify(declared.path)} is not a safe relative path.` };\n }\n if (observed.byteSize > SKILL_PACK_FILE_MAX_BYTES) {\n return {\n ok: false,\n reason: 'file-over-cap',\n detail: `${JSON.stringify(declared.path)} delivered ${observed.byteSize} bytes, over the ${SKILL_PACK_FILE_MAX_BYTES} byte per-file limit.`,\n };\n }\n if (observed.byteSize !== declared.byteSize) {\n return {\n ok: false,\n reason: 'size-mismatch',\n detail: `${JSON.stringify(declared.path)} declared ${declared.byteSize} bytes and delivered ${observed.byteSize}.`,\n };\n }\n if ((observed.contentHash as string) !== (declared.contentHash as string)) {\n return {\n ok: false,\n reason: 'hash-mismatch',\n detail: `${JSON.stringify(declared.path)} declared ${declared.contentHash as string} and delivered ${observed.contentHash as string}.`,\n };\n }\n return { ok: true, bytes: observed.byteSize };\n}\n\n/**\n * `SKILL.md` frontmatter, in the `agentskills.io` shape: exactly `name` and\n * `description`, both required.\n *\n * The allowlist is the whole contract. `allowed-tools`, `hooks` and friends are\n * real fields in other skill dialects and every one of them widens what a pack\n * can ask a runtime to do; a parser that merely IGNORED them would still let a\n * pack ship them to a host that does not.\n */\nexport interface SkillFrontmatter {\n readonly name: string;\n readonly description: string;\n}\n\n/** The only frontmatter keys a pack may declare. */\nexport const SKILL_FRONTMATTER_FIELDS = ['name', 'description'] as const;\n\nconst FRONTMATTER_DELIMITER = '---';\nconst FRONTMATTER_LINE_PATTERN = /^([A-Za-z][A-Za-z0-9_-]*):[ \\t]*(.*)$/;\n\nfunction unquote(value: string): string | undefined {\n const trimmed = value.trim();\n if (trimmed.length >= 2) {\n const first = trimmed[0];\n const last = trimmed[trimmed.length - 1];\n if ((first === '\"' && last === '\"') || (first === \"'\" && last === \"'\")) {\n const inner = trimmed.slice(1, -1);\n return inner.includes(first) ? undefined : inner;\n }\n }\n return trimmed;\n}\n\n/**\n * Parses and validates a `SKILL.md`'s frontmatter block.\n *\n * Deliberately not a YAML engine: this is a closed two-key grammar, and the\n * whole reason to hand-write it is that a general parser would happily accept\n * anchors, aliases, nested maps, multi-document streams and block scalars —\n * every one of which is a way to express something this format has decided not\n * to have. Anything outside the grammar is a rejection, never a skipped line.\n *\n * @throws {ByokCoreError} code `skill_pack_frontmatter_invalid`.\n */\nexport function parseSkillFrontmatter(text: string): SkillFrontmatter {\n const reject = (message: string): never => {\n throw new ByokCoreError('skill_pack_frontmatter_invalid', message);\n };\n\n const lines = text.split('\\n');\n if (lines[0]?.trimEnd() !== FRONTMATTER_DELIMITER) {\n reject(`A skill file must open with a ${FRONTMATTER_DELIMITER} frontmatter delimiter.`);\n }\n const closing = lines.findIndex((line, index) => index > 0 && line.trimEnd() === FRONTMATTER_DELIMITER);\n if (closing < 0) reject(`The frontmatter block is not closed by a ${FRONTMATTER_DELIMITER} line.`);\n\n const fields = new Map<string, string>();\n for (const line of lines.slice(1, closing)) {\n if (line.trim().length === 0) continue;\n const match = FRONTMATTER_LINE_PATTERN.exec(line);\n if (match === null) reject(`Frontmatter line ${JSON.stringify(line)} is not a \\`key: value\\` pair.`);\n const key = match![1]!;\n if (!(SKILL_FRONTMATTER_FIELDS as readonly string[]).includes(key)) {\n reject(\n `Frontmatter key ${JSON.stringify(key)} is not one of ${SKILL_FRONTMATTER_FIELDS.join(', ')}; a skill declares no tools, hooks, or environment.`,\n );\n }\n if (fields.has(key)) reject(`Frontmatter key ${JSON.stringify(key)} is declared twice.`);\n const value = unquote(match![2]!);\n if (value === undefined || value.length === 0) {\n reject(`Frontmatter key ${JSON.stringify(key)} has no usable value.`);\n }\n fields.set(key, value!);\n }\n\n const name = fields.get('name');\n const description = fields.get('description');\n if (name === undefined) reject('Frontmatter is missing `name`.');\n if (description === undefined) reject('Frontmatter is missing `description`.');\n if (name!.length > SKILL_PACK_NAME_MAX_LENGTH || !SKILL_PACK_NAME_PATTERN.test(name!)) {\n reject(\n `Frontmatter \\`name\\` must match ${SKILL_PACK_NAME_PATTERN.source} and be at most ${SKILL_PACK_NAME_MAX_LENGTH} characters.`,\n );\n }\n if (description!.length > SKILL_PACK_DESCRIPTION_MAX_LENGTH) {\n reject(`Frontmatter \\`description\\` exceeds ${SKILL_PACK_DESCRIPTION_MAX_LENGTH} characters.`);\n }\n return { name: name!, description: description! };\n}\n\n/**\n * The entry file's own declaration must agree with the manifest's.\n *\n * Two authorities naming the same pack is not a redundancy to tolerate — a\n * device that installed under one name and handed the runtime a skill calling\n * itself another would be projecting content nobody asked for.\n */\nexport function checkSkillPackEntry(manifest: SkillPackManifest, entryText: string): SkillPackCheck {\n const frontmatter = parseSkillFrontmatter(entryText);\n if (frontmatter.name !== manifest.name) {\n return {\n ok: false,\n reason: 'name-mismatch',\n detail: `${SKILL_PACK_ENTRY_PATH} declares ${JSON.stringify(frontmatter.name)} but the manifest declares ${JSON.stringify(manifest.name)}.`,\n };\n }\n return { ok: true, bytes: new TextEncoder().encode(entryText).length };\n}\n\n/** One file's bytes, as the distribution surface hands them over. */\nexport interface SkillPackFileContent {\n readonly path: string;\n readonly contentHash: ContentHash;\n readonly byteSize: number;\n /** UTF-8 text. A pack carries Markdown, YAML and static text assets — never binaries, never archives. */\n readonly content: string;\n}\n\n/** What a publisher hands the store: the validated manifest plus the bytes it addresses. */\nexport interface SkillPackPublishInput {\n readonly manifest: SkillPackManifest;\n readonly files: readonly { readonly path: string; readonly content: string }[];\n}\n\nexport interface SkillPackListQuery {\n readonly limit?: number;\n}\n\n/**\n * Skill pack port. Tenant-first, async, content plus manifest.\n *\n * Registered in `ports-contract.ts` as a core PORT, and deliberately not (yet)\n * a member of `CoreStores`: a composition contract that named it would oblige\n * every existing composition to implement it in the same slice, and the\n * Postgres implementation is Phase 2 of this plan. See `ports-contract.ts` for\n * the full note on that split.\n *\n * Raises: `skill_pack_manifest_invalid` (a publish whose bytes disagree with\n * the manifest it was handed).\n */\nexport interface SkillPackStore {\n /** Idempotent per (tenant, name, contentHash). Publishing a changed pack under the same name replaces it. */\n publish(tenant: TenantId, input: SkillPackPublishInput): Promise<SkillPackManifest>;\n get(tenant: TenantId, name: string): Promise<SkillPackManifest | undefined>;\n list(tenant: TenantId, query: SkillPackListQuery): Promise<readonly SkillPackManifest[]>;\n readFile(tenant: TenantId, name: string, path: string): Promise<SkillPackFileContent | undefined>;\n}\n","/**\n * The composition contract: the full set of store ports, plus the clock seam.\n *\n * Every method on every port in this package obeys two rules, and\n * `src/__tests__/constraints.test.ts` enumerates them method by method to prove\n * it (sprint I7):\n *\n * 1. **Async.** Every method returns a `Promise`. A synchronous port would\n * silently exclude SQL and object-store compositions from the contract.\n * 2. **Tenant-first.** Every method's first parameter is a required\n * {@link TenantId}. There is no bare `deviceId`/`taskId` lookup anywhere —\n * §12.6.2 layer 3 forbids the index such a lookup would need, and layer 5\n * requires the tenant to be part of the lookup key rather than a second\n * comparison step that can be forgotten.\n *\n * No port method can change the tenant of an existing row. That is not an\n * omission: \"move this to another tenant\" is the one operation that would make\n * every cross-tenant assertion in the conformance suite unfalsifiable.\n */\nimport type { PresenceStore } from './presence';\nimport type { BoardStore } from './board';\nimport type { MailboxStore } from './mailbox';\nimport type { ObjectStore } from './blob';\nimport type { QuotaStore } from './quota';\nimport type { SkillPackStore } from './skill-pack';\nimport type { TenantId } from './tenant';\nimport type { TruthStore } from './truth';\n\n/**\n * Injected time.\n *\n * TTL semantics (presence expiry and reservation expiry) are\n * behavior the conformance suite has to assert deterministically, which is\n * impossible against a wall clock. Compositions inject one; nothing in core\n * calls `Date.now()` directly.\n */\nexport interface Clock {\n now(): Date;\n}\n\n/** A clock pinned to a fixed instant, advanced explicitly. Used by tests and the in-memory reference. */\nexport interface MutableClock extends Clock {\n advance(ms: number): void;\n set(instant: Date): void;\n}\n\n/** Every port a composition must supply. */\nexport interface CoreStores {\n readonly mailbox: MailboxStore;\n readonly board: BoardStore;\n readonly truth: TruthStore;\n readonly presence: PresenceStore;\n readonly objects: ObjectStore;\n readonly quota: QuotaStore;\n /**\n * Skill-pack storage is a MANDATORY member: every composition creates the\n * tables and supplies the port (Phase 2 of `skill-pack-delivery-channel`).\n * Storage presence is not capability advertisement — the wire route/capability\n * stays optional in `@byok-sdk/cloud` (`includeSkillPacks`), and a deployment\n * that never declares `skills.pack` simply keeps the tables empty.\n */\n readonly skillPacks: SkillPackStore;\n}\n\n/** Names of the ports in {@link CoreStores}, in contract order. */\nexport const CORE_STORE_NAMES = [\n 'mailbox',\n 'board',\n 'truth',\n 'presence',\n 'objects',\n 'quota',\n 'skillPacks',\n] as const;\n\nexport type CoreStoreName = (typeof CORE_STORE_NAMES)[number];\n\n// Layer 2 of §12.6.2 — the tenant-closed facade a handler actually receives —\n// is deliberately not here. It is shaped by how handlers are written, and the\n// first handlers land in `@byok-sdk/cloud` (S3). Defining it now would mean\n// guessing that shape and freezing the guess into the contract package that\n// every later sprint depends on. The tenant-first ports below are what make\n// that facade a thin binding rather than a new authority.\n","/**\n * The declared method inventory of every core port (sprint I7).\n *\n * This table is contract data, not test data — it says what a port IS, and it\n * is enforced from two directions that must read the same table:\n *\n * - `__tests__/constraints.test.ts` scans the *source interfaces* in this\n * package and asserts each listed method exists, is async, and takes a\n * required `TenantId` first.\n * - `@byok-sdk/conformance`'s port-inventory dimension asserts every *composition\n * under test* implements exactly these methods — no missing method, and no\n * extra one that the contract has not pinned down and that therefore no\n * other composition would implement.\n *\n * It lives in shipped source rather than under `__tests__/` because the second\n * enforcer is now a separate package (S4A story O-005): a `core → conformance`\n * devDependency for a table `core` itself asserts against would be a cycle,\n * and the direction that has to hold is `conformance → core`.\n *\n * Adding a port method means editing this table, which is the point: a port\n * grows by contract, not by whichever composition needed something.\n */\nimport { CORE_STORE_NAMES, type CoreStoreName } from './stores';\n\n/**\n * Ports that are core ports but NOT members of the composition contract.\n *\n * Now empty, and that is the whole point of Phase 2. Phase 1 of\n * `skill-pack-delivery-channel` held `skillPacks` here as a self-declared\n * temporary bridge: adding it to `CoreStores` before its Postgres\n * implementation existed would have obliged every composition to implement it\n * in the same slice, and the alternatives — an optional port member (a\n * compatibility fallback, forbidden) or a port outside the contract table\n * entirely (exempt from the tenant-first scan, the one rule most worth having)\n * — were both worse. Phase 2 delivered that implementation and moved\n * `skillPacks` into `CORE_STORE_NAMES`, so this list goes back to empty exactly\n * as the Phase 1 note promised. The empty set stays named rather than deleted:\n * it is the testable statement \"every core port is a composition member\", which\n * `CORE_STORE_NAMES` alone cannot make.\n */\nexport const CORE_NON_COMPOSITION_PORT_NAMES = [] as const;\n\nexport const CORE_PORT_METHODS: Readonly<Record<CoreStoreName, readonly string[]>> = {\n mailbox: [\n 'append',\n 'readUsage',\n 'readAfter',\n 'recordDelivery',\n 'advanceCursor',\n 'readCursor',\n 'collectExpired',\n 'expirePending',\n 'closeStream',\n 'reopenStream',\n ],\n board: ['create', 'get', 'list', 'claim', 'unclaim', 'updateStatus', 'remove'],\n truth: ['writeTerminal', 'writeSnapshot', 'getRecord', 'listManifest'],\n presence: ['publish', 'read', 'list', 'collectExpired'],\n objects: [\n 'putManifest',\n 'commit',\n 'get',\n 'list',\n 'addReference',\n 'removeReference',\n 'markDeletePending',\n 'markDeleted',\n 'collectExpired',\n ],\n quota: [\n 'readEntitlement',\n 'writeEntitlement',\n 'readUsage',\n 'readStatus',\n 'readReservation',\n 'reserve',\n 'finalizeReservation',\n 'abortReservation',\n 'collectExpired',\n ],\n skillPacks: ['publish', 'get', 'list', 'readFile'],\n};\n\n/** The interface each port name is declared as, for the source-side scan. */\nexport const CORE_PORT_INTERFACES: Readonly<Record<CoreStoreName, string>> = {\n mailbox: 'MailboxStore',\n board: 'BoardStore',\n truth: 'TruthStore',\n presence: 'PresenceStore',\n objects: 'ObjectStore',\n quota: 'QuotaStore',\n skillPacks: 'SkillPackStore',\n};\n","/**\n * Device proof envelope and canonical signing bytes (§12.6.3, sprint §S6.2).\n *\n * Three things live here and nothing else:\n *\n * 1. **The protected-claims schema.** Every field a signature must cover so the\n * proof binds a *specific request*: tenant, product, device, key + epoch,\n * request id, operation, resource, the request line (method+path or a stable\n * operation id), and the body's hash *and* size. Signing only the body is\n * forbidden — it would let a valid proof be replayed against a different\n * operation or resource.\n * 2. **A dependency-free deterministic canonicalizer.** RFC 8785 (JCS) in the\n * narrow subset the envelope allows. Node and Workers must produce\n * byte-identical output, so the accepted value space is deliberately small:\n * strings, booleans, null, safe integers, plain objects, arrays. Floats,\n * non-safe integers, `NaN`, `Infinity`, `undefined`, `bigint`, dates and\n * class instances throw instead of being coerced — a signature over a value\n * whose serialization is implementation-defined is not a signature.\n * 3. **The verify port.** An interface, never an implementation: core is\n * Node-free and Workers-safe, and `node:crypto` and WebCrypto disagree about\n * key handling. The composition brings its own verifier.\n *\n * Claims are **untrusted input**. `tenantId` here is a plain string, not a\n * branded `TenantId`, because a device asserting a tenant proves nothing: the\n * claim is a lookup key used to load the device row, and the row is the\n * authority (§12.6.2 layer 5). Branding happens after that lookup, not here.\n */\nimport { z } from 'zod';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\n\n/** Envelope schema id, self-consistent with the domain prefix below. */\nexport const DEVICE_PROOF_SCHEMA_ID = 'byok-device-proof-v1';\n\n/**\n * Domain separation prefix (§12.6.3). Prepended to the canonical claim bytes\n * before signing so a device-proof signature can never be replayed as a nonce\n * signature (`byok-nonce-v1\\n`) or a record attestation.\n */\nexport const DEVICE_PROOF_DOMAIN_PREFIX = 'byok-device-proof-v1\\n';\n\nexport const DEVICE_PROOF_VERSION = 1;\n\n/** Signature algorithms this envelope version admits. */\nexport const DEVICE_PROOF_ALGORITHMS = ['ed25519'] as const;\nexport type DeviceProofAlgorithm = (typeof DEVICE_PROOF_ALGORITHMS)[number];\n\n/**\n * HTTP header carrying the base64url device-proof envelope on a truth-route\n * request (§12.6.3). Both the daemon that mints the proof and the host that\n * decodes it must name the exact same header, so it is a single wire constant\n * here rather than a string re-spelled on each side.\n */\nexport const DEVICE_PROOF_HEADER = 'x-byok-device-proof';\n\nconst BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;\nconst HTTP_METHOD_PATTERN = /^[A-Z]+$/;\n\n// ---------------------------------------------------------------------------\n// Canonicalization (RFC 8785 subset)\n// ---------------------------------------------------------------------------\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | readonly JsonValue[] | { readonly [key: string]: JsonValue };\nexport type JsonObject = { readonly [key: string]: JsonValue };\n\nfunction canonicalizationFailure(path: string, reason: string): ByokCoreError {\n return new ByokCoreError(\n 'proof_canonicalization_failed',\n `Cannot canonicalize ${path}: ${reason}`,\n );\n}\n\nfunction isPlainObject(value: object): boolean {\n const prototype: unknown = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n\nfunction canonicalizeValue(value: unknown, path: string, seen: Set<object>): string {\n if (value === null) return 'null';\n\n switch (typeof value) {\n case 'boolean':\n return value ? 'true' : 'false';\n case 'string':\n // JSON.stringify implements exactly the ECMAScript string serialization\n // RFC 8785 mandates, including well-formed escaping of lone surrogates.\n return JSON.stringify(value);\n case 'number': {\n if (!Number.isSafeInteger(value)) {\n throw canonicalizationFailure(\n path,\n `only safe integers are canonicalizable, received ${String(value)}`,\n );\n }\n // Normalizes -0 to 0; RFC 8785 has no signed zero.\n return String(value === 0 ? 0 : value);\n }\n case 'undefined':\n throw canonicalizationFailure(path, 'undefined has no canonical form');\n case 'bigint':\n throw canonicalizationFailure(path, 'bigint is not a JSON type');\n case 'function':\n case 'symbol':\n throw canonicalizationFailure(path, `${typeof value} is not a JSON type`);\n case 'object':\n break;\n default:\n throw canonicalizationFailure(path, `unsupported type ${typeof value}`);\n }\n\n const objectValue = value as object;\n if (seen.has(objectValue)) {\n throw canonicalizationFailure(path, 'circular reference');\n }\n seen.add(objectValue);\n try {\n if (Array.isArray(objectValue)) {\n const parts = objectValue.map((entry, index) =>\n canonicalizeValue(entry, `${path}[${index}]`, seen),\n );\n return `[${parts.join(',')}]`;\n }\n if (!isPlainObject(objectValue)) {\n throw canonicalizationFailure(\n path,\n 'only plain objects and arrays are canonicalizable',\n );\n }\n // Default string sort compares UTF-16 code units, which is what RFC 8785\n // specifies for member ordering.\n const keys = Object.keys(objectValue).sort();\n const record = objectValue as Record<string, unknown>;\n const parts = keys.map((key) => {\n const encodedKey = JSON.stringify(key);\n const encodedValue = canonicalizeValue(record[key], `${path}.${key}`, seen);\n return `${encodedKey}:${encodedValue}`;\n });\n return `{${parts.join(',')}}`;\n } finally {\n seen.delete(objectValue);\n }\n}\n\n/**\n * Canonical JSON text for `value`, per RFC 8785 restricted to the value space\n * above. Key insertion order never affects the output; anything outside the\n * accepted space throws `proof_canonicalization_failed`.\n */\nexport function canonicalizeJson(value: JsonValue): string {\n return canonicalizeValue(value, '<root>', new Set());\n}\n\n/** UTF-8 bytes of {@link canonicalizeJson}. `TextEncoder` is a platform global on Node and Workers. */\nexport function canonicalizeJsonBytes(value: JsonValue): Uint8Array {\n return new TextEncoder().encode(canonicalizeJson(value));\n}\n\n// ---------------------------------------------------------------------------\n// Protected claims\n// ---------------------------------------------------------------------------\n\n/**\n * The signed claim set (§S6.2).\n *\n * The request line is expressible two ways — `method` + `path`, or a stable\n * `operationId` — and exactly one form must be present. Allowing both at once\n * would create two different canonical byte strings for one request; allowing\n * neither would drop the operation binding the whole design rests on.\n */\nexport const DeviceProofProtectedClaimsSchema = z\n .strictObject({\n version: z.literal(DEVICE_PROOF_VERSION),\n tenantId: z.string().min(1),\n productId: z.string().min(1),\n deviceId: z.string().min(1),\n /** Identity of the signing key, resolved against the device row at verify time. */\n keyId: z.string().min(1),\n /** Rotation generation. An older epoch is rejected by the verifier, not here. */\n keyEpoch: z.number().int().nonnegative(),\n /** Idempotency key: exact replay returns the original result, reuse with a different body is a conflict. */\n requestId: z.string().min(1),\n /** Logical operation, e.g. `truth.write`. */\n operation: z.string().min(1),\n /** Tenant-scoped resource the operation targets. */\n resource: z.string().min(1),\n method: z.string().regex(HTTP_METHOD_PATTERN).optional(),\n path: z.string().startsWith('/').optional(),\n operationId: z.string().min(1).optional(),\n bodySha256: z.string().regex(CONTENT_HASH_PATTERN),\n /** Bound alongside the hash so a truncation attack cannot hide behind a hash collision claim. */\n bodySize: z.number().int().nonnegative(),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime().optional(),\n nonce: z.string().min(1).optional(),\n })\n .superRefine((claims, ctx) => {\n const hasRequestLine = claims.method !== undefined && claims.path !== undefined;\n const hasOperationId = claims.operationId !== undefined;\n if (hasRequestLine === hasOperationId) {\n ctx.addIssue({\n code: 'custom',\n message:\n 'Claims must carry exactly one request binding: both `method` and `path`, or `operationId`.',\n });\n }\n if (!hasRequestLine && (claims.method !== undefined || claims.path !== undefined)) {\n ctx.addIssue({\n code: 'custom',\n message: '`method` and `path` must be supplied together.',\n });\n }\n });\n\nexport type DeviceProofProtectedClaims = z.infer<typeof DeviceProofProtectedClaimsSchema>;\n\nexport const DeviceProofEnvelopeV1Schema = z.strictObject({\n schema: z.literal(DEVICE_PROOF_SCHEMA_ID),\n algorithm: z.enum(DEVICE_PROOF_ALGORITHMS),\n protected: DeviceProofProtectedClaimsSchema,\n /** base64url, unpadded. */\n signature: z.string().regex(BASE64URL_PATTERN),\n});\n\nexport type DeviceProofEnvelopeV1 = z.infer<typeof DeviceProofEnvelopeV1Schema>;\n\n/**\n * Parses an envelope fail-closed.\n *\n * @throws {ByokCoreError} code `proof_envelope_invalid`.\n */\nexport function parseDeviceProofEnvelope(input: unknown): DeviceProofEnvelopeV1 {\n const result = DeviceProofEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'proof_envelope_invalid',\n `Invalid device proof envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field rather than by spreading the parsed object: an absent\n * optional must be an *absent key*, never a key holding `undefined`, or\n * `{nonce: undefined}` and `{}` would be the same request with two different\n * signatures. The canonicalizer refuses `undefined` outright, so this\n * projection is where absence is decided.\n */\nexport function deviceProofCanonicalClaims(claims: DeviceProofProtectedClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n tenantId: claims.tenantId,\n productId: claims.productId,\n deviceId: claims.deviceId,\n keyId: claims.keyId,\n keyEpoch: claims.keyEpoch,\n requestId: claims.requestId,\n operation: claims.operation,\n resource: claims.resource,\n bodySha256: claims.bodySha256,\n bodySize: claims.bodySize,\n issuedAt: claims.issuedAt,\n };\n if (claims.method !== undefined) canonical['method'] = claims.method;\n if (claims.path !== undefined) canonical['path'] = claims.path;\n if (claims.operationId !== undefined) canonical['operationId'] = claims.operationId;\n if (claims.expiresAt !== undefined) canonical['expiresAt'] = claims.expiresAt;\n if (claims.nonce !== undefined) canonical['nonce'] = claims.nonce;\n return canonical;\n}\n\n/** Canonical JSON text of the protected claim set, without the domain prefix. */\nexport function deviceProofCanonicalJson(claims: DeviceProofProtectedClaims): string {\n return canonicalizeJson(deviceProofCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a device signs and a verifier reconstructs:\n * `byok-device-proof-v1\\n` followed by the canonical claim JSON, UTF-8 encoded.\n *\n * Frozen by `src/__tests__/golden/device-proof-v1.canonical.json`.\n */\nexport function deviceProofSigningInput(claims: DeviceProofProtectedClaims): Uint8Array {\n return new TextEncoder().encode(\n DEVICE_PROOF_DOMAIN_PREFIX + deviceProofCanonicalJson(claims),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Verify port\n// ---------------------------------------------------------------------------\n\nexport interface DeviceProofVerifyInput {\n readonly algorithm: DeviceProofAlgorithm;\n /** Raw public key, base64url — the JWK `x` encoding the device registry stores. */\n readonly publicKey: string;\n readonly signature: string;\n readonly signingInput: Uint8Array;\n}\n\n/**\n * Injected signature verification.\n *\n * Not a store port, so it has no tenant parameter: it answers a pure\n * cryptographic question about bytes. Deciding *which* key to check against is\n * the caller's tenant-scoped device-row lookup, and keeping that out of here is\n * what stops a verifier from becoming a second authority on device identity.\n */\nexport interface DeviceProofVerifier {\n verify(input: DeviceProofVerifyInput): Promise<boolean>;\n}\n","import type { CollectExpiredInput, CollectExpiredResult } from './retention';\n/**\n * Device assertion envelope, canonical signing bytes, and verifier\n * (plan `device-assertion-broker`, P3 ①-⑤).\n *\n * A device assertion is a short-lived, audience-scoped statement a *paired\n * device* makes about itself — \"this device, paired to this product against\n * this server, wants to talk to `<audience>` for the next two minutes\" — signed\n * with the same Ed25519 device identity key `attestation.ts`'s device proof\n * uses. A sibling CLI installed alongside the daemon presents one to the host's\n * cloud, which exchanges it for a product session. It is NOT a request-bound\n * proof (`attestation.ts`) and the two must never be interchangeable; see the\n * domain prefix below.\n *\n * Four decisions this file encodes, none of them re-litigable here:\n *\n * 1. **A custom JSON signing envelope, not JWS.** The domain prefix has to be\n * *inside* the signed bytes. JWS puts its type tag in a header that no\n * verifier is required to check, which is a fail-open shape: a token minted\n * for one purpose verifies for another as long as the key matches. So this\n * clones the mechanism `attestation.ts` already froze — RFC 8785-subset\n * canonicalization (`canonicalizeJson`, imported, never re-implemented) plus\n * a golden fixture pinning the exact bytes.\n * 2. **What the claims deliberately do NOT carry.** No `devicePublicKey`: a\n * verifier must resolve the key from its own device directory by `deviceId`,\n * or the envelope becomes self-authenticating. No caller identity: every\n * process under the same UID can reach the control socket, so a \"who asked\"\n * field would be synthesized authority, not evidence. No `keyId`: there is\n * no key-rotation story for this envelope yet, and a field nothing populates\n * honestly is a structure that invites a verifier to trust it.\n * 3. **`audience` is a single string, never an array.** A multi-audience token\n * forces every verifier to agree on the same containment rule; one string\n * compared with `===` cannot be got wrong.\n * 4. **The verifier cannot forget the revocation check.** {@link\n * verifyDeviceAssertion} takes `revoked` as a REQUIRED dependency, so a\n * caller that never looked the device row up does not compile. The daemon's\n * own local checks (see `@byok-sdk/client`'s `assertion.issue`) are only half\n * of revocation; the other half is this recheck at exchange time, and no\n * documentation may claim the daemon satisfies \"synchronous invalidation\"\n * on its own.\n *\n * Like `attestation.ts`, this module is crypto-free: signature verification is\n * an injected port (`DeviceAssertionVerifier`), because core must load on\n * Workers and `node:crypto`/WebCrypto disagree about key handling.\n */\nimport { z } from 'zod';\nimport { canonicalizeJson, type JsonObject, type JsonValue } from './attestation';\nimport { ByokCoreError } from './errors';\nimport type { DevicePrincipal } from './principals';\nimport { isTenantId, type TenantId } from './tenant';\n\n/** Envelope schema id, self-consistent with the domain prefix below. */\nexport const DEVICE_ASSERTION_SCHEMA_ID = 'byok-device-assertion-v1';\n\n/**\n * Domain separation prefix, prepended to the canonical claim bytes before\n * signing.\n *\n * Must remain mutually NON-PREFIX with the other three things this same Ed25519\n * device key signs — `byok-nonce-v1\\n` (challenge/token renewal, see\n * `@byok-sdk/client`'s `device-keys.ts`), `byok-device-proof-v1\\n`\n * (`attestation.ts`), and `byok-task-assertion-v1\\n` ({@link\n * TASK_ASSERTION_DOMAIN_PREFIX}) — so no signature over one domain can ever be\n * reinterpreted as a signature over another.\n * `packages/core/src/__tests__/device-assertion.test.ts` asserts the property\n * across the three core-owned prefixes and\n * `packages/client/src/__tests__/device-assertion-broker.test.ts` across all\n * four; those assertions are the falsifier for this whole design, not a nicety.\n */\nexport const DEVICE_ASSERTION_DOMAIN_PREFIX = 'byok-device-assertion-v1\\n';\n\nexport const DEVICE_ASSERTION_VERSION = 1;\n\n/**\n * Envelope schema id of the task-scoped assertion (contract §8.1), kept beside\n * the device one so the two are read — and reviewed — together.\n */\nexport const TASK_ASSERTION_SCHEMA_ID = 'byok-task-assertion-v1';\n\n/**\n * Domain separation prefix for `byok-task-assertion-v1`.\n *\n * Joins the mutually NON-PREFIX set the ONE Ed25519 device key signs under:\n * `byok-nonce-v1\\n`, `byok-device-proof-v1\\n`,\n * `byok-device-assertion-v1\\n`, and this. Contract §8.1 requires the old and\n * new envelopes to be non-interchangeable, and domain separation is the half of\n * that which holds even when both envelopes parse: a device-lane signature can\n * never be reinterpreted as a task-lane one, because the signed bytes differ in\n * their first line. The four-way falsifier lives in\n * `packages/client/src/__tests__/device-assertion-broker.test.ts` (the only\n * suite that can import the real nonce domain); the three core-owned prefixes\n * are cross-checked in `packages/core/src/__tests__/device-assertion.test.ts`.\n */\nexport const TASK_ASSERTION_DOMAIN_PREFIX = 'byok-task-assertion-v1\\n';\n\nexport const TASK_ASSERTION_VERSION = 1;\n\n/** Signature algorithms this envelope version admits. */\nexport const DEVICE_ASSERTION_ALGORITHMS = ['ed25519'] as const;\nexport type DeviceAssertionAlgorithm = (typeof DEVICE_ASSERTION_ALGORITHMS)[number];\n\n/**\n * Default assertion lifetime. Short on purpose: the daemon keeps no `jti`\n * ledger (it is not on the verification path and could not stop a real replay\n * anyway), so a narrow expiry window plus a burn-on-use verifier is the whole\n * replay story.\n */\nexport const DEVICE_ASSERTION_DEFAULT_TTL_MS = 120_000;\n\n/**\n * Hard ceiling on the lifetime, enforced at BOTH ends: a daemon refuses to be\n * configured above it, and {@link verifyDeviceAssertion} refuses an envelope\n * whose own `issuedAt`→`expiresAt` span exceeds it regardless of who minted it.\n */\nexport const DEVICE_ASSERTION_MAX_TTL_MS = 300_000;\n\n/** Bound on the `audience` claim, in UTF-8 bytes — an allowlist entry is a short identifier, not a document. */\nexport const DEVICE_ASSERTION_AUDIENCE_MAX_BYTES = 256;\n\n/** base64url of 16 CSPRNG bytes (128 bits), unpadded. */\nconst JTI_PATTERN = /^[A-Za-z0-9_-]{22}$/;\n\n/** base64url of a raw 64-byte Ed25519 signature, unpadded. */\nconst SIGNATURE_PATTERN = /^[A-Za-z0-9_-]{86}$/;\n\nfunction utf8ByteLength(value: string): number {\n return new TextEncoder().encode(value).length;\n}\n\n/**\n * The one `audience` validator both envelope kinds parse through.\n *\n * Declared once rather than restated per schema: a second copy is a second\n * place the byte bound could be relaxed, and `byok-task-assertion-v1` inherits\n * the bound by construction rather than by a reviewer noticing.\n */\nconst ASSERTION_AUDIENCE = z\n .string()\n .min(1)\n .refine((value) => utf8ByteLength(value) <= DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, {\n message: `audience must be at most ${DEVICE_ASSERTION_AUDIENCE_MAX_BYTES} UTF-8 bytes`,\n });\n\n// ---------------------------------------------------------------------------\n// Claims\n// ---------------------------------------------------------------------------\n\n/**\n * The signed claim set. `strictObject` with every member REQUIRED: an optional\n * claim is a claim a verifier may or may not see, and this envelope is small\n * enough that there is no honest reason for one.\n *\n * `issuer` is the paired server's origin (scheme + host + port, normalized) —\n * it binds the assertion to the deployment the device is actually paired\n * against, so an assertion minted by a device paired to a staging server cannot\n * be presented to production.\n */\nexport const DeviceAssertionClaimsSchema = z.strictObject({\n version: z.literal(DEVICE_ASSERTION_VERSION),\n /** The paired server's origin, normalized (`new URL(serverUrl).origin`). */\n issuer: z.string().min(1),\n productId: z.string().min(1),\n /** The device row this assertion claims to be. A lookup key, never authority — the row is the authority. */\n deviceId: z.string().min(1),\n /** Exactly one audience, compared with `===` by every verifier. Never an array, never a prefix. */\n audience: ASSERTION_AUDIENCE,\n /** 128-bit CSPRNG token, base64url unpadded. The verifier burns it; the signer never reuses one. */\n jti: z.string().regex(JTI_PATTERN),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime(),\n});\n\nexport type DeviceAssertionClaims = z.infer<typeof DeviceAssertionClaimsSchema>;\n\nexport const DeviceAssertionEnvelopeV1Schema = z.strictObject({\n schema: z.literal(DEVICE_ASSERTION_SCHEMA_ID),\n algorithm: z.enum(DEVICE_ASSERTION_ALGORITHMS),\n protected: DeviceAssertionClaimsSchema,\n /** Raw 64-byte Ed25519 signature, base64url unpadded. */\n signature: z.string().regex(SIGNATURE_PATTERN),\n});\n\nexport type DeviceAssertionEnvelopeV1 = z.infer<typeof DeviceAssertionEnvelopeV1Schema>;\n\n/**\n * Parses an envelope fail-closed.\n *\n * @throws {ByokCoreError} code `assertion_envelope_invalid`.\n */\nexport function parseDeviceAssertionEnvelope(input: unknown): DeviceAssertionEnvelopeV1 {\n const result = DeviceAssertionEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'assertion_envelope_invalid',\n `Invalid device assertion envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field rather than by spreading the parsed object — the same\n * discipline `deviceProofCanonicalClaims` documents. Nothing here is optional,\n * so there is no absent-key decision to get wrong; the explicit projection is\n * what keeps it that way if a field is ever added.\n */\nexport function deviceAssertionCanonicalClaims(claims: DeviceAssertionClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n issuer: claims.issuer,\n productId: claims.productId,\n deviceId: claims.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n };\n return canonical;\n}\n\n/** Canonical JSON text of the claim set, without the domain prefix. */\nexport function deviceAssertionCanonicalJson(claims: DeviceAssertionClaims): string {\n return canonicalizeJson(deviceAssertionCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a device signs and a verifier reconstructs:\n * `byok-device-assertion-v1\\n` followed by the canonical claim JSON, UTF-8\n * encoded.\n *\n * Frozen by `src/__tests__/golden/device-assertion-v1.canonical.json`.\n */\nexport function deviceAssertionSigningInput(claims: DeviceAssertionClaims): Uint8Array {\n return new TextEncoder().encode(\n DEVICE_ASSERTION_DOMAIN_PREFIX + deviceAssertionCanonicalJson(claims),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Verify\n// ---------------------------------------------------------------------------\n\nexport interface DeviceAssertionVerifyInput {\n readonly algorithm: DeviceAssertionAlgorithm;\n /** Raw public key, base64url — the JWK `x` encoding the device registry stores. */\n readonly publicKey: string;\n readonly signature: string;\n readonly signingInput: Uint8Array;\n}\n\n/**\n * Injected signature verification, for the same reason `DeviceProofVerifier`\n * exists: core is Node-free and Workers-safe, so it answers no cryptographic\n * question itself. Kept separate from `DeviceProofVerifier` even though the\n * shapes coincide — one composition object satisfies both — because this file's\n * entire purpose is that the two domains never become interchangeable, and a\n * shared type is the first step toward a shared code path.\n */\nexport interface DeviceAssertionVerifier {\n verify(input: DeviceAssertionVerifyInput): Promise<boolean>;\n}\n\n/**\n * The device-row fields a verification reads — the verifier's OWN directory\n * row, resolved by `deviceId`, never anything the envelope carried.\n *\n * Both fields together, from one lookup, are what make forgetting impossible:\n * the caller cannot obtain `publicKeyJwkX` without also obtaining the current\n * `revoked` state, because they arrive as one object from one call.\n */\nexport interface DeviceAssertionDeviceRow {\n /** JWK `x` of the device's registered Ed25519 public key. The ONLY key a signature is ever checked against. */\n readonly publicKeyJwkX: string;\n /** The row's CURRENT revocation state, read in the same lookup as the key. */\n readonly revoked: boolean;\n}\n\n/**\n * Everything a verification needs that is NOT in the envelope.\n *\n * The device row is supplied through a LOOKUP PORT, not as a pre-fetched\n * value, and that is the whole point (this is the faithful clone of\n * `DeviceProofVerifier`'s \"core is never a second authority on device\n * identity\" shape). `verifyDeviceAssertion` reads `deviceId` from the parsed\n * claims and calls `lookupDevice(deviceId)` ITSELF, so:\n *\n * - There is no way to invoke a verification without providing the means to\n * look the current row up — \"I forgot to check revocation\" cannot be\n * expressed, because the function does the lookup, not the caller.\n * - Both the public key AND the revocation state come from that one row, so a\n * caller cannot pass a key while claiming `revoked: false` from thin air.\n * - The `deviceId` handed to `lookupDevice` is the claimed one; the row it\n * returns is authority. A device asserting an identity it is not is caught\n * by the lookup missing, or by the returned row's key failing the signature.\n */\nexport interface DeviceAssertionVerifyDeps {\n readonly verifier: DeviceAssertionVerifier;\n /**\n * Resolve the verifier's own device row by the claimed `deviceId`.\n * `undefined` for an unknown device. Sync or async; awaited either way.\n */\n readonly lookupDevice: (\n deviceId: string,\n ) => Promise<DeviceAssertionDeviceRow | undefined> | DeviceAssertionDeviceRow | undefined;\n /** Injected instant — core never reads a wall clock (`stores.ts`'s `Clock`). */\n readonly now: Date;\n /** Bound on `issuedAt`→`expiresAt`. Defaults to (and may never exceed) {@link DEVICE_ASSERTION_MAX_TTL_MS}. */\n readonly maxLifetimeMs?: number;\n}\n\nfunction parseInstant(value: string): number | undefined {\n const parsed = Date.parse(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n}\n\n/**\n * Raw Ed25519 public key as a JWK `x`: 32 bytes, base64url unpadded — exactly\n * 43 characters. The envelope's `algorithm` is a closed `ed25519`, so the row's\n * key must be an Ed25519 key of this exact shape.\n */\nconst EDDSA_JWK_X_PATTERN = /^[A-Za-z0-9_-]{43}$/;\n\n/**\n * codex round-2 F2: strict runtime validation of a looked-up device row, since\n * `lookupDevice` is a caller-supplied port whose return value TypeScript cannot\n * enforce at runtime. Fails closed on any shape that isn't exactly a usable row:\n *\n * - `revoked` must be the literal boolean `false`. A missing, `undefined`,\n * truthy, or non-boolean `revoked` is a malformed row — and a missing\n * `revoked` reading as \"not revoked\" (`undefined` is falsey) is precisely the\n * fail-open this guard closes: a revoked device must never slip through on a\n * row shape the caller got wrong.\n * - `publicKeyJwkX` must be a present, well-formed Ed25519 JWK `x`. A missing or\n * malformed key is rejected here, before any crypto — so a bad key can never\n * reach (and throw inside) the verifier port either.\n */\nfunction isUsableDeviceRow(row: unknown): row is DeviceAssertionDeviceRow {\n if (row === null || typeof row !== 'object') return false;\n if ((row as { revoked?: unknown }).revoked !== false) return false;\n const key = (row as { publicKeyJwkX?: unknown }).publicKeyJwkX;\n return typeof key === 'string' && EDDSA_JWK_X_PATTERN.test(key);\n}\n\n/**\n * Resolve the effective lifetime ceiling, or `undefined` when the caller asked\n * for one this module refuses to honour.\n *\n * Both envelope kinds resolve it here so `byok-task-assertion-v1` cannot be\n * given a longer window than `byok-device-assertion-v1` — contract §8.1 says\n * the task lane inherits the SDK's existing maximum TTL rather than deriving\n * its own from an unpredictable task lifetime.\n */\nfunction resolveMaxLifetimeMs(requested: number | undefined): number | undefined {\n const maxLifetimeMs = requested ?? DEVICE_ASSERTION_MAX_TTL_MS;\n if (\n !Number.isSafeInteger(maxLifetimeMs) ||\n maxLifetimeMs <= 0 ||\n maxLifetimeMs > DEVICE_ASSERTION_MAX_TTL_MS\n ) {\n return undefined;\n }\n return maxLifetimeMs;\n}\n\n/**\n * The time-window rule, shared by both envelope kinds so there is exactly one\n * place it can be widened: a parseable `[issuedAt, expiresAt)` half-open\n * interval, no clock-skew allowance, and a span no longer than the ceiling.\n */\nfunction assertionWindowAdmits(\n claims: { readonly issuedAt: string; readonly expiresAt: string },\n now: Date,\n maxLifetimeMs: number,\n): boolean {\n const issuedAt = parseInstant(claims.issuedAt);\n const expiresAt = parseInstant(claims.expiresAt);\n if (issuedAt === undefined || expiresAt === undefined) return false;\n if (expiresAt <= issuedAt) return false;\n if (expiresAt - issuedAt > maxLifetimeMs) return false;\n\n const instant = now.getTime();\n if (!Number.isFinite(instant)) return false;\n return instant >= issuedAt && instant < expiresAt;\n}\n\n/**\n * Verifies an assertion and returns its claims, or `undefined`.\n *\n * Every rejected state collapses to `undefined` — malformed input, an unknown\n * or revoked device, an expired or over-long window, a bad signature — so a\n * route has one response for all of them and cannot accidentally leak which\n * check failed. That is the same shape `authenticateDeviceProof`\n * (`@byok-sdk/cloud`) already uses.\n *\n * The row lookup and both authority reads (key, revocation) happen INSIDE this\n * function — see {@link DeviceAssertionVerifyDeps}. What the caller MUST still\n * do afterward, and this cannot: assert `claims.audience` equals the audience\n * it actually serves, assert `claims.issuer`/`claims.productId` match its own\n * deployment, and BURN `claims.jti` so the assertion cannot be presented\n * twice. The daemon keeps no `jti` ledger; single use is entirely the\n * verifier's job.\n */\nexport async function verifyDeviceAssertion(\n input: unknown,\n deps: DeviceAssertionVerifyDeps,\n): Promise<DeviceAssertionClaims | undefined> {\n const maxLifetimeMs = resolveMaxLifetimeMs(deps.maxLifetimeMs);\n if (maxLifetimeMs === undefined) return undefined;\n\n let envelope: DeviceAssertionEnvelopeV1;\n try {\n envelope = parseDeviceAssertionEnvelope(input);\n } catch {\n return undefined;\n }\n const claims = envelope.protected;\n\n // Resolve the row by the CLAIMED deviceId, then read authority from the row.\n // An unknown device, a revoked one, and a MALFORMED one all stop here, before\n // any crypto is done on the claimed identity's behalf. The row is validated\n // strictly (codex round-2 F2): `revoked` must be exactly `false` and the key\n // must be a well-formed Ed25519 JWK `x` — a missing `revoked` never reads as\n // \"not revoked\", and a missing/malformed key never reaches the verifier.\n const row = await deps.lookupDevice(claims.deviceId);\n if (!isUsableDeviceRow(row)) return undefined;\n\n // No clock-skew allowance: this envelope's whole safety margin is its short\n // window, and a tolerance knob is just that window quietly widened. A\n // deployment whose clocks disagree by minutes has a clock problem to fix, not\n // an assertion lifetime to extend. Validity is a half-open interval\n // `[issuedAt, expiresAt)` — at the exact `expiresAt` instant the assertion is\n // already expired. See {@link assertionWindowAdmits}, the one place that rule\n // is written down for both envelope kinds.\n if (!assertionWindowAdmits(claims, deps.now, maxLifetimeMs)) return undefined;\n\n const verified = await deps.verifier.verify({\n algorithm: envelope.algorithm,\n // The row's key, never an envelope-supplied one.\n publicKey: row.publicKeyJwkX,\n signature: envelope.signature,\n signingInput: deviceAssertionSigningInput(claims),\n });\n if (!verified) return undefined;\n\n return claims;\n}\n\n// ---------------------------------------------------------------------------\n// Authenticate + consume once\n// ---------------------------------------------------------------------------\n\n/** The verifier's complete current row. Claims remain lookup keys, never authority. */\nexport interface DeviceAssertionAuthorityRow extends DeviceAssertionDeviceRow {\n readonly tenantId: TenantId;\n readonly productId: string;\n readonly deviceId: string;\n}\n\n/** Trusted deployment values the host compares with exact string equality. */\nexport interface DeviceAssertionExpectedBinding {\n readonly issuer: string;\n readonly productId: string;\n readonly audience: string;\n}\n\n/**\n * The envelope kinds that share one replay authority.\n *\n * A closed union with no default: contract §8.2(2) requires the replay key to\n * carry an envelope-kind discriminator so the same `jti` presented as a device\n * assertion and as a task assertion occupies two key slots and neither lane can\n * burn the other's. A defaulted or optional field would reintroduce exactly the\n * collision the discriminator exists to prevent, so every caller states its\n * lane and a caller that forgets does not compile.\n */\nexport type DeviceAssertionReplaySchemaId =\n | typeof DEVICE_ASSERTION_SCHEMA_ID\n | typeof TASK_ASSERTION_SCHEMA_ID;\n\n/** One replay key. Every field is derived from verified claims/current authority. */\nexport interface DeviceAssertionReplayConsumeInput {\n /** Which signed envelope kind produced this key. Required; never inferred, never defaulted. */\n readonly schema: DeviceAssertionReplaySchemaId;\n readonly tenantId: TenantId;\n readonly issuer: string;\n readonly productId: string;\n readonly deviceId: string;\n readonly audience: string;\n readonly jti: string;\n readonly expiresAt: string;\n}\n\n/**\n * Atomic single-use authority. `true` means this caller inserted the key;\n * `false` means it was already consumed. Operational failures throw and must\n * never be translated into authenticated success.\n */\nexport interface DeviceAssertionReplayAuthority {\n collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult>;\n consume(input: DeviceAssertionReplayConsumeInput): Promise<boolean>;\n}\n\nexport interface AuthenticateDeviceAssertionDeps {\n readonly verifier: DeviceAssertionVerifier;\n readonly lookupDevice: (\n deviceId: string,\n ) => Promise<DeviceAssertionAuthorityRow | undefined> | DeviceAssertionAuthorityRow | undefined;\n readonly replay: DeviceAssertionReplayAuthority;\n readonly expected: DeviceAssertionExpectedBinding;\n readonly now: Date;\n readonly maxLifetimeMs?: number;\n}\n\n/**\n * What both lanes' results carry: the current-authority principal plus the\n * audit fields of the credential that was spent. Never a name a caller holds —\n * a value is always one lane or the other, and {@link AuthenticatedAssertion}\n * is the union to accept when a consumer genuinely serves both.\n */\ninterface AuthenticatedAssertionBase {\n readonly device: DevicePrincipal;\n readonly issuer: string;\n readonly audience: string;\n readonly jti: string;\n readonly issuedAt: string;\n readonly expiresAt: string;\n}\n\n/**\n * Audit-safe result of a consumed DEVICE assertion; no credential or signature\n * is retained.\n *\n * `lane` is the discriminator contract §8.1 requires the result to carry. The\n * two lanes have zero interchange, so a consumer that serves only one of them\n * has to be able to say which — and \"which fields are present\" is not that\n * statement: a structural check drifts the moment either claim set grows, and\n * an extension relationship would make a task credential satisfy every\n * device-lane type check for free.\n */\nexport interface AuthenticatedDeviceAssertion extends AuthenticatedAssertionBase {\n readonly lane: 'device';\n}\n\nfunction isNonEmptyExactString(value: unknown): value is string {\n return typeof value === 'string' && value.length > 0 && value.trim() === value;\n}\n\nfunction isAuthorityRow(row: unknown, requestedDeviceId: string): row is DeviceAssertionAuthorityRow {\n if (row === null || typeof row !== 'object') return false;\n const candidate = row as Partial<DeviceAssertionAuthorityRow>;\n return (\n isTenantId(candidate.tenantId) &&\n isNonEmptyExactString(candidate.productId) &&\n candidate.deviceId === requestedDeviceId\n );\n}\n\n/**\n * Authenticate one device assertion and atomically consume its JTI.\n *\n * All invalid authentication states collapse to `undefined`. Replay-store\n * operational failures reject the promise, allowing a host to return an\n * availability error without ever degrading to signature-only acceptance.\n */\nexport async function authenticateDeviceAssertion(\n input: unknown,\n deps: AuthenticateDeviceAssertionDeps,\n): Promise<AuthenticatedDeviceAssertion | undefined> {\n if (\n !isNonEmptyExactString(deps.expected.issuer) ||\n !isNonEmptyExactString(deps.expected.productId) ||\n !isNonEmptyExactString(deps.expected.audience) ||\n utf8ByteLength(deps.expected.audience) > DEVICE_ASSERTION_AUDIENCE_MAX_BYTES\n ) {\n return undefined;\n }\n\n let authorityRow: DeviceAssertionAuthorityRow | undefined;\n const claims = await verifyDeviceAssertion(input, {\n verifier: deps.verifier,\n lookupDevice: async (deviceId) => {\n const row = await deps.lookupDevice(deviceId);\n if (!isAuthorityRow(row, deviceId)) return undefined;\n authorityRow = row;\n return { publicKeyJwkX: row.publicKeyJwkX, revoked: row.revoked };\n },\n now: deps.now,\n ...(deps.maxLifetimeMs === undefined ? {} : { maxLifetimeMs: deps.maxLifetimeMs }),\n });\n if (claims === undefined || authorityRow === undefined) return undefined;\n\n if (\n claims.issuer !== deps.expected.issuer ||\n claims.productId !== deps.expected.productId ||\n claims.audience !== deps.expected.audience ||\n authorityRow.productId !== deps.expected.productId ||\n authorityRow.deviceId !== claims.deviceId\n ) {\n return undefined;\n }\n\n const consumed = await deps.replay.consume({\n schema: DEVICE_ASSERTION_SCHEMA_ID,\n tenantId: authorityRow.tenantId,\n issuer: claims.issuer,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n expiresAt: claims.expiresAt,\n });\n if (!consumed) return undefined;\n\n return {\n lane: 'device',\n device: {\n kind: 'device',\n tenantId: authorityRow.tenantId,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n },\n issuer: claims.issuer,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Task assertion (`byok-task-assertion-v1`) — contract §8.1 / §8.2(2)\n// ---------------------------------------------------------------------------\n\n/**\n * The task-scoped assertion: a separate envelope, NOT a device assertion with\n * extra claims.\n *\n * Contract §8.1 fixes the property this section exists to hold: the old and new\n * envelopes are not interchangeable in either direction. Three independent\n * mechanisms carry it, and none of them is \"the verifier remembers to check\":\n *\n * 1. **Different signed bytes.** {@link TASK_ASSERTION_DOMAIN_PREFIX} is\n * non-prefix with every other domain this device key signs under, so a\n * signature made in one lane cannot be reinterpreted in another even if the\n * claim sets were made to coincide.\n * 2. **Different strict schemas.** `schema` is a literal and `protected` is a\n * `strictObject`, so a device envelope fails\n * {@link parseTaskAssertionEnvelope} on its missing `taskId`/`agentRef`/\n * `toolsetId` and a task envelope fails\n * {@link parseDeviceAssertionEnvelope} on those same claims being unknown.\n * 3. **Different replay keys.** {@link DeviceAssertionReplayConsumeInput}\n * carries a required `schema` segment (§8.2(2)), so the two lanes' ledgers\n * are distinguishable and neither can burn the other's `jti`.\n *\n * What is deliberately NOT duplicated: `jti`/signature encodings, the audience\n * byte bound, {@link DEVICE_ASSERTION_MAX_TTL_MS}, the window rule and the\n * device-row rule are the SAME validators the device lane uses, referenced not\n * copied. Contract §8.1: the task lane inherits the SDK's existing limits and\n * does not define a second, looser set.\n *\n * The claim set carries no caller identity for the reason stated at the top of\n * this file — under one UID every process can reach the control socket, so a\n * self-reported \"who asked\" is synthesized authority. The task/AgentRef binding\n * here is authority precisely because the daemon signs it after checking its\n * own local registry, not because a caller sent it.\n */\n\n/** Bound on each AgentRef scalar, in UTF-8 bytes. Mirrors `AGENT_REF_MAX_BYTES` in `@byok-sdk/protocol`. */\nexport const TASK_ASSERTION_AGENT_REF_MAX_BYTES = 160;\n\n/** Bound on `toolsetId`. Mirrors the `ToolsetIdSchema` bound in `@byok-sdk/protocol`. */\nexport const TASK_ASSERTION_TOOLSET_ID_MAX_LENGTH = 128;\n\n/**\n * AgentRef scalar, restated from the SDK's authoritative `AgentRefSchema`\n * (`@byok-sdk/protocol`'s `messages.ts`) rather than imported.\n *\n * Core may not grow an edge to protocol — the §12.1 invariant that\n * `packages/core/src/__tests__/constraints.test.ts` enforces on shipped source\n * AND tests — so this lane cannot import the authority it must not weaken. The\n * falsifier for the restatement is therefore a BEHAVIOURAL drift test in the\n * client suite (`device-assertion-broker.test.ts`), which imports the real\n * `AgentRefSchema`/`ToolsetIdSchema` alongside these and asserts the two agree\n * on every candidate. A weakened copy here turns that suite red; it does not\n * quietly widen the task lane.\n */\nconst AGENT_REF_VALUE = z\n .string()\n .min(1)\n .max(TASK_ASSERTION_AGENT_REF_MAX_BYTES)\n .refine((value) => utf8ByteLength(value) <= TASK_ASSERTION_AGENT_REF_MAX_BYTES, {\n message: `AgentRef values must not exceed ${TASK_ASSERTION_AGENT_REF_MAX_BYTES} UTF-8 bytes`,\n })\n .regex(/^[^\\u0000-\\u001f\\u007f\\r\\n]+$/u, 'AgentRef values must not contain control characters');\n\nconst WINDOWS_RESERVED_AGENT_SEGMENT = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\\..*)?$/iu;\n\n/** The frozen offer's Agent identity. Same shape and same rules as the SDK's `AgentRefSchema`. */\nexport const TaskAssertionAgentRefSchema = z\n .object({\n agentId: AGENT_REF_VALUE.regex(/^[^\\\\/:<>\"|?*]+$/u, 'agentId must be one portable pathname segment')\n .refine((value) => value !== '.' && value !== '..', 'agentId must not be a dot segment')\n .refine(\n (value) => !/[. ]$/u.test(value) && !WINDOWS_RESERVED_AGENT_SEGMENT.test(value),\n 'agentId must be a portable Windows-safe pathname segment',\n ),\n /**\n * From the FROZEN offer. Contract §8.1 forbids substituting the current\n * revision read from a working directory's `profile.json`; this module\n * cannot enforce that (it never reads a file) — the signer's contract does.\n */\n profileRevision: AGENT_REF_VALUE,\n })\n .strict();\n\nexport type TaskAssertionAgentRef = z.infer<typeof TaskAssertionAgentRefSchema>;\n\n/** Logical, host-owned toolset id. Restated from `@byok-sdk/protocol`'s `ToolsetIdSchema`; see {@link TaskAssertionAgentRefSchema}. */\nconst TOOLSET_ID_VALUE = z\n .string()\n .min(1)\n .max(TASK_ASSERTION_TOOLSET_ID_MAX_LENGTH)\n .regex(/^[a-z0-9]+(?:[._-][a-z0-9]+)*$/u, 'toolset ids must be lowercase logical identifiers');\n\n/**\n * The wire's task id shape: the same `z.string().min(1)` the protocol envelope's\n * `task_id` routing key is built from. Contract §8.1 makes `taskId` the sole\n * execution locator, so this lane must accept exactly what the wire routes —\n * neither inventing a narrower bound nor admitting an empty one.\n */\nconst TASK_ID_VALUE = z.string().min(1);\n\n/**\n * The signed task claim set: the device claim set plus the three bindings that\n * make the assertion task-scoped, every member required for the same reason the\n * device claims are.\n */\nexport const TaskAssertionClaimsSchema = z.strictObject({\n version: z.literal(TASK_ASSERTION_VERSION),\n /** The paired server's origin, normalized (`new URL(serverUrl).origin`). */\n issuer: z.string().min(1),\n productId: z.string().min(1),\n /** The device row this assertion claims to be. A lookup key, never authority. */\n deviceId: z.string().min(1),\n /** Exactly one audience, compared with `===`. Participates in the replay key (§8.2(2)). */\n audience: ASSERTION_AUDIENCE,\n /** Same 128-bit CSPRNG token shape the device lane uses; burned once per `schema` segment. */\n jti: z.string().regex(JTI_PATTERN),\n issuedAt: z.iso.datetime(),\n expiresAt: z.iso.datetime(),\n /** The only execution locator (§8.1). No attemptId is minted beside it. */\n taskId: TASK_ID_VALUE,\n /** The frozen offer's Agent identity, at the SDK's full AgentRef strength. */\n agentRef: TaskAssertionAgentRefSchema,\n /** The frozen toolset this invocation belongs to (the wire's `toolset` field). */\n toolsetId: TOOLSET_ID_VALUE,\n});\n\nexport type TaskAssertionClaims = z.infer<typeof TaskAssertionClaimsSchema>;\n\nexport const TaskAssertionEnvelopeV1Schema = z.strictObject({\n schema: z.literal(TASK_ASSERTION_SCHEMA_ID),\n algorithm: z.enum(DEVICE_ASSERTION_ALGORITHMS),\n protected: TaskAssertionClaimsSchema,\n /** Raw 64-byte Ed25519 signature, base64url unpadded — the device lane's encoding, unchanged. */\n signature: z.string().regex(SIGNATURE_PATTERN),\n});\n\nexport type TaskAssertionEnvelopeV1 = z.infer<typeof TaskAssertionEnvelopeV1Schema>;\n\n/**\n * Parses a task envelope fail-closed. A device assertion is not a degraded task\n * assertion and is rejected here, not tolerated (§8.1: task lane zero fallback).\n *\n * @throws {ByokCoreError} code `assertion_envelope_invalid`.\n */\nexport function parseTaskAssertionEnvelope(input: unknown): TaskAssertionEnvelopeV1 {\n const result = TaskAssertionEnvelopeV1Schema.safeParse(input);\n if (!result.success) {\n throw new ByokCoreError(\n 'assertion_envelope_invalid',\n `Invalid task assertion envelope: ${result.error.issues\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n { cause: result.error },\n );\n }\n return result.data;\n}\n\n/**\n * Projects task claims into the exact JSON object that gets canonicalized.\n *\n * Built field by field, like the device projection, and covering EVERY claim —\n * contract §8.1 requires the canonical projection to include all added claims,\n * so an unsigned `taskId`, `agentRef` or `toolsetId` would be a claim a verifier\n * reads but no signature covers.\n */\nexport function taskAssertionCanonicalClaims(claims: TaskAssertionClaims): JsonObject {\n const canonical: Record<string, JsonValue> = {\n version: claims.version,\n issuer: claims.issuer,\n productId: claims.productId,\n deviceId: claims.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n taskId: claims.taskId,\n agentRef: {\n agentId: claims.agentRef.agentId,\n profileRevision: claims.agentRef.profileRevision,\n },\n toolsetId: claims.toolsetId,\n };\n return canonical;\n}\n\n/** Canonical JSON text of the task claim set, without the domain prefix. */\nexport function taskAssertionCanonicalJson(claims: TaskAssertionClaims): string {\n return canonicalizeJson(taskAssertionCanonicalClaims(claims));\n}\n\n/**\n * The exact bytes a daemon signs and a verifier reconstructs:\n * `byok-task-assertion-v1\\n` followed by the canonical claim JSON, UTF-8\n * encoded.\n *\n * Frozen by `src/__tests__/golden/task-assertion-v1.canonical.json`.\n */\nexport function taskAssertionSigningInput(claims: TaskAssertionClaims): Uint8Array {\n return new TextEncoder().encode(\n TASK_ASSERTION_DOMAIN_PREFIX + taskAssertionCanonicalJson(claims),\n );\n}\n\n/**\n * Verifies a task assertion and returns its claims, or `undefined`.\n *\n * The twin of {@link verifyDeviceAssertion}, with the same\n * collapse-to-`undefined` discipline, the same injected row lookup, and the\n * same window and ceiling rules ({@link assertionWindowAdmits},\n * {@link resolveMaxLifetimeMs}) — and a schema this function will not widen: a\n * `byok-device-assertion-v1` envelope is rejected at the parse step.\n *\n * What the caller MUST still do, exactly as in the device lane: compare\n * `issuer`/`productId`/`audience` against its own deployment, burn the `jti`\n * under this envelope's `schema` segment, and check that `taskId`/`agentRef`/\n * `toolsetId` belong to the frozen offer (§8.2(2)) — the last of which is Host\n * authority that core cannot hold.\n */\nexport async function verifyTaskAssertion(\n input: unknown,\n deps: DeviceAssertionVerifyDeps,\n): Promise<TaskAssertionClaims | undefined> {\n const maxLifetimeMs = resolveMaxLifetimeMs(deps.maxLifetimeMs);\n if (maxLifetimeMs === undefined) return undefined;\n\n let envelope: TaskAssertionEnvelopeV1;\n try {\n envelope = parseTaskAssertionEnvelope(input);\n } catch {\n return undefined;\n }\n const claims = envelope.protected;\n\n const row = await deps.lookupDevice(claims.deviceId);\n if (!isUsableDeviceRow(row)) return undefined;\n\n if (!assertionWindowAdmits(claims, deps.now, maxLifetimeMs)) return undefined;\n\n const verified = await deps.verifier.verify({\n algorithm: envelope.algorithm,\n publicKey: row.publicKeyJwkX,\n signature: envelope.signature,\n signingInput: taskAssertionSigningInput(claims),\n });\n if (!verified) return undefined;\n\n return claims;\n}\n\n/**\n * Audit-safe result of a consumed TASK assertion; no credential or signature is\n * retained.\n *\n * Deliberately NOT an extension of {@link AuthenticatedDeviceAssertion}. It was\n * one, and that was the same mistake in the type system that §8.1 forbids on\n * the wire: an extension is assignable to the thing it extends, so every\n * consumer written for device authority would have accepted a task credential\n * silently, with no fallback ever written down. The two results share\n * {@link AuthenticatedAssertionBase} and differ in `lane`, so a consumer that\n * must accept exactly one of them compares one field, and a consumer that must\n * accept either says so with {@link AuthenticatedAssertion}.\n */\nexport interface AuthenticatedTaskAssertion extends AuthenticatedAssertionBase {\n readonly lane: 'task';\n readonly taskId: string;\n readonly agentRef: TaskAssertionAgentRef;\n readonly toolsetId: string;\n}\n\n/**\n * Either lane's result, discriminated by `lane`.\n *\n * For the consumer that genuinely serves both (an audit projection, a ledger\n * writer). A consumer that serves ONE lane must name that lane's type instead —\n * this union exists so \"both\" is stated on purpose, not reached by accident.\n */\nexport type AuthenticatedAssertion = AuthenticatedDeviceAssertion | AuthenticatedTaskAssertion;\n\n/**\n * Authenticate one task assertion and atomically consume its JTI under the\n * `byok-task-assertion-v1` replay segment.\n *\n * Identical in shape and failure discipline to\n * {@link authenticateDeviceAssertion}: every invalid state collapses to\n * `undefined`, and a replay-store operational failure REJECTS rather than\n * degrading to signature-only acceptance (§8.2(2): an unavailable replay store\n * fails, it does not downgrade authentication).\n *\n * Consumption is the last step, after every binding comparison, so a rejected\n * assertion never burns a key — the \"reject before side effects\" ordering AC11\n * requires. The frozen-offer check (`taskId`/`agentRef`/`toolsetId` belong to\n * this Execution) is deliberately NOT here: that authority lives in the Host,\n * and a core function that accepted it as an argument would be inviting a\n * caller to synthesize it.\n */\nexport async function authenticateTaskAssertion(\n input: unknown,\n deps: AuthenticateDeviceAssertionDeps,\n): Promise<AuthenticatedTaskAssertion | undefined> {\n if (\n !isNonEmptyExactString(deps.expected.issuer) ||\n !isNonEmptyExactString(deps.expected.productId) ||\n !isNonEmptyExactString(deps.expected.audience) ||\n utf8ByteLength(deps.expected.audience) > DEVICE_ASSERTION_AUDIENCE_MAX_BYTES\n ) {\n return undefined;\n }\n\n let authorityRow: DeviceAssertionAuthorityRow | undefined;\n const claims = await verifyTaskAssertion(input, {\n verifier: deps.verifier,\n lookupDevice: async (deviceId) => {\n const row = await deps.lookupDevice(deviceId);\n if (!isAuthorityRow(row, deviceId)) return undefined;\n authorityRow = row;\n return { publicKeyJwkX: row.publicKeyJwkX, revoked: row.revoked };\n },\n now: deps.now,\n ...(deps.maxLifetimeMs === undefined ? {} : { maxLifetimeMs: deps.maxLifetimeMs }),\n });\n if (claims === undefined || authorityRow === undefined) return undefined;\n\n if (\n claims.issuer !== deps.expected.issuer ||\n claims.productId !== deps.expected.productId ||\n claims.audience !== deps.expected.audience ||\n authorityRow.productId !== deps.expected.productId ||\n authorityRow.deviceId !== claims.deviceId\n ) {\n return undefined;\n }\n\n const consumed = await deps.replay.consume({\n schema: TASK_ASSERTION_SCHEMA_ID,\n tenantId: authorityRow.tenantId,\n issuer: claims.issuer,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n audience: claims.audience,\n jti: claims.jti,\n expiresAt: claims.expiresAt,\n });\n if (!consumed) return undefined;\n\n return {\n lane: 'task',\n device: {\n kind: 'device',\n tenantId: authorityRow.tenantId,\n productId: authorityRow.productId,\n deviceId: authorityRow.deviceId,\n },\n issuer: claims.issuer,\n audience: claims.audience,\n jti: claims.jti,\n issuedAt: claims.issuedAt,\n expiresAt: claims.expiresAt,\n taskId: claims.taskId,\n agentRef: claims.agentRef,\n toolsetId: claims.toolsetId,\n };\n}\n","/**\n * The WebCrypto surface core relies on, declared structurally so core's\n * published types need neither the DOM lib nor Node's types, and resolved\n * from `globalThis.crypto.subtle` so the browser, Node, and Bun share one\n * code path. No `node:crypto`.\n */\nimport { ByokCoreError } from './errors';\n\n/**\n * A WebCrypto `CryptoKey`, declared structurally so core's published types\n * need neither the DOM lib nor Node's types. Every runtime's native\n * `CryptoKey` satisfies it.\n */\nexport interface WebCryptoKey {\n readonly type: string;\n readonly extractable: boolean;\n readonly algorithm: object;\n readonly usages: readonly string[];\n}\n\n/** The subset of `SubtleCrypto` this package calls, typed loosely on purpose (see {@link WebCryptoKey}). */\nexport interface WebCryptoSubtle {\n importKey(format: 'raw' | 'jwk', keyData: object, algorithm: object, extractable: boolean, usages: string[]): Promise<WebCryptoKey>;\n exportKey(format: 'raw', key: WebCryptoKey): Promise<ArrayBuffer>;\n generateKey(algorithm: object, extractable: boolean, usages: string[]): Promise<{ publicKey: WebCryptoKey; privateKey: WebCryptoKey }>;\n deriveBits(algorithm: object, baseKey: WebCryptoKey, length: number): Promise<ArrayBuffer>;\n sign(algorithm: string, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n encrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n decrypt(algorithm: object, key: WebCryptoKey, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n digest(algorithm: string, data: Uint8Array<ArrayBuffer>): Promise<ArrayBuffer>;\n}\n\n/** The WebCrypto subtle interface, or a closed-set failure when the runtime lacks it. */\nexport function webCryptoSubtle(): WebCryptoSubtle {\n const subtle = (globalThis as { crypto?: { subtle?: WebCryptoSubtle } }).crypto?.subtle;\n if (subtle === undefined) {\n throw new ByokCoreError('webcrypto_unavailable', 'WebCrypto subtle is unavailable in this runtime');\n }\n return subtle;\n}\n","/**\n * RFC 9180 HPKE, base mode, exactly one cipher suite:\n * `DHKEM(P-256, HKDF-SHA256) / HKDF-SHA256 / AES-128-GCM`\n * (KEM `0x0010`, KDF `0x0001`, AEAD `0x0001`).\n *\n * Why this module exists instead of a dependency: the same bytes must be\n * produced in a browser (the Web seals a provider key), in Node, and in a\n * Bun-compiled device daemon (which opens it). Every primitive used here —\n * P-256 ECDH, HMAC-SHA-256, AES-GCM, SHA-256, random key generation — is a\n * WebCrypto primitive all three runtimes ship, so the suite needs no\n * third-party code and no `node:` import (core must stay Workers/browser\n * safe). There is no algorithm negotiation: one suite, one mode, and anything\n * else is rejected by the envelope schema before this module is reached.\n *\n * Only one-shot seal/open is reachable from the package root. The key\n * schedule and sequence-numbered nonces are exported from this module for the\n * RFC 9180 Appendix A.3 conformance tests only; `index.ts` never re-exports a\n * reusable encryption context.\n *\n * Self-implemented HPKE: RFC vectors and an independent implementation\n * interoperate in the test suite, but passing vectors is not an audit. A\n * dedicated security review is required before a release is published.\n */\nimport { ByokCoreError } from './errors';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nconst KEM_ID = 0x0010;\nconst KDF_ID = 0x0001;\nconst AEAD_ID = 0x0001;\n\n/** Encoded P-256 public key and encapsulation length (uncompressed SEC1). */\nexport const HPKE_P256_PUBLIC_KEY_BYTES = 65;\nconst N_SECRET = 32;\nconst N_K = 16;\nconst N_N = 12;\nconst N_H = 32;\n/** AES-GCM authentication tag length. */\nexport const HPKE_AEAD_TAG_BYTES = 16;\n\nconst MODE_BASE = 0x00;\nconst HPKE_V1 = utf8('HPKE-v1');\nconst KEM_SUITE_ID = concat(utf8('KEM'), i2osp(KEM_ID, 2));\nconst HPKE_SUITE_ID = concat(utf8('HPKE'), i2osp(KEM_ID, 2), i2osp(KDF_ID, 2), i2osp(AEAD_ID, 2));\nconst EMPTY = new Uint8Array(0);\n/** HMAC pads its key with zeros to the block size, so an empty salt equals HashLen zeros. */\nconst ZERO_SALT = new Uint8Array(N_H);\n\ntype Bytes = Uint8Array<ArrayBuffer>;\n\nfunction utf8(value: string): Bytes {\n return new TextEncoder().encode(value) as Bytes;\n}\n\nfunction concat(...parts: readonly Uint8Array[]): Bytes {\n const length = parts.reduce((total, part) => total + part.byteLength, 0);\n const out = new Uint8Array(length);\n let offset = 0;\n for (const part of parts) {\n out.set(part, offset);\n offset += part.byteLength;\n }\n return out;\n}\n\nfunction i2osp(value: number, length: number): Bytes {\n if (!Number.isSafeInteger(value) || value < 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer encoding requires a non-negative safe integer');\n }\n const out = new Uint8Array(length);\n let remaining = value;\n for (let index = length - 1; index >= 0; index -= 1) {\n out[index] = remaining % 256;\n remaining = Math.floor(remaining / 256);\n }\n if (remaining !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE integer does not fit the requested width');\n }\n return out;\n}\n\nfunction copy(bytes: Uint8Array): Bytes {\n return new Uint8Array(bytes) as Bytes;\n}\n\nasync function hmacSha256(key: Uint8Array, data: Uint8Array): Promise<Bytes> {\n const subtle = webCryptoSubtle();\n const hmacKey = await subtle.importKey('raw', copy(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);\n return new Uint8Array(await subtle.sign('HMAC', hmacKey, copy(data))) as Bytes;\n}\n\nasync function hkdfExpand(prk: Uint8Array, info: Uint8Array, length: number): Promise<Bytes> {\n if (length > 255 * N_H) {\n throw new ByokCoreError('sealed_secret_invalid', 'HKDF output length exceeds its limit');\n }\n const out = new Uint8Array(length);\n let previous: Uint8Array = EMPTY;\n let offset = 0;\n for (let counter = 1; offset < length; counter += 1) {\n previous = await hmacSha256(prk, concat(previous, info, Uint8Array.of(counter)));\n const take = Math.min(previous.byteLength, length - offset);\n out.set(previous.subarray(0, take), offset);\n offset += take;\n }\n return out as Bytes;\n}\n\nasync function labeledExtract(suiteId: Uint8Array, salt: Uint8Array, label: string, ikm: Uint8Array): Promise<Bytes> {\n return hmacSha256(salt.byteLength === 0 ? ZERO_SALT : salt, concat(HPKE_V1, suiteId, utf8(label), ikm));\n}\n\nasync function labeledExpand(\n suiteId: Uint8Array,\n prk: Uint8Array,\n label: string,\n info: Uint8Array,\n length: number,\n): Promise<Bytes> {\n return hkdfExpand(prk, concat(i2osp(length, 2), HPKE_V1, suiteId, utf8(label), info), length);\n}\n\n/**\n * Import an uncompressed SEC1 P-256 public key for ECDH.\n *\n * The length and `0x04` prefix are checked here; the on-curve check is the\n * WebCrypto import itself, which rejects a point that is not on P-256.\n */\nexport async function importP256PublicKey(raw: Uint8Array): Promise<WebCryptoKey> {\n if (raw.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || raw[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key must be a 65-byte uncompressed point');\n }\n try {\n return await webCryptoSubtle().importKey('raw', copy(raw), { name: 'ECDH', namedCurve: 'P-256' }, true, []);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 public key is not a valid curve point', { cause });\n }\n}\n\nasync function ecdhP256(privateKey: WebCryptoKey, publicKey: WebCryptoKey): Promise<Bytes> {\n const bits = await webCryptoSubtle().deriveBits({ name: 'ECDH', public: publicKey }, privateKey, N_SECRET * 8);\n return new Uint8Array(bits) as Bytes;\n}\n\nasync function extractAndExpand(dh: Uint8Array, kemContext: Uint8Array): Promise<Bytes> {\n const eaePrk = await labeledExtract(KEM_SUITE_ID, EMPTY, 'eae_prk', dh);\n return labeledExpand(KEM_SUITE_ID, eaePrk, 'shared_secret', kemContext, N_SECRET);\n}\n\n/** Key schedule output for base mode. Exported for the RFC 9180 conformance tests only. */\nexport interface HpkeBaseKeySchedule {\n readonly sharedSecret: Uint8Array;\n readonly key: Uint8Array;\n readonly baseNonce: Uint8Array;\n readonly exporterSecret: Uint8Array;\n}\n\nasync function keyScheduleBase(sharedSecret: Uint8Array, info: Uint8Array): Promise<HpkeBaseKeySchedule> {\n const pskIdHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'psk_id_hash', EMPTY);\n const infoHash = await labeledExtract(HPKE_SUITE_ID, EMPTY, 'info_hash', info);\n const context = concat(Uint8Array.of(MODE_BASE), pskIdHash, infoHash);\n const secret = await labeledExtract(HPKE_SUITE_ID, sharedSecret, 'secret', EMPTY);\n return {\n sharedSecret,\n key: await labeledExpand(HPKE_SUITE_ID, secret, 'key', context, N_K),\n baseNonce: await labeledExpand(HPKE_SUITE_ID, secret, 'base_nonce', context, N_N),\n exporterSecret: await labeledExpand(HPKE_SUITE_ID, secret, 'exp', context, N_H),\n };\n}\n\n/** A caller-fixed ephemeral key pair. Conformance tests only; production always generates one. */\nexport interface HpkeEphemeralKeyPair {\n readonly privateKey: WebCryptoKey;\n readonly publicKey: Uint8Array;\n}\n\n/** `SetupBaseS`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseSender(\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n ephemeral?: HpkeEphemeralKeyPair,\n): Promise<{ enc: Uint8Array; schedule: HpkeBaseKeySchedule }> {\n const pkR = await importP256PublicKey(recipientPublicKey);\n let pair = ephemeral;\n if (pair === undefined) {\n const subtle = webCryptoSubtle();\n const generated = await subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveBits']);\n pair = {\n privateKey: generated.privateKey,\n publicKey: new Uint8Array(await subtle.exportKey('raw', generated.publicKey)),\n };\n }\n const enc = copy(pair.publicKey);\n const dh = await ecdhP256(pair.privateKey, pkR);\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return { enc, schedule: await keyScheduleBase(sharedSecret, info) };\n}\n\n/** `SetupBaseR`. Exported for the RFC 9180 conformance tests only. */\nexport async function setupBaseRecipient(\n enc: Uint8Array,\n recipientPrivateKey: WebCryptoKey,\n recipientPublicKey: Uint8Array,\n info: Uint8Array,\n): Promise<HpkeBaseKeySchedule> {\n if (recipientPublicKey.byteLength !== HPKE_P256_PUBLIC_KEY_BYTES || recipientPublicKey[0] !== 0x04) {\n throw new ByokCoreError('sealed_secret_invalid', 'P-256 recipient public key must be a 65-byte uncompressed point');\n }\n const pkE = await importP256PublicKey(enc);\n let dh: Bytes;\n try {\n dh = await ecdhP256(recipientPrivateKey, pkE);\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE decapsulation failed', { cause });\n }\n const sharedSecret = await extractAndExpand(dh, concat(enc, recipientPublicKey));\n return keyScheduleBase(sharedSecret, info);\n}\n\n/** `ComputeNonce(seq)`. Exported for the RFC 9180 conformance tests only. */\nexport function hpkeNonce(baseNonce: Uint8Array, sequence: number): Bytes {\n const seq = i2osp(sequence, N_N);\n const out = new Uint8Array(N_N);\n for (let index = 0; index < N_N; index += 1) out[index] = baseNonce[index]! ^ seq[index]!;\n return out as Bytes;\n}\n\nasync function aesGcmKey(key: Uint8Array, usage: 'encrypt' | 'decrypt'): Promise<WebCryptoKey> {\n return webCryptoSubtle().importKey('raw', copy(key), { name: 'AES-GCM' }, false, [usage]);\n}\n\n/** AEAD seal at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadSeal(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n plaintext: Uint8Array,\n): Promise<Bytes> {\n const ciphertext = await webCryptoSubtle().encrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'encrypt'),\n copy(plaintext),\n );\n return new Uint8Array(ciphertext) as Bytes;\n}\n\n/** AEAD open at an explicit sequence number. Exported for the RFC 9180 conformance tests only. */\nexport async function hpkeAeadOpen(\n schedule: HpkeBaseKeySchedule,\n sequence: number,\n aad: Uint8Array,\n ciphertext: Uint8Array,\n): Promise<Bytes> {\n if (ciphertext.byteLength < HPKE_AEAD_TAG_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'HPKE ciphertext is shorter than its authentication tag');\n }\n try {\n const plaintext = await webCryptoSubtle().decrypt(\n { name: 'AES-GCM', iv: hpkeNonce(schedule.baseNonce, sequence), additionalData: copy(aad), tagLength: 128 },\n await aesGcmKey(schedule.key, 'decrypt'),\n copy(ciphertext),\n );\n return new Uint8Array(plaintext) as Bytes;\n } catch (cause) {\n throw new ByokCoreError('sealed_secret_open_failed', 'HPKE ciphertext failed authentication', { cause });\n }\n}\n\n/** One-shot `SealBase`: a fresh ephemeral key, sequence 0, never reused. */\nexport async function hpkeSealBase(input: {\n readonly recipientPublicKey: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly plaintext: Uint8Array;\n}): Promise<{ enc: Uint8Array; ciphertext: Uint8Array }> {\n const { enc, schedule } = await setupBaseSender(input.recipientPublicKey, input.info);\n return { enc, ciphertext: await hpkeAeadSeal(schedule, 0, input.aad, input.plaintext) };\n}\n\n/** One-shot `OpenBase`, sequence 0. */\nexport async function hpkeOpenBase(input: {\n readonly recipientPrivateKey: WebCryptoKey;\n readonly recipientPublicKey: Uint8Array;\n readonly enc: Uint8Array;\n readonly info: Uint8Array;\n readonly aad: Uint8Array;\n readonly ciphertext: Uint8Array;\n}): Promise<Uint8Array> {\n const schedule = await setupBaseRecipient(input.enc, input.recipientPrivateKey, input.recipientPublicKey, input.info);\n return hpkeAeadOpen(schedule, 0, input.aad, input.ciphertext);\n}\n","/**\n * A zod parse that never throws.\n *\n * `safeParse` returns a failure for invalid data, but it does not catch an\n * error that a getter or a proxy trap throws while zod reads the value, and a\n * revoked proxy throws on any read. A receiver that promises a typed result\n * for hostile input, or a typed error for bad caller input, parses through\n * this. Wire input from `JSON.parse` cannot hold getters or proxies; this\n * closes the same gap for in-process callers.\n */\nimport type { z } from 'zod';\n\nexport type TotalParseResult<T> =\n | { readonly success: true; readonly data: T }\n | { readonly success: false; readonly error?: z.ZodError };\n\n/** `schema.safeParse(value)`, with a throw while reading `value` as a failure without issues. */\nexport function safeParseTotal<S extends z.ZodType>(schema: S, value: unknown): TotalParseResult<z.output<S>> {\n try {\n return schema.safeParse(value);\n } catch {\n return { success: false };\n }\n}\n","/**\n * Sealed provider provisioning v1 (plan web-sealed-provisioning §3).\n *\n * A browser seals a provider API key to one device's long-lived P-256\n * sealing key; the cloud relays only ciphertext; the device opens it in\n * memory. This module is the single byte authority both ends share:\n *\n * - the request schema (header + non-secret config + optional sealed secret),\n * - canonical AAD bytes, config digest, and request digest,\n * - the sealing-key claim canonical bytes a device signs at registration,\n * - plaintext padding (2-byte length prefix, zero-padded to 256-byte blocks),\n * - one-shot seal/open on top of `hpke.ts`.\n *\n * Every function is WebCrypto-only and `node:`-free so the Web bundle and the\n * device use literally the same code. Nothing here reads a clock, a network,\n * or a store; time windows, replay ledgers, placement and enrollment are the\n * device's (`@byok-sdk/keys`) decisions.\n *\n * Error messages never include plaintext, ciphertext, or key material.\n */\nimport { z } from 'zod';\n\nimport { canonicalizeJson, canonicalizeJsonBytes, type JsonObject, type JsonValue } from './attestation';\nimport { CONTENT_HASH_PATTERN } from './blob';\nimport { ByokCoreError } from './errors';\nimport {\n HPKE_AEAD_TAG_BYTES,\n HPKE_P256_PUBLIC_KEY_BYTES,\n hpkeOpenBase,\n hpkeSealBase,\n importP256PublicKey,\n} from './hpke';\nimport { isCanonicalTimestamp } from './time';\nimport { safeParseTotal } from './total-parse';\nimport { webCryptoSubtle, type WebCryptoKey } from './webcrypto';\n\nexport type { WebCryptoKey } from './webcrypto';\n\n/** The only HPKE suite v1 admits. There is no negotiation and no second value. */\nexport const PROVIDER_SECRET_HPKE_SUITE = 'hpke-base.dhkem-p256-hkdf-sha256.hkdf-sha256.aes-128-gcm';\n\n/** HPKE `info`, versioned; a v2 is a new constant, never a parser branch. */\nexport const PROVIDER_SECRET_HPKE_INFO = 'byok-sdk.provider-secret.v1';\n\nexport const PROVIDER_PROVISIONING_REQUEST_VERSION = 1;\n\nexport const PROVIDER_PROVISIONING_OPERATIONS = ['configure', 'update_model', 'replace_secret', 'delete'] as const;\nexport type ProviderProvisioningOperation = (typeof PROVIDER_PROVISIONING_OPERATIONS)[number];\n\n/** Operations whose request must carry exactly one sealed secret. */\nexport const PROVIDER_PROVISIONING_SECRET_OPERATIONS = ['configure', 'replace_secret'] as const;\n\n/** Upper bound for `expiresAt - issuedAt` (plan D11). */\nexport const PROVIDER_PROVISIONING_MAX_TTL_MS = 15 * 60 * 1000;\n\n/** Plaintext is padded to a multiple of this many bytes so ciphertext length hides key length. */\nexport const PROVIDER_SECRET_PAD_BLOCK_BYTES = 256;\n\n/** Largest padded plaintext v1 accepts; the secret itself is at most this minus the 2-byte prefix. */\nexport const PROVIDER_SECRET_MAX_PADDED_BYTES = 4096;\n\nexport const PROVIDER_SECRET_MAX_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES - 2;\n\n/** Length of a sealing key id: base64url(sha256(raw public key)) truncated to 22 characters. */\nexport const SEALING_KEY_ID_LENGTH = 22;\n\n// ---------------------------------------------------------------------------\n// base64url (strict, unpadded, canonical)\n// ---------------------------------------------------------------------------\n\nconst B64URL_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';\nconst B64URL_PATTERN = /^[A-Za-z0-9_-]*$/;\n\nexport function encodeBase64Url(bytes: Uint8Array): string {\n let out = '';\n let index = 0;\n for (; index + 3 <= bytes.length; index += 3) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8) | bytes[index + 2]!;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]! + B64URL_ALPHABET[value & 63]!;\n }\n const rest = bytes.length - index;\n if (rest === 1) {\n const value = bytes[index]! << 16;\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!;\n } else if (rest === 2) {\n const value = (bytes[index]! << 16) | (bytes[index + 1]! << 8);\n out += B64URL_ALPHABET[(value >> 18) & 63]! + B64URL_ALPHABET[(value >> 12) & 63]!\n + B64URL_ALPHABET[(value >> 6) & 63]!;\n }\n return out;\n}\n\n/** Decode canonical unpadded base64url, or throw — never a repaired approximation. */\nexport function decodeBase64Url(value: string, field: string): Uint8Array<ArrayBuffer> {\n if (!B64URL_PATTERN.test(value) || value.length % 4 === 1) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n const out = new Uint8Array(Math.floor((value.length * 3) / 4));\n let buffer = 0;\n let bits = 0;\n let offset = 0;\n for (const char of value) {\n buffer = (buffer << 6) | B64URL_ALPHABET.indexOf(char);\n bits += 6;\n if (bits >= 8) {\n bits -= 8;\n out[offset] = (buffer >> bits) & 0xff;\n offset += 1;\n }\n }\n if (encodeBase64Url(out) !== value) {\n throw new ByokCoreError('sealed_secret_invalid', `${field} is not canonical base64url`);\n }\n return out;\n}\n\nfunction base64UrlField(bytes: { exact?: number; max?: number }) {\n return z.string().superRefine((value, ctx) => {\n try {\n const decoded = decodeBase64Url(value, 'field');\n if (bytes.exact !== undefined && decoded.byteLength !== bytes.exact) {\n ctx.addIssue({ code: 'custom', message: `must decode to exactly ${bytes.exact} bytes` });\n }\n if (bytes.max !== undefined && decoded.byteLength > bytes.max) {\n ctx.addIssue({ code: 'custom', message: `must decode to at most ${bytes.max} bytes` });\n }\n } catch {\n ctx.addIssue({ code: 'custom', message: 'must be canonical unpadded base64url' });\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Hashing\n// ---------------------------------------------------------------------------\n\nasync function sha256(bytes: Uint8Array): Promise<Uint8Array> {\n return new Uint8Array(await webCryptoSubtle().digest('SHA-256', new Uint8Array(bytes)));\n}\n\nfunction hex(bytes: Uint8Array): string {\n let out = '';\n for (const byte of bytes) out += byte.toString(16).padStart(2, '0');\n return out;\n}\n\nasync function contentDigest(value: JsonValue): Promise<string> {\n return `sha256:${hex(await sha256(canonicalizeJsonBytes(value)))}`;\n}\n\n// ---------------------------------------------------------------------------\n// Sealing key (public JWK + claim)\n// ---------------------------------------------------------------------------\n\n/**\n * The only public-key shape v1 accepts. Strict: a `d` (private) member, an\n * `alg`, `use`, `key_ops` or any other extra member is rejected rather than\n * ignored, so a private JWK can never be published by mistake.\n */\nexport const SealingPublicJwkSchema = z.strictObject({\n kty: z.literal('EC'),\n crv: z.literal('P-256'),\n x: base64UrlField({ exact: 32 }),\n y: base64UrlField({ exact: 32 }),\n});\nexport type SealingPublicJwk = z.infer<typeof SealingPublicJwkSchema>;\n\nexport const SealingKeyIdSchema = z.string().regex(new RegExp(`^[A-Za-z0-9_-]{${SEALING_KEY_ID_LENGTH}}$`));\n\nfunction parseSealingPublicJwk(input: unknown): SealingPublicJwk {\n const result = safeParseTotal(SealingPublicJwkSchema, input);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing public key must be a strict P-256 EC public JWK');\n }\n return result.data;\n}\n\n/** Uncompressed SEC1 bytes (`0x04 || x || y`) of a sealing public JWK. */\nexport function sealingPublicKeyBytes(publicJwk: SealingPublicJwk): Uint8Array<ArrayBuffer> {\n const jwk = parseSealingPublicJwk(publicJwk);\n const raw = new Uint8Array(HPKE_P256_PUBLIC_KEY_BYTES);\n raw[0] = 0x04;\n raw.set(decodeBase64Url(jwk.x, 'x'), 1);\n raw.set(decodeBase64Url(jwk.y, 'y'), 33);\n return raw;\n}\n\n/** `base64url(sha256(0x04 || x || y))[0..22]` — the device's and the browser's shared key id rule. */\nexport async function deriveSealingKeyId(publicJwk: SealingPublicJwk): Promise<string> {\n const raw = sealingPublicKeyBytes(publicJwk);\n await importP256PublicKey(raw);\n return encodeBase64Url(await sha256(raw)).slice(0, SEALING_KEY_ID_LENGTH);\n}\n\n/**\n * The claim a device signs (through its device-proof signer, host glue) when\n * it registers its sealing key. The proof body is these canonical bytes.\n */\nexport const SealingKeyClaimV1Schema = z.strictObject({\n version: z.literal(1),\n keyId: SealingKeyIdSchema,\n epoch: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n publicJwk: SealingPublicJwkSchema,\n});\nexport type SealingKeyClaimV1 = z.infer<typeof SealingKeyClaimV1Schema>;\n\n/** Canonical UTF-8 bytes of a sealing-key claim. */\nexport function sealingKeyClaimCanonicalBytes(claim: SealingKeyClaimV1): Uint8Array {\n const result = safeParseTotal(SealingKeyClaimV1Schema, claim);\n if (!result.success) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key claim is invalid');\n }\n const parsed = result.data;\n return canonicalizeJsonBytes({\n version: parsed.version,\n keyId: parsed.keyId,\n epoch: parsed.epoch,\n publicJwk: { kty: parsed.publicJwk.kty, crv: parsed.publicJwk.crv, x: parsed.publicJwk.x, y: parsed.publicJwk.y },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Request schema\n// ---------------------------------------------------------------------------\n\n/** Opaque identifier: non-empty, bounded, no surrounding whitespace, no control characters. */\nconst OpaqueIdSchema = z.string().min(1).max(200).superRefine((value, ctx) => {\n if (value.trim() !== value || /[\\u0000-\\u001f\\u007f]/u.test(value)) {\n ctx.addIssue({ code: 'custom', message: 'must not carry surrounding whitespace or control characters' });\n }\n});\n\nconst CanonicalTimestampSchema = z.string().refine(isCanonicalTimestamp, 'must be a canonical ISO-8601 UTC instant');\n\nconst ProfileRefSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ProviderKindSchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:[-_][a-z0-9]+)*$/u);\nconst ModelIdSchema = z.string().min(1).max(160).refine((value) => value.trim() === value && !/[\\u0000-\\u001f\\u007f]/u.test(value), 'model id is invalid');\nconst CapabilitySchema = z.string().min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/u);\n\n/**\n * `pi_model` travels as an opaque canonicalizable JSON object; the device\n * validates it against `@byok-sdk/keys`' strict `PiModelConfigSchema`. Core\n * only guarantees it has one canonical byte form.\n */\nconst PiModelJsonSchema = z.custom<JsonObject>((value) => {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return false;\n try {\n canonicalizeJson(value as JsonObject);\n return true;\n } catch {\n return false;\n }\n}, 'piModel must be a canonical JSON object');\n\nconst ModelConfigFields = {\n agentId: OpaqueIdSchema,\n providerKind: ProviderKindSchema,\n modelId: ModelIdSchema,\n piModel: PiModelJsonSchema,\n capabilities: z.array(CapabilitySchema).max(8).refine((values) => new Set(values).size === values.length, 'capabilities must be unique'),\n};\n\n/**\n * The non-secret configuration, one exact shape per operation. An operation\n * carries only the fields it acts on — `delete` has no model, `replace_secret`\n * declares only the provider kind its key is scoped to — so nothing is\n * accepted and silently ignored.\n */\nexport const ProviderProvisioningConfigV1Schema = z.discriminatedUnion('operation', [\n z.strictObject({ operation: z.literal('configure'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('update_model'), ...ModelConfigFields }),\n z.strictObject({ operation: z.literal('replace_secret'), agentId: OpaqueIdSchema, providerKind: ProviderKindSchema }),\n z.strictObject({ operation: z.literal('delete'), agentId: OpaqueIdSchema }),\n]);\nexport type ProviderProvisioningConfigV1 = z.infer<typeof ProviderProvisioningConfigV1Schema>;\n\n/** The credential-free provider triple the Host believes is current (A3), or `null` for none. */\nexport const ProviderProvisioningExpectedProfileSchema = z.union([\n z.null(),\n z.strictObject({\n profileRef: ProfileRefSchema,\n profileRevision: z.string().regex(/^(?:0|[1-9][0-9]{0,19})$/u),\n profileHash: z.string().regex(CONTENT_HASH_PATTERN),\n }),\n]);\nexport type ProviderProvisioningExpectedProfile = z.infer<typeof ProviderProvisioningExpectedProfileSchema>;\n\n/**\n * Opaque, Host-issued identity version: the enrollment revision (changes on\n * re-pair / re-enrollment of the same device id) or the agent placement\n * revision. The device compares it byte-for-byte with its own snapshot.\n */\nexport const ProviderProvisioningIdentityRevisionSchema = z.string().min(1).max(128).regex(/^[A-Za-z0-9._:-]+$/u);\n\nexport const ProviderProvisioningHeaderV1Schema = z.strictObject({\n tenantId: OpaqueIdSchema,\n deviceId: OpaqueIdSchema,\n agentId: OpaqueIdSchema,\n requestId: OpaqueIdSchema,\n operation: z.enum(PROVIDER_PROVISIONING_OPERATIONS),\n /** Non-secret, strictly increasing per bot (A3); a device rejects anything not above its high-watermark. */\n operationGeneration: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),\n expectedProfile: ProviderProvisioningExpectedProfileSchema,\n /** The device enrollment revision the Host authorized against (F2). */\n expectedEnrollmentRevision: ProviderProvisioningIdentityRevisionSchema,\n /** The agent placement revision the Host authorized against (F2). */\n expectedPlacementRevision: ProviderProvisioningIdentityRevisionSchema,\n configDigest: z.string().regex(CONTENT_HASH_PATTERN),\n issuedAt: CanonicalTimestampSchema,\n expiresAt: CanonicalTimestampSchema,\n});\nexport type ProviderProvisioningHeaderV1 = z.infer<typeof ProviderProvisioningHeaderV1Schema>;\n\n/** Ciphertext bound: largest padded plaintext plus the AEAD tag. */\nconst MAX_CIPHERTEXT_BYTES = PROVIDER_SECRET_MAX_PADDED_BYTES + HPKE_AEAD_TAG_BYTES;\n\nexport const SealedProviderSecretV1Schema = z.strictObject({\n suite: z.literal(PROVIDER_SECRET_HPKE_SUITE),\n keyId: SealingKeyIdSchema,\n enc: base64UrlField({ exact: HPKE_P256_PUBLIC_KEY_BYTES }),\n ciphertext: base64UrlField({ max: MAX_CIPHERTEXT_BYTES }),\n});\nexport type SealedProviderSecretV1 = z.infer<typeof SealedProviderSecretV1Schema>;\n\nfunction isSecretOperation(operation: ProviderProvisioningOperation): boolean {\n return (PROVIDER_PROVISIONING_SECRET_OPERATIONS as readonly string[]).includes(operation);\n}\n\nexport const ProviderProvisioningRequestV1Schema = z\n .strictObject({\n version: z.literal(PROVIDER_PROVISIONING_REQUEST_VERSION),\n header: ProviderProvisioningHeaderV1Schema,\n config: ProviderProvisioningConfigV1Schema,\n sealed: SealedProviderSecretV1Schema.optional(),\n })\n .superRefine((request, ctx) => {\n if (request.header.operation !== request.config.operation) {\n ctx.addIssue({ code: 'custom', path: ['config', 'operation'], message: 'config operation must equal header operation' });\n }\n if (request.header.agentId !== request.config.agentId) {\n ctx.addIssue({ code: 'custom', path: ['config', 'agentId'], message: 'config agentId must equal header agentId' });\n }\n if (isSecretOperation(request.header.operation) !== (request.sealed !== undefined)) {\n ctx.addIssue({ code: 'custom', path: ['sealed'], message: 'a sealed secret is required exactly for configure and replace_secret' });\n }\n });\nexport type ProviderProvisioningRequestV1 = z.infer<typeof ProviderProvisioningRequestV1Schema>;\n\n/** Parse a request fail-closed. Issue text names paths and rules only, never values. */\nexport function parseProviderProvisioningRequest(input: unknown): ProviderProvisioningRequestV1 {\n const result = safeParseTotal(ProviderProvisioningRequestV1Schema, input);\n if (!result.success) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n `Invalid provider provisioning request: ${(result.error?.issues ?? [{ path: [], message: 'is not readable' }])\n .map((issue) => `${issue.path.join('.') || '<root>'}: ${issue.message}`)\n .join('; ')}`,\n );\n }\n return result.data;\n}\n\n// ---------------------------------------------------------------------------\n// Canonical bytes and digests\n// ---------------------------------------------------------------------------\n\nfunction configJson(config: ProviderProvisioningConfigV1): JsonObject {\n return config as unknown as JsonObject;\n}\n\n/** `sha256:<hex>` over the canonical JSON of the non-secret config. */\nexport async function providerProvisioningConfigDigest(config: ProviderProvisioningConfigV1): Promise<string> {\n const result = safeParseTotal(ProviderProvisioningConfigV1Schema, config);\n if (!result.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n return contentDigest(configJson(result.data));\n}\n\n/**\n * Canonical AAD bytes. Every header field plus the sealing key id is bound,\n * so tampering with any of tenant, device, key, request, agent, operation,\n * generation, expected triple, expected enrollment and placement revisions,\n * config digest, or time window fails the AEAD.\n */\nexport function providerSecretAadBytes(header: ProviderProvisioningHeaderV1, keyId: string): Uint8Array {\n const parsed = safeParseTotal(ProviderProvisioningHeaderV1Schema, header);\n if (!parsed.success || !safeParseTotal(SealingKeyIdSchema, keyId).success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning AAD input is invalid');\n }\n const value = parsed.data;\n return canonicalizeJsonBytes({\n v: PROVIDER_PROVISIONING_REQUEST_VERSION,\n tenantId: value.tenantId,\n deviceId: value.deviceId,\n keyId,\n requestId: value.requestId,\n agentId: value.agentId,\n operation: value.operation,\n operationGeneration: value.operationGeneration,\n expectedProfile: value.expectedProfile === null\n ? null\n : {\n profileRef: value.expectedProfile.profileRef,\n profileRevision: value.expectedProfile.profileRevision,\n profileHash: value.expectedProfile.profileHash,\n },\n expectedEnrollmentRevision: value.expectedEnrollmentRevision,\n expectedPlacementRevision: value.expectedPlacementRevision,\n configDigest: value.configDigest,\n issuedAt: value.issuedAt,\n expiresAt: value.expiresAt,\n });\n}\n\n/**\n * `sha256:<hex>` over the canonical JSON of the complete request. A device\n * compares it for an already-seen `requestId`: equal returns the stored\n * result, different is a conflict.\n */\nexport async function providerProvisioningRequestDigest(request: ProviderProvisioningRequestV1): Promise<string> {\n const parsed = parseProviderProvisioningRequest(request);\n return contentDigest(parsed as unknown as JsonObject);\n}\n\n/** Fail closed unless `header.configDigest` is the digest of `config`. */\nexport async function assertProviderProvisioningConfigDigest(request: ProviderProvisioningRequestV1): Promise<void> {\n const parsed = parseProviderProvisioningRequest(request);\n if ((await providerProvisioningConfigDigest(parsed.config)) !== parsed.header.configDigest) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config digest does not match its header');\n }\n}\n\n// ---------------------------------------------------------------------------\n// Padding\n// ---------------------------------------------------------------------------\n\n/** `u16be(len) || utf8(secret) || zeros`, total a multiple of 256 bytes. */\nexport function padProviderSecret(secret: string): Uint8Array<ArrayBuffer> {\n const bytes = new TextEncoder().encode(secret);\n if (bytes.byteLength === 0 || bytes.byteLength > PROVIDER_SECRET_MAX_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', `Provider secret must be 1 to ${PROVIDER_SECRET_MAX_BYTES} UTF-8 bytes`);\n }\n const total = Math.ceil((bytes.byteLength + 2) / PROVIDER_SECRET_PAD_BLOCK_BYTES) * PROVIDER_SECRET_PAD_BLOCK_BYTES;\n const out = new Uint8Array(total);\n out[0] = bytes.byteLength >> 8;\n out[1] = bytes.byteLength & 0xff;\n out.set(bytes, 2);\n return out;\n}\n\n/** Strict inverse of {@link padProviderSecret}: block size, bounds, zero padding, and fatal UTF-8 are all checked. */\nexport function unpadProviderSecret(padded: Uint8Array): string {\n if (\n padded.byteLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || padded.byteLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || padded.byteLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length');\n }\n const length = (padded[0]! << 8) | padded[1]!;\n if (length === 0 || length + 2 > padded.byteLength || padded.byteLength - (length + 2) >= PROVIDER_SECRET_PAD_BLOCK_BYTES) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has an invalid length prefix');\n }\n for (let index = length + 2; index < padded.byteLength; index += 1) {\n if (padded[index] !== 0) {\n throw new ByokCoreError('sealed_secret_invalid', 'Padded provider secret has non-zero padding');\n }\n }\n try {\n return new TextDecoder('utf-8', { fatal: true, ignoreBOM: true }).decode(padded.subarray(2, length + 2));\n } catch {\n throw new ByokCoreError('sealed_secret_invalid', 'Provider secret is not valid UTF-8');\n }\n}\n\n// ---------------------------------------------------------------------------\n// One-shot seal / open\n// ---------------------------------------------------------------------------\n\nconst INFO_BYTES = (): Uint8Array => new TextEncoder().encode(PROVIDER_SECRET_HPKE_INFO);\n\nexport interface SealProviderProvisioningRequestInput {\n /** The header without its digest; the digest is computed here from `config`. */\n readonly header: Omit<ProviderProvisioningHeaderV1, 'configDigest'>;\n readonly config: ProviderProvisioningConfigV1;\n /** Required exactly for secret-bearing operations. */\n readonly recipient?: { readonly keyId: string; readonly publicJwk: SealingPublicJwk };\n /** Required exactly for secret-bearing operations. */\n readonly secret?: string;\n}\n\n/**\n * Build one immutable provisioning request. Secret-bearing operations are\n * sealed once, to a freshly generated ephemeral key; the key id is re-derived\n * from the public JWK so a claim whose id does not match its key is refused\n * before anything is encrypted.\n */\nexport async function sealProviderProvisioningRequest(\n input: SealProviderProvisioningRequestInput,\n): Promise<ProviderProvisioningRequestV1> {\n const configResult = safeParseTotal(ProviderProvisioningConfigV1Schema, input.config);\n if (!configResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning config is invalid');\n }\n const config = configResult.data;\n const headerResult = safeParseTotal(ProviderProvisioningHeaderV1Schema, {\n ...input.header,\n configDigest: await providerProvisioningConfigDigest(config),\n });\n if (!headerResult.success) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning header is invalid');\n }\n const header = headerResult.data;\n const needsSecret = isSecretOperation(header.operation);\n if (needsSecret !== (input.secret !== undefined) || needsSecret !== (input.recipient !== undefined)) {\n throw new ByokCoreError(\n 'provider_provisioning_request_invalid',\n 'A secret and recipient are required exactly for configure and replace_secret',\n );\n }\n let sealed: SealedProviderSecretV1 | undefined;\n if (needsSecret) {\n const recipient = input.recipient!;\n const publicJwk = parseSealingPublicJwk(recipient.publicJwk);\n if ((await deriveSealingKeyId(publicJwk)) !== recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealing key id does not match its public key');\n }\n const { enc, ciphertext } = await hpkeSealBase({\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(header, recipient.keyId),\n plaintext: padProviderSecret(input.secret!),\n });\n sealed = {\n suite: PROVIDER_SECRET_HPKE_SUITE,\n keyId: recipient.keyId,\n enc: encodeBase64Url(enc),\n ciphertext: encodeBase64Url(ciphertext),\n };\n }\n return parseProviderProvisioningRequest({\n version: PROVIDER_PROVISIONING_REQUEST_VERSION,\n header,\n config,\n ...(sealed === undefined ? {} : { sealed }),\n });\n}\n\nexport interface ProviderSecretRecipient {\n readonly keyId: string;\n readonly publicJwk: SealingPublicJwk;\n /** Non-extractable ECDH private key; never leaves the device. */\n readonly privateKey: WebCryptoKey;\n}\n\n/**\n * Open the sealed secret of a request, in memory. Checks, in order: request\n * schema, suite (schema literal), recipient key id, config digest, ciphertext\n * length against the padding grammar, HPKE open under the request's own AAD,\n * then strict unpadding. Time windows, replay, and placement are not checked\n * here — they are device state.\n */\nexport async function openProviderProvisioningSecret(input: {\n readonly request: ProviderProvisioningRequestV1;\n readonly recipient: ProviderSecretRecipient;\n}): Promise<string> {\n const request = parseProviderProvisioningRequest(input.request);\n const sealed = request.sealed;\n if (sealed === undefined) {\n throw new ByokCoreError('provider_provisioning_request_invalid', 'Provider provisioning request carries no sealed secret');\n }\n const publicJwk = parseSealingPublicJwk(input.recipient.publicJwk);\n if (sealed.keyId !== input.recipient.keyId || (await deriveSealingKeyId(publicJwk)) !== input.recipient.keyId) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret is not addressed to this sealing key');\n }\n await assertProviderProvisioningConfigDigest(request);\n const ciphertext = decodeBase64Url(sealed.ciphertext, 'ciphertext');\n const paddedLength = ciphertext.byteLength - HPKE_AEAD_TAG_BYTES;\n if (\n paddedLength < PROVIDER_SECRET_PAD_BLOCK_BYTES\n || paddedLength > PROVIDER_SECRET_MAX_PADDED_BYTES\n || paddedLength % PROVIDER_SECRET_PAD_BLOCK_BYTES !== 0\n ) {\n throw new ByokCoreError('sealed_secret_invalid', 'Sealed secret ciphertext has an invalid length');\n }\n const padded = await hpkeOpenBase({\n recipientPrivateKey: input.recipient.privateKey,\n recipientPublicKey: sealingPublicKeyBytes(publicJwk),\n enc: decodeBase64Url(sealed.enc, 'enc'),\n info: INFO_BYTES(),\n aad: providerSecretAadBytes(request.header, sealed.keyId),\n ciphertext,\n });\n try {\n return unpadProviderSecret(padded);\n } finally {\n padded.fill(0);\n }\n}\n","/**\n * Host-approved Agent memory intent — the identity digest.\n *\n * One `operationDigest` binds an intent to the tenant and device it was\n * approved for and to its exact operation. A Host computes it at approval; a\n * device recomputes it with its OWN enrolled tenant and device ids, so an\n * intent released to another tenant or device, or with any identity or\n * operation field changed, can never match. The digest never covers content:\n * `targetRevision` (the body digest) binds the body instead.\n *\n * Canonicalization is the shared RFC 8785 canonicalizer ({@link canonicalizeJsonBytes});\n * hashing is WebCrypto SHA-256, as for every other core digest.\n */\nimport { canonicalizeJsonBytes, type JsonObject } from './attestation';\nimport { webCryptoSubtle } from './webcrypto';\n\n/** Domain tag inside every agent memory intent operation digest. */\nexport const AGENT_MEMORY_INTENT_DIGEST_VERSION = 'byok-agent-memory-intent-v1' as const;\n\n/** Every field the operation digest covers. `targetRevision` is `null` exactly for `delete`. */\nexport interface AgentMemoryIntentDigestInput {\n readonly tenantId: string;\n readonly deviceId: string;\n readonly intentId: string;\n readonly agentRef: { readonly agentId: string; readonly profileRevision: string };\n readonly path: string;\n readonly operation: 'replace' | 'delete';\n readonly baseRevision: string;\n readonly targetRevision: string | null;\n readonly approvalRef: string;\n}\n\n/**\n * `sha256:<hex>` over\n * `canonicalizeJson({v, tenantId, deviceId, intentId, agentRef, path, operation, baseRevision, targetRevision, approvalRef})`.\n *\n * Only the listed fields are read (an extra property on `input` never changes\n * the digest); a missing field is `undefined`, which the canonicalizer refuses.\n */\nexport async function agentMemoryIntentOperationDigest(input: AgentMemoryIntentDigestInput): Promise<string> {\n const canonical: JsonObject = {\n v: AGENT_MEMORY_INTENT_DIGEST_VERSION,\n tenantId: input.tenantId,\n deviceId: input.deviceId,\n intentId: input.intentId,\n agentRef: { agentId: input.agentRef.agentId, profileRevision: input.agentRef.profileRevision },\n path: input.path,\n operation: input.operation,\n baseRevision: input.baseRevision,\n targetRevision: input.targetRevision,\n approvalRef: input.approvalRef,\n };\n const digest = new Uint8Array(\n await webCryptoSubtle().digest('SHA-256', new Uint8Array(canonicalizeJsonBytes(canonical))),\n );\n let hex = '';\n for (const byte of digest) hex += byte.toString(16).padStart(2, '0');\n return `sha256:${hex}`;\n}\n","/**\n * Nonce-signing domain separation for device token renewal (docs/protocol.md §6.2).\n *\n * S1 (GAP-004) put a domain tag in front of every challenge nonce a device\n * signs: the device key is a long-lived identity key that other planes (S6\n * device proof) also sign structured messages with, so without a tag a\n * signature produced for one purpose would be a valid signature for another.\n *\n * The tag started life as three separate literals — one in the daemon, one on\n * the hosted surface, one on the reference server — each with a comment saying\n * it was byte-identical to the others. That is a drift hazard written down, not\n * a design: three copies agree only until someone edits one. This module is the\n * single authority, and it lives in core for the same reason\n * {@link DEVICE_PROOF_DOMAIN_PREFIX} does — core is the one package all three\n * ends already depend on, it is Node-free and Workers-safe, and it holds no\n * crypto of its own. What travels is *bytes to sign*; who signs them, and with\n * which primitive, stays with each end.\n *\n * There is deliberately no dual mode and no grace window: a raw, unprefixed\n * nonce signature is simply invalid, and a device on an older encoding re-pairs.\n */\n\n/**\n * The domain-separation prefix a device signs along with a challenge nonce.\n *\n * Byte-frozen: `62 79 6f 6b 2d 6e 6f 6e 63 65 2d 76 31 0a` (14 bytes, UTF-8).\n * Changing it invalidates every deployed device's token-renewal path, so it is\n * a wire constant, not a tunable.\n */\nexport const NONCE_SIGNING_DOMAIN = 'byok-nonce-v1\\n';\n\n/**\n * The exact bytes a device signs for a challenge nonce, and the exact bytes a\n * verifier reconstructs: {@link NONCE_SIGNING_DOMAIN} followed by `nonce`,\n * UTF-8 encoded.\n *\n * `TextEncoder` is a platform global on Node and Workers alike, which is what\n * lets the one authority sit in a package that imports no `node:` builtin.\n */\nexport function nonceSigningBytes(nonce: string): Uint8Array {\n return new TextEncoder().encode(NONCE_SIGNING_DOMAIN + nonce);\n}\n","import { ByokCoreError } from '../errors';\nimport type { Clock } from '../stores';\nimport type { ContentHash } from '../blob';\nimport type { StorageReservation, TenantStorageUsage } from '../quota';\nimport type { TenantId } from '../tenant';\n\nexport interface ReservationRecord {\n readonly reservation: StorageReservation;\n readonly deduplicated: boolean;\n}\n/** Shared authority for reservations, object accounting and quota reads. */\nexport class InMemoryStorageLedger {\n readonly #usage = new Map<TenantId, TenantStorageUsage>();\n readonly #reservations = new Map<string, ReservationRecord>();\n readonly #committed = new Map<TenantId, Map<string, { kind: 'object' | 'inline'; bytes: bigint }>>();\n constructor(private readonly clock: Clock) {}\n readReservation(key: string): ReservationRecord | undefined { return this.#reservations.get(key); }\n writeReservation(key: string, record: ReservationRecord): void { this.#reservations.set(key, record); }\n deleteReservation(key: string): void { this.#reservations.delete(key); }\n reservations(): IterableIterator<[string, ReservationRecord]> { return this.#reservations.entries(); }\n readUsage(tenant: TenantId): TenantStorageUsage {\n let usage = this.#usage.get(tenant);\n if (usage === undefined) {\n usage = { committedObjectBytes: 0n, committedInlineBytes: 0n, reservedBytes: 0n, objectCount: 0n, updatedAt: this.clock.now().toISOString() };\n this.#usage.set(tenant, usage);\n }\n return usage;\n }\n writeUsage(tenant: TenantId, usage: TenantStorageUsage): void { this.#usage.set(tenant, usage); }\n isCounted(tenant: TenantId, hash: string): boolean { return this.#committed.get(tenant)?.has(hash) === true; }\n recordCommitted(tenant: TenantId, reservation: StorageReservation): void {\n let hashes = this.#committed.get(tenant);\n if (hashes === undefined) { hashes = new Map(); this.#committed.set(tenant, hashes); }\n hashes.set(reservation.contentHash, { kind: reservation.kind, bytes: reservation.expectedBytes });\n }\n hasReservedObject(tenant: TenantId, hash: ContentHash): boolean {\n for (const { reservation } of this.#reservations.values()) {\n if (reservation.tenantId === tenant && reservation.kind === 'object'\n && reservation.contentHash === hash && reservation.state === 'reserved') return true;\n }\n return false;\n }\n reservedObjectHashes(tenant: TenantId): readonly string[] {\n return [...this.#reservations.values()].filter(({ reservation }) => reservation.tenantId === tenant && reservation.kind === 'object' && reservation.state === 'reserved').map(({ reservation }) => reservation.contentHash);\n }\n prepareCollectedObjectRelease(tenant: TenantId, hash: ContentHash, byteSize: bigint, now: string): { readonly releasedBytes: bigint; readonly commit: () => void } {\n const hashes = this.#committed.get(tenant);\n const accounted = hashes?.get(hash);\n // Direct metadata commits and rows retained across a SQLite restart have\n // no charge in this process-local authority.\n if (accounted === undefined || accounted.kind === 'inline') return { releasedBytes: 0n, commit: () => {} };\n const usage = this.#usage.get(tenant);\n if (usage === undefined || accounted.bytes !== byteSize || usage.committedObjectBytes < accounted.bytes || usage.objectCount < 1n) {\n throw new ByokCoreError('storage_integrity_mismatch', 'Collected object accounting does not match the storage ledger.');\n }\n return { releasedBytes: accounted.bytes, commit: () => {\n hashes!.delete(hash);\n this.writeUsage(tenant, { ...usage, committedObjectBytes: usage.committedObjectBytes - accounted.bytes, objectCount: usage.objectCount - 1n, updatedAt: now });\n } };\n }\n releaseCollectedObject(tenant: TenantId, hash: ContentHash, byteSize: bigint, now: string): bigint {\n const release = this.prepareCollectedObjectRelease(tenant, hash, byteSize, now);\n release.commit();\n return release.releasedBytes;\n }\n}\n","import { ByokCoreError } from './errors';\nimport { assertCanonicalTimestamp } from './time';\n\nexport interface CollectExpiredInput {\n readonly now: string;\n readonly limit: number;\n}\nexport interface CollectExpiredCounts {\n readonly removed: number;\n readonly expired: number;\n readonly releasedBytes: bigint;\n}\nexport interface CollectExpiredResult extends CollectExpiredCounts {\n readonly more: boolean;\n}\nexport function assertCollectExpiredInput(input: CollectExpiredInput): void {\n assertCanonicalTimestamp(input.now, 'now');\n if (!Number.isSafeInteger(input.limit) || input.limit <= 0) {\n throw new ByokCoreError('retention_input_invalid', 'collectExpired limit must be a positive safe integer.');\n }\n}\n/** A committed partial result remains visible when external deletion fails. */\nexport class CollectExpiredFailure extends ByokCoreError {\n constructor(\n readonly committed: CollectExpiredCounts,\n readonly failedRows: number,\n readonly more?: boolean,\n options?: ErrorOptions,\n ) {\n super('retention_collect_failed', 'Retention collection did not complete.', options);\n }\n}\n","import { assertCollectExpiredInput, type CollectExpiredInput, type CollectExpiredResult } from '../retention';\n/**\n * In-memory {@link PresenceStore} reference (§12.3).\n *\n * Expiry is absence. A hint past its `expiresAt` is filtered out of every read\n * and lazily dropped, so no reader can ever observe a stale level and mistake\n * it for a live one. Both stores read time from the injected clock, which is\n * what lets the conformance suite assert expiry without sleeping.\n */\nimport { ByokCoreError } from '../errors';\nimport {\n freezePresenceRuntimeFact,\n type PresenceHint,\n type PresenceHintInput,\n type PresenceStore,\n} from '../presence';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\n\nfunction assertTtl(ttlMs: number): void {\n if (!Number.isFinite(ttlMs) || ttlMs <= 0) {\n throw new ByokCoreError(\n 'hint_ttl_invalid',\n `Hint ttl must be a positive number of milliseconds, received ${String(ttlMs)}.`,\n );\n }\n}\n\nfunction assertMinimumInterval(minimumIntervalMs: number): void {\n if (!Number.isFinite(minimumIntervalMs) || minimumIntervalMs < 0) {\n throw new ByokCoreError(\n 'hint_ttl_invalid',\n `Hint minimum interval must be a non-negative number of milliseconds, received ${String(minimumIntervalMs)}.`,\n );\n }\n}\n\nexport class InMemoryPresenceStore implements PresenceStore {\n readonly #hints = new Map<string, PresenceHint>();\n readonly #clock: Clock;\n\n constructor(clock: Clock) {\n this.#clock = clock;\n }\n\n async publish(tenant: TenantId, input: PresenceHintInput): Promise<PresenceHint> {\n assertTtl(input.ttlMs);\n assertMinimumInterval(input.minimumIntervalMs);\n const now = this.#clock.now();\n const key = tenantKey(tenant, input.deviceId);\n const existing = this.#hints.get(key);\n // A backward clock step has zero elapsed time: only positive intervals throttle.\n if (\n existing &&\n now.toISOString() < existing.expiresAt &&\n Math.max(0, Number(now) - Date.parse(existing.observedAt)) < input.minimumIntervalMs\n ) {\n throw new ByokCoreError(\n 'hint_rate_limited',\n `Presence for ${input.deviceId} was published more recently than the configured minimum interval.`,\n );\n }\n const hint: PresenceHint = {\n tenantId: tenant,\n deviceId: input.deviceId,\n level: input.level,\n ...(input.detail === undefined ? {} : { detail: input.detail }),\n ...(input.configuredToolsets === undefined\n ? {}\n : { configuredToolsets: Object.freeze([...input.configuredToolsets]) }),\n ...(input.clientVersion === undefined ? {} : { clientVersion: input.clientVersion }),\n ...(input.protocolVersions === undefined\n ? {}\n : { protocolVersions: Object.freeze([...input.protocolVersions]) }),\n ...(input.runtimes === undefined\n ? {}\n : {\n runtimes: Object.freeze(input.runtimes.map(freezePresenceRuntimeFact)),\n }),\n observedAt: now.toISOString(),\n expiresAt: new Date(now.getTime() + input.ttlMs).toISOString(),\n };\n this.#hints.set(key, hint);\n return hint;\n }\n\n async read(tenant: TenantId, deviceId: string): Promise<PresenceHint | undefined> {\n const key = tenantKey(tenant, deviceId);\n const hint = this.#hints.get(key);\n if (hint === undefined) return undefined;\n if (this.#isExpired(hint.expiresAt)) {\n this.#hints.delete(key);\n return undefined;\n }\n return hint;\n }\n\n async list(tenant: TenantId): Promise<readonly PresenceHint[]> {\n const prefix = tenantKey(tenant, '');\n const live: PresenceHint[] = [];\n for (const [key, hint] of [...this.#hints.entries()]) {\n if (!key.startsWith(prefix)) continue;\n if (this.#isExpired(hint.expiresAt)) {\n this.#hints.delete(key);\n continue;\n }\n live.push(hint);\n }\n live.sort((left, right) => left.deviceId.localeCompare(right.deviceId));\n return live;\n }\n\n async collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n let removed = 0, more = false;\n for (const [key, hint] of this.#hints) {\n if (hint.tenantId !== tenant || hint.expiresAt > input.now) continue;\n if (removed === input.limit) { more = true; break; }\n this.#hints.delete(key); removed++;\n }\n return { removed, expired: 0, releasedBytes: 0n, more };\n }\n\n #isExpired(expiresAt: string): boolean {\n return this.#clock.now().toISOString() >= expiresAt;\n }\n}\n","/**\n * In-memory {@link BoardStore} reference (§12.3).\n *\n * The claim path is the interesting one: because JavaScript resolves each\n * `await` boundary atomically here, N concurrent `claim` calls serialize and\n * exactly one finds `assignee === undefined`. A SQL composition gets the same\n * outcome from a conditional `UPDATE ... WHERE assignee IS NULL`; the\n * conformance suite asserts the outcome, not the mechanism.\n *\n * `boardSeq` is per tenant and bumps on every mutation, which is what makes\n * `list({ afterSeq })` an incremental feed that cannot leak another tenant's\n * write rate.\n */\nimport {\n isLegalBoardTransition,\n type BoardClaimInput,\n type BoardItem,\n type BoardItemInput,\n type BoardListQuery,\n type BoardPage,\n type BoardStatusUpdateInput,\n type BoardStore,\n type BoardUnclaimInput,\n} from '../board';\nimport { ByokCoreError, CoreConflictError } from '../errors';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\n\nconst DEFAULT_LIST_LIMIT = 50;\n\nexport class InMemoryBoardStore implements BoardStore {\n readonly #items = new Map<string, BoardItem>();\n readonly #seqByTenant = new Map<string, number>();\n readonly #clock: Clock;\n\n constructor(clock: Clock) {\n this.#clock = clock;\n }\n\n async create(tenant: TenantId, input: BoardItemInput): Promise<BoardItem> {\n const key = tenantKey(tenant, input.itemId);\n if (this.#items.has(key)) {\n throw new ByokCoreError(\n 'board_item_exists',\n `Board item ${input.itemId} already exists in this tenant.`,\n );\n }\n const now = this.#now();\n const item: BoardItem = {\n tenantId: tenant,\n itemId: input.itemId,\n channel: input.channel,\n title: input.title,\n status: input.status ?? 'todo',\n boardSeq: this.#nextSeq(tenant),\n createdAt: now,\n updatedAt: now,\n };\n this.#items.set(key, item);\n return item;\n }\n\n async get(tenant: TenantId, itemId: string): Promise<BoardItem | undefined> {\n return this.#items.get(tenantKey(tenant, itemId));\n }\n\n async list(tenant: TenantId, query: BoardListQuery): Promise<BoardPage> {\n const afterSeq = query.afterSeq ?? 0;\n const limit = query.limit ?? DEFAULT_LIST_LIMIT;\n const prefix = tenantKey(tenant, '');\n const matches: BoardItem[] = [];\n for (const [key, item] of this.#items.entries()) {\n if (!key.startsWith(prefix)) continue;\n if (item.boardSeq <= afterSeq) continue;\n if (query.channel !== undefined && item.channel !== query.channel) continue;\n if (query.status !== undefined && item.status !== query.status) continue;\n matches.push(item);\n }\n matches.sort((left, right) => left.boardSeq - right.boardSeq);\n const page = matches.slice(0, limit);\n return {\n items: page,\n nextSeq: page.at(-1)?.boardSeq ?? afterSeq,\n hasMore: matches.length > page.length,\n };\n }\n\n async remove(tenant: TenantId, itemId: string): Promise<void> {\n this.#items.delete(tenantKey(tenant, itemId));\n }\n\n async claim(tenant: TenantId, input: BoardClaimInput): Promise<BoardItem> {\n const item = this.#require(tenant, input.itemId);\n const expectedStatus = input.expectedStatus ?? 'todo';\n\n if (item.assignee !== undefined) {\n if (item.assignee.holderId === input.holderId) {\n // The same holder retrying is not a second winner. But an *explicit*\n // expectedStatus is a full CAS by contract, and skipping it here would\n // let the holder's retry succeed against a status it no longer believes\n // in — a CAS in name only. The default is not applied on this path: a\n // retry of a successful claim legitimately observes `in_progress`.\n if (input.expectedStatus !== undefined && item.status !== input.expectedStatus) {\n throw new CoreConflictError(\n 'board_status_conflict',\n `Board item ${input.itemId} is ${item.status}, not ${input.expectedStatus}.`,\n item,\n this.#now(),\n );\n }\n return item;\n }\n throw new CoreConflictError(\n 'board_claim_conflict',\n `Board item ${input.itemId} is held by ${item.assignee.holderId}.`,\n item,\n this.#now(),\n );\n }\n if (item.status !== expectedStatus) {\n throw new CoreConflictError(\n 'board_status_conflict',\n `Board item ${input.itemId} is ${item.status}, not ${expectedStatus}.`,\n item,\n this.#now(),\n );\n }\n if (item.status !== 'todo' && item.status !== 'in_progress') {\n throw new CoreConflictError(\n 'board_transition_invalid',\n `Board item ${input.itemId} cannot be claimed from ${item.status}.`,\n item,\n this.#now(),\n );\n }\n\n const now = this.#now();\n const claimed: BoardItem = {\n ...item,\n status: item.status === 'todo' ? 'in_progress' : item.status,\n assignee: { holderId: input.holderId, heldSince: now },\n boardSeq: this.#nextSeq(tenant),\n updatedAt: now,\n };\n this.#items.set(tenantKey(tenant, input.itemId), claimed);\n return claimed;\n }\n\n async unclaim(tenant: TenantId, input: BoardUnclaimInput): Promise<BoardItem> {\n const item = this.#require(tenant, input.itemId);\n if (item.assignee === undefined) {\n throw new ByokCoreError(\n 'board_not_held',\n `Board item ${input.itemId} is not held by anyone.`,\n );\n }\n if (item.assignee.holderId !== input.holderId) {\n throw new CoreConflictError(\n 'board_claim_conflict',\n `Board item ${input.itemId} is held by ${item.assignee.holderId}, not ${input.holderId}.`,\n item,\n this.#now(),\n );\n }\n const now = this.#now();\n const released: BoardItem = {\n tenantId: item.tenantId,\n itemId: item.itemId,\n channel: item.channel,\n title: item.title,\n status: item.status === 'in_progress' ? 'todo' : item.status,\n boardSeq: this.#nextSeq(tenant),\n createdAt: item.createdAt,\n updatedAt: now,\n };\n this.#items.set(tenantKey(tenant, input.itemId), released);\n return released;\n }\n\n async updateStatus(tenant: TenantId, input: BoardStatusUpdateInput): Promise<BoardItem> {\n const item = this.#require(tenant, input.itemId);\n if (item.status !== input.expectedStatus) {\n throw new CoreConflictError(\n 'board_status_conflict',\n `Board item ${input.itemId} is ${item.status}, not ${input.expectedStatus}.`,\n item,\n this.#now(),\n );\n }\n if (input.holderId !== undefined && item.assignee?.holderId !== input.holderId) {\n throw new CoreConflictError(\n 'board_claim_conflict',\n `Board item ${input.itemId} is not held by ${input.holderId}.`,\n item,\n this.#now(),\n );\n }\n if (!isLegalBoardTransition(input.expectedStatus, input.status)) {\n throw new CoreConflictError(\n 'board_transition_invalid',\n `${input.expectedStatus} to ${input.status} is not a legal board transition.`,\n item,\n this.#now(),\n );\n }\n const now = this.#now();\n const updated: BoardItem = {\n ...item,\n status: input.status,\n boardSeq: this.#nextSeq(tenant),\n updatedAt: now,\n };\n this.#items.set(tenantKey(tenant, input.itemId), updated);\n return updated;\n }\n\n #require(tenant: TenantId, itemId: string): BoardItem {\n const item = this.#items.get(tenantKey(tenant, itemId));\n if (item === undefined) {\n throw new ByokCoreError(\n 'board_item_not_found',\n `Board item ${itemId} does not exist in this tenant.`,\n );\n }\n return item;\n }\n\n #nextSeq(tenant: TenantId): number {\n const next = (this.#seqByTenant.get(tenant) ?? 0) + 1;\n this.#seqByTenant.set(tenant, next);\n return next;\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n","/**\n * Archive access to the in-memory core stores (#1120).\n *\n * The Host task archive in `@byok-sdk/cloud` rewrites acked and expired mailbox\n * bodies and removes object references in one synchronous step, which the\n * async ports cannot express. Adding methods to the port classes would put\n * them in the port inventory, and exporting functions would put them in this\n * package's API. Each in-memory store instead registers its access here, keyed\n * by the store instance, in a registry under a well-known global symbol. The\n * cloud package reads the same registry by the same key. Nothing here is\n * exported from the package entry.\n */\nimport type { MailboxBody, MailboxMessage } from '../mailbox';\nimport type { TenantId } from '../tenant';\n\nexport interface InMemoryMailboxArchiveAccess {\n /** The retained rows of one device. */\n messagesOf(tenant: TenantId, deviceId: string): readonly MailboxMessage[];\n /** Replaces one retained row's body. The row, its seq and its state stay. */\n replaceBody(tenant: TenantId, deviceId: string, seq: number, body: MailboxBody): void;\n}\n\nexport interface InMemoryObjectArchiveAccess {\n /** Removes every reference `(refKind, refId)` holds and returns how many went. */\n releaseReferences(tenant: TenantId, refKind: string, refId: string): number;\n}\n\n/** Keep identical to the key `@byok-sdk/cloud` reads. */\nconst REGISTRY_KEY = Symbol.for('@byok-sdk/in-memory-archive-access');\n\nfunction registry(): WeakMap<object, unknown> {\n const holder = globalThis as unknown as Record<symbol, WeakMap<object, unknown> | undefined>;\n return (holder[REGISTRY_KEY] ??= new WeakMap<object, unknown>());\n}\n\nexport function registerArchiveAccess(store: object, access: InMemoryMailboxArchiveAccess | InMemoryObjectArchiveAccess): void {\n registry().set(store, access);\n}\n","import { CollectExpiredFailure } from '../retention';\nimport { assertCollectExpiredInput, type CollectExpiredResult } from '../retention';\n/**\n * In-memory {@link MailboxStore} reference (§12.7.3).\n *\n * Every row lives under a `(tenant, device)` composite key, so a cross-tenant\n * read is not \"denied\" — it addresses a different key space and finds nothing.\n * That is the in-memory expression of §12.6.2 layer 3: there is no bare device\n * index to accidentally query.\n *\n * Mailbox bytes are never counted: usage is the sum over the retained\n * `pending` rows, and a `limited` append sums, checks and inserts without\n * yielding, so no append on another device of the same tenant can interleave\n * with the check.\n */\nimport { ByokCoreError, CoreConflictError } from '../errors';\nimport type {\n MailboxAdvanceCursorInput,\n MailboxAppendInput,\n MailboxCloseStreamInput,\n MailboxCursorState,\n MailboxMessage,\n MailboxPage,\n MailboxReadQuery,\n MailboxRecordDeliveryInput,\n MailboxCollectExpiredInput,\n MailboxExpirePendingInput,\n MailboxReopenStreamInput,\n MailboxStore,\n MailboxStreamCloseCause,\n MailboxUsage,\n} from '../mailbox';\nimport { MailboxStreamClosedError } from '../mailbox';\nimport type { QuotaStore } from '../quota';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport { registerArchiveAccess } from './archive-access';\nimport { assertCanonicalTimestamp } from '../time';\n\nconst DEFAULT_READ_LIMIT = 50;\n\ninterface DeviceMailbox {\n nextSeq: number;\n deliveredSeq: number;\n ackedSeq: number;\n cursorUpdatedAt: string;\n closed: { readonly at: string; readonly cause: MailboxStreamCloseCause } | undefined;\n mutationTail: Promise<void>;\n readonly messages: MailboxMessage[];\n readonly byMessageId: Map<string, MailboxMessage>;\n}\n\nexport class InMemoryMailboxStore implements MailboxStore {\n readonly #devices = new Map<string, DeviceMailbox>();\n readonly #clock: Clock;\n readonly #quota: Pick<QuotaStore, 'readEntitlement'>;\n\n /** The mailbox reads its limit from quota; quota never reads the mailbox. */\n constructor(clock: Clock, quota: Pick<QuotaStore, 'readEntitlement'>) {\n this.#clock = clock;\n this.#quota = quota;\n registerArchiveAccess(this, {\n messagesOf: (tenant, deviceId) => this.#devices.get(tenantKey(tenant, deviceId))?.messages ?? [],\n replaceBody: (tenant, deviceId, seq, body) => {\n const device = this.#devices.get(tenantKey(tenant, deviceId));\n const index = device?.messages.findIndex((message) => message.seq === seq) ?? -1;\n if (device === undefined || index < 0) return;\n const replaced: MailboxMessage = { ...device.messages[index]!, ...body };\n device.messages[index] = replaced;\n device.byMessageId.set(replaced.messageId, replaced);\n },\n });\n }\n\n async append(tenant: TenantId, input: MailboxAppendInput): Promise<MailboxMessage> {\n const device = this.#device(tenant, input.deviceId);\n const appended = device.mutationTail.then(async () => {\n if (device.closed !== undefined) throw new MailboxStreamClosedError(input.deviceId, device.closed.cause);\n const existing = device.byMessageId.get(input.messageId);\n if (existing !== undefined) return existing;\n\n // Anything but the one exempt class is limited: an unknown admission\n // fails closed instead of skipping the check.\n const limit =\n input.admission === 'cancellation' ? undefined : await this.#mailboxLimit(tenant);\n const seq = device.nextSeq;\n const materialized = await input.materialize(seq);\n // No await from here to the push: the sum, the check and the insert are\n // one synchronous step, so the check is exact across devices.\n if (limit !== undefined) {\n const used = this.#usedBytes(tenant);\n if (used + materialized.byteSize > limit) {\n throw new ByokCoreError(\n 'storage_quota_exceeded',\n `Mailbox would reach ${String(used + materialized.byteSize)} bytes, over the limit of ${String(limit)} bytes.`,\n );\n }\n }\n const message: MailboxMessage = {\n tenantId: tenant,\n deviceId: input.deviceId,\n seq,\n messageId: input.messageId,\n ...materialized,\n state: 'pending',\n appendedAt: this.#now(),\n };\n device.nextSeq += 1;\n device.messages.push(message);\n device.byMessageId.set(message.messageId, message);\n return message;\n });\n // A failed materializer rejects its own append but must not poison the\n // per-device serializer; the next append starts from the same sequence.\n device.mutationTail = appended.then(\n () => undefined,\n () => undefined,\n );\n return appended;\n }\n\n async readUsage(tenant: TenantId): Promise<MailboxUsage> {\n return { bytes: this.#usedBytes(tenant) };\n }\n\n async readAfter(tenant: TenantId, query: MailboxReadQuery): Promise<MailboxPage> {\n const device = this.#devices.get(tenantKey(tenant, query.deviceId));\n const limit = query.limit ?? DEFAULT_READ_LIMIT;\n if (device === undefined) {\n // A device with no mailbox has lost nothing, so cursor 0 is inside its\n // (empty) window rather than behind a floor it could never have met.\n return { messages: [], nextSeq: query.afterSeq, hasMore: false, recoverableFrom: 1 };\n }\n const pending = device.messages\n .filter((message) => message.state === 'pending' && message.seq > query.afterSeq)\n .sort((left, right) => left.seq - right.seq);\n const page = pending.slice(0, limit);\n const last = page.at(-1);\n return {\n messages: page,\n // Reading is not acknowledging: the returned position is a *read* cursor.\n // Nothing above was mutated, so an identical call replays the same page.\n nextSeq: last?.seq ?? query.afterSeq,\n hasMore: pending.length > page.length,\n // Computed over the WHOLE mailbox, not the queried slice: the floor is a\n // property of the device's history, and reporting it relative to\n // `afterSeq` would make every cursor look recoverable from itself.\n recoverableFrom: this.#recoverableFrom(device),\n };\n }\n\n async advanceCursor(\n tenant: TenantId,\n input: MailboxAdvanceCursorInput,\n ): Promise<MailboxCursorState> {\n const device = this.#device(tenant, input.deviceId);\n const advanced = device.mutationTail.then(() => {\n if (input.ackedSeq < device.ackedSeq) {\n throw new CoreConflictError(\n 'mailbox_cursor_regression',\n `Cursor for device ${input.deviceId} is at ${device.ackedSeq}; refusing to move it back to ${input.ackedSeq}.`,\n this.#cursorState(tenant, input.deviceId, device),\n this.#now(),\n );\n }\n if (input.ackedSeq > device.deliveredSeq) {\n throw new CoreConflictError(\n 'mailbox_cursor_ahead_of_delivery',\n `Cursor for device ${input.deviceId} was delivered through ${device.deliveredSeq}; refusing to acknowledge future cursor ${input.ackedSeq}.`,\n this.#cursorState(tenant, input.deviceId, device),\n this.#now(),\n );\n }\n device.ackedSeq = input.ackedSeq;\n device.cursorUpdatedAt = this.#now();\n for (const [index, message] of device.messages.entries()) {\n if (message.state === 'pending' && message.seq <= input.ackedSeq) {\n device.messages[index] = { ...message, state: 'acked' };\n device.byMessageId.set(message.messageId, device.messages[index]!);\n }\n }\n return this.#cursorState(tenant, input.deviceId, device);\n });\n device.mutationTail = advanced.then(\n () => undefined,\n () => undefined,\n );\n return advanced;\n }\n\n async recordDelivery(\n tenant: TenantId,\n input: MailboxRecordDeliveryInput,\n ): Promise<MailboxCursorState> {\n const device = this.#device(tenant, input.deviceId);\n const recorded = device.mutationTail.then(() => {\n if (input.deliveredSeq > device.deliveredSeq) {\n device.deliveredSeq = input.deliveredSeq;\n }\n return this.#cursorState(tenant, input.deviceId, device);\n });\n device.mutationTail = recorded.then(\n () => undefined,\n () => undefined,\n );\n return recorded;\n }\n\n async readCursor(tenant: TenantId, deviceId: string): Promise<MailboxCursorState> {\n const device = this.#devices.get(tenantKey(tenant, deviceId));\n if (device === undefined) {\n return { tenantId: tenant, deviceId, deliveredSeq: 0, ackedSeq: 0, updatedAt: this.#now() };\n }\n return this.#cursorState(tenant, deviceId, device);\n }\n\n async collectExpired(tenant: TenantId, input: MailboxCollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n assertCanonicalTimestamp(input.ackedBefore, 'ackedBefore');\n assertCanonicalTimestamp(input.expireUnackedBefore, 'expireUnackedBefore');\n assertCanonicalTimestamp(input.reapDeadLettersBefore, 'reapDeadLettersBefore');\n let removed = 0, expired = 0, more = false;\n // The reap runs before this call's expiry, so only rows that were already\n // `expired` qualify, and never the device's highest-seq dead letter: that\n // row is the recoverableFrom floor.\n const reapable = (device: DeviceMailbox, message: MailboxMessage): boolean =>\n message.state === 'expired' && message.appendedAt < input.reapDeadLettersBefore\n && device.messages.some((other) => other.state === 'expired' && other.seq > message.seq);\n try {\n phases: for (const phase of ['acked', 'reap', 'pending'] as const) {\n for (const [key, device] of this.#devices) {\n if (!key.startsWith(tenantKey(tenant, ''))) continue;\n const collected = device.mutationTail.then(() => {\n for (let index = 0; index < device.messages.length;) {\n const message = device.messages[index]!;\n const eligible = phase === 'reap'\n ? reapable(device, message)\n : message.state === phase\n && message.appendedAt < (phase === 'acked' ? input.ackedBefore : input.expireUnackedBefore);\n if (!eligible) { index++; continue; }\n if (removed + expired === input.limit) { more = true; return; }\n if (phase === 'pending') {\n const retired: MailboxMessage = { ...message, state: 'expired' };\n device.messages[index] = retired;\n device.byMessageId.set(retired.messageId, retired);\n expired++; index++;\n } else {\n device.messages.splice(index, 1);\n device.byMessageId.delete(message.messageId);\n removed++;\n }\n }\n });\n device.mutationTail = collected.then(() => undefined, () => undefined);\n await collected;\n if (more) break phases;\n }\n }\n // This call's expiry can leave rows reapable for the next call.\n if (!more) {\n more = [...this.#devices].some(([key, device]) => key.startsWith(tenantKey(tenant, ''))\n && device.messages.some((message) => reapable(device, message)));\n }\n } catch (cause) {\n throw new CollectExpiredFailure({ removed, expired, releasedBytes: 0n }, 0, undefined, { cause });\n }\n // Mailbox usage is the pending rows, never a mutable accounting counter, so no phase moves it.\n return { removed, expired, releasedBytes: 0n, more };\n }\n\n async expirePending(tenant: TenantId, input: MailboxExpirePendingInput): Promise<{ readonly expired: number }> {\n const device = this.#devices.get(tenantKey(tenant, input.deviceId));\n if (device === undefined) return { expired: 0 };\n const selected = new Set(input.seqs);\n return this.#serialize(device, () => expirePendingMessages(device, (message) => selected.has(message.seq)));\n }\n\n async closeStream(tenant: TenantId, input: MailboxCloseStreamInput): Promise<{ readonly expired: number }> {\n const device = this.#device(tenant, input.deviceId);\n return this.#serialize(device, () => {\n device.closed = { at: device.closed?.at ?? this.#now(), cause: input.cause };\n return expirePendingMessages(device, () => true);\n });\n }\n\n async reopenStream(tenant: TenantId, input: MailboxReopenStreamInput): Promise<void> {\n const device = this.#devices.get(tenantKey(tenant, input.deviceId));\n if (device === undefined) return;\n await this.#serialize(device, () => {\n device.closed = undefined;\n });\n }\n\n /** Runs one synchronous step on the device's chain, whatever the previous step's outcome. */\n #serialize<T>(device: DeviceMailbox, step: () => T): Promise<T> {\n const run = device.mutationTail.then(step);\n device.mutationTail = run.then(() => undefined, () => undefined);\n return run;\n }\n\n async #mailboxLimit(tenant: TenantId): Promise<bigint> {\n const entitlement = await this.#quota.readEntitlement(tenant);\n if (entitlement === undefined) {\n throw new ByokCoreError(\n 'storage_entitlement_missing',\n 'No storage entitlement has been issued for this tenant.',\n );\n }\n return entitlement.mailboxLimitBytes;\n }\n\n /**\n * Every `pending` row of the tenant, on any device. Acked and dead-lettered\n * rows are retained but hold no quota (#1115).\n */\n #usedBytes(tenant: TenantId): bigint {\n const prefix = tenantKey(tenant, '');\n let bytes = 0n;\n for (const [key, device] of this.#devices.entries()) {\n if (!key.startsWith(prefix)) continue;\n for (const message of device.messages) {\n if (message.state === 'pending') bytes += message.byteSize;\n }\n }\n return bytes;\n }\n\n #device(tenant: TenantId, deviceId: string): DeviceMailbox {\n if (deviceId.length === 0) {\n throw new ByokCoreError('mailbox_message_not_found', 'Device id must not be empty.');\n }\n const key = tenantKey(tenant, deviceId);\n const existing = this.#devices.get(key);\n if (existing !== undefined) return existing;\n const created: DeviceMailbox = {\n nextSeq: 1,\n deliveredSeq: 0,\n ackedSeq: 0,\n cursorUpdatedAt: this.#now(),\n closed: undefined,\n mutationTail: Promise.resolve(),\n messages: [],\n byMessageId: new Map(),\n };\n this.#devices.set(key, created);\n return created;\n }\n\n /**\n * One past the highest row this device lost, which is exactly the highest\n * `expired` seq: dead-lettered rows are kept rather than deleted (§12.7.5),\n * so the loss stays observable and needs no column of its own to remember it.\n *\n * `acked` is deliberately not counted. A consumed row is not a lost one, and\n * counting it would turn a daemon re-polling from an old cursor — which the\n * at-least-once contract explicitly allows — into a hard failure.\n */\n #recoverableFrom(device: DeviceMailbox): number {\n let lost = 0;\n for (const message of device.messages) {\n if (message.state === 'expired' && message.seq > lost) lost = message.seq;\n }\n return lost + 1;\n }\n\n #cursorState(\n tenant: TenantId,\n deviceId: string,\n device: DeviceMailbox,\n ): MailboxCursorState {\n return {\n tenantId: tenant,\n deviceId,\n deliveredSeq: device.deliveredSeq,\n ackedSeq: device.ackedSeq,\n updatedAt: device.cursorUpdatedAt,\n };\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n\n/** Moves the selected `pending` rows to `expired`; nothing else changes. */\nfunction expirePendingMessages(device: DeviceMailbox, selected: (message: MailboxMessage) => boolean): { readonly expired: number } {\n let expired = 0;\n for (const [index, message] of device.messages.entries()) {\n if (message.state !== 'pending' || !selected(message)) continue;\n const dead: MailboxMessage = { ...message, state: 'expired' };\n device.messages[index] = dead;\n device.byMessageId.set(dead.messageId, dead);\n expired++;\n }\n return { expired };\n}\n","import { InMemoryStorageLedger } from './storage-ledger';\nimport { assertCollectExpiredInput, CollectExpiredFailure, type CollectExpiredResult } from '../retention';\nimport type { ObjectCollectExpiredInput } from '../blob';\n/**\n * In-memory {@link ObjectStore} reference (§12.7.4, §12.7.8).\n *\n * Metadata only — there are no bytes here, and there are none in the Postgres\n * composition either: the manifest is the transaction authority and the object\n * store holds the payload. `refCount` is derived from the reference rows rather\n * than incremented in place, so a double `addReference` for the same\n * `(refKind, refId)` cannot inflate it and strand an object forever.\n */\nimport {\n isLegalObjectTransition,\n type ContentHash,\n type ObjectCommitInput,\n type ObjectListQuery,\n type ObjectManifestEntry,\n type ObjectManifestInput,\n type ObjectReference,\n type ObjectReferenceInput,\n type ObjectStore,\n} from '../blob';\nimport { ByokCoreError } from '../errors';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport { assertCanonicalTimestamp } from '../time';\nimport { registerArchiveAccess } from './archive-access';\n\nconst DEFAULT_LIST_LIMIT = 100;\n\nexport class InMemoryObjectStore implements ObjectStore {\n readonly #manifest = new Map<string, ObjectManifestEntry>();\n readonly #references = new Map<string, ObjectReference>();\n readonly #clock: Clock;\n readonly #deleteCursor = new Map<TenantId, string>();\n\n constructor(clock: Clock, private readonly maintenance: { readonly ledger: InMemoryStorageLedger; readonly bytes: InMemoryObjectBytes }) {\n this.#clock = clock;\n if (maintenance === undefined || maintenance.ledger === undefined ||\n typeof maintenance.bytes?.deleteObject !== 'function') {\n throw new ByokCoreError('retention_input_invalid', 'ObjectStore requires its shared ledger and an explicit byte authority.');\n }\n registerArchiveAccess(this, {\n releaseReferences: (tenant, refKind, refId) => {\n const hashes = new Set<ContentHash>();\n let released = 0;\n for (const [key, reference] of this.#references) {\n if (reference.tenantId !== tenant || reference.refKind !== refKind || reference.refId !== refId) continue;\n this.#references.delete(key);\n hashes.add(reference.hash);\n released += 1;\n }\n for (const hash of hashes) {\n const entry = this.#manifest.get(tenantKey(tenant, hash));\n if (entry !== undefined) this.#recount(tenant, entry);\n }\n return released;\n },\n });\n }\n\n async putManifest(\n tenant: TenantId,\n input: ObjectManifestInput,\n ): Promise<ObjectManifestEntry> {\n const key = tenantKey(tenant, input.hash);\n const existing = this.#manifest.get(key);\n if (existing !== undefined && existing.state !== 'deleted') return existing;\n\n const now = this.#now();\n const entry: ObjectManifestEntry = {\n tenantId: tenant,\n hash: input.hash,\n byteSize: input.byteSize,\n contentType: input.contentType,\n state: 'pending',\n refCount: 0,\n createdAt: now,\n updatedAt: now,\n };\n this.#manifest.set(key, entry);\n return entry;\n }\n\n async commit(tenant: TenantId, input: ObjectCommitInput): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, input.hash);\n if (\n entry.byteSize !== input.observedByteSize ||\n entry.contentType !== input.observedContentType\n ) {\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Observed object ${input.hash} (${String(input.observedByteSize)} bytes, ${input.observedContentType}) does not match the declared manifest.`,\n );\n }\n if (entry.state === 'committed') return entry;\n return this.#transition(tenant, entry, 'committed');\n }\n\n async get(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry | undefined> {\n return this.#manifest.get(tenantKey(tenant, hash));\n }\n\n async list(\n tenant: TenantId,\n query: ObjectListQuery,\n ): Promise<readonly ObjectManifestEntry[]> {\n // The cutoff is compared against `deletePendingAt` as a string below, which\n // only equals a time comparison for the canonical form. A GC sweep reading\n // a mis-parsed cutoff would either miss tombstones or take live ones.\n if (query.deletePendingBefore !== undefined) {\n assertCanonicalTimestamp(query.deletePendingBefore, 'deletePendingBefore');\n }\n const prefix = tenantKey(tenant, '');\n const matches: ObjectManifestEntry[] = [];\n for (const [key, entry] of this.#manifest.entries()) {\n if (!key.startsWith(prefix)) continue;\n if (query.state !== undefined && entry.state !== query.state) continue;\n if (query.deletePendingBefore !== undefined) {\n if (entry.deletePendingAt === undefined) continue;\n if (entry.deletePendingAt >= query.deletePendingBefore) continue;\n }\n matches.push(entry);\n }\n matches.sort((left, right) => left.hash.localeCompare(right.hash));\n return matches.slice(0, query.limit ?? DEFAULT_LIST_LIMIT);\n }\n\n async addReference(\n tenant: TenantId,\n input: ObjectReferenceInput,\n ): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, input.hash);\n if (entry.state !== 'committed') {\n throw new ByokCoreError(\n 'object_state_invalid',\n `Only committed objects can be referenced; ${input.hash} is ${entry.state}.`,\n );\n }\n const refKey = tenantKey(tenant, input.hash, input.refKind, input.refId);\n if (!this.#references.has(refKey)) {\n this.#references.set(refKey, {\n tenantId: tenant,\n hash: input.hash,\n refKind: input.refKind,\n refId: input.refId,\n createdAt: this.#now(),\n });\n }\n return this.#recount(tenant, entry);\n }\n\n async removeReference(\n tenant: TenantId,\n input: ObjectReferenceInput,\n ): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, input.hash);\n this.#references.delete(tenantKey(tenant, input.hash, input.refKind, input.refId));\n return this.#recount(tenant, entry);\n }\n\n async markDeletePending(\n tenant: TenantId,\n hash: ContentHash,\n ): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, hash);\n if (entry.refCount !== 0) {\n throw new ByokCoreError(\n 'object_state_invalid',\n `Object ${hash} still has ${entry.refCount} reference(s).`,\n );\n }\n return this.#transition(tenant, entry, 'delete_pending');\n }\n\n async markDeleted(tenant: TenantId, hash: ContentHash): Promise<ObjectManifestEntry> {\n const entry = this.#require(tenant, hash);\n return this.#transition(tenant, entry, 'deleted');\n }\n\n async collectExpired(tenant: TenantId, input: ObjectCollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n assertCanonicalTimestamp(input.orphanBefore, 'orphanBefore');\n const eligible = (entry: ObjectManifestEntry): boolean => entry.tenantId === tenant && entry.refCount === 0\n && !this.maintenance.ledger.hasReservedObject(tenant, entry.hash)\n && (entry.state === 'delete_pending' || ((entry.state === 'pending' || entry.state === 'committed') && entry.updatedAt < input.orphanBefore));\n let removed = 0, releasedBytes = 0n, more = false, visited = 0, failures = 0;\n let firstFailure: unknown;\n const cursor = this.#deleteCursor.get(tenant) ?? '';\n // Retry tombstones first. Each distinct object consumes one shared slot.\n const entries = [...this.#manifest.values()].filter(eligible);\n const pending = entries.filter(entry => entry.state === 'delete_pending').sort((a, b) => a.hash.localeCompare(b.hash));\n const first = pending.filter(entry => entry.hash > cursor).slice(0, input.limit);\n const fresh = entries.filter(entry => entry.state !== 'delete_pending').sort((a, b) => a.updatedAt.localeCompare(b.updatedAt) || a.hash.localeCompare(b.hash)).slice(0, input.limit - first.length);\n const wrapped = pending.filter(entry => entry.hash <= cursor).slice(0, input.limit - first.length - fresh.length);\n const candidates = [...first, ...fresh, ...wrapped];\n more = entries.length > candidates.length;\n for (const candidate of candidates) {\n if (visited++ === input.limit) { more = true; break; }\n const entry = this.#manifest.get(tenantKey(tenant, candidate.hash))!;\n if (!eligible(entry)) continue;\n const pending = entry.state === 'delete_pending' ? entry : { ...entry, state: 'delete_pending' as const, deletePendingAt: input.now, updatedAt: input.now };\n this.#manifest.set(tenantKey(tenant, entry.hash), pending);\n try {\n // No await may split protection, byte deletion and accounting.\n const release = this.maintenance.ledger.prepareCollectedObjectRelease(tenant, entry.hash, entry.byteSize, input.now);\n this.maintenance.bytes.deleteObject(tenant, entry.hash);\n release.commit();\n const released = release.releasedBytes;\n this.#manifest.set(tenantKey(tenant, entry.hash), { ...pending, state: 'deleted', updatedAt: input.now });\n removed++; releasedBytes += released;\n } catch (cause) {\n failures++; firstFailure ??= cause;\n }\n }\n this.#deleteCursor.set(tenant, wrapped.at(-1)?.hash ?? first.at(-1)?.hash ?? '');\n if (failures > 0) throw new CollectExpiredFailure({ removed, expired: 0, releasedBytes }, failures, true, { cause: firstFailure });\n return { removed, expired: 0, releasedBytes, more };\n }\n\n #transition(\n tenant: TenantId,\n entry: ObjectManifestEntry,\n next: ObjectManifestEntry['state'],\n ): ObjectManifestEntry {\n if (!isLegalObjectTransition(entry.state, next)) {\n throw new ByokCoreError(\n 'object_state_invalid',\n `${entry.state} to ${next} is not a legal object manifest transition.`,\n );\n }\n const now = this.#now();\n const updated: ObjectManifestEntry = {\n ...entry,\n state: next,\n updatedAt: now,\n ...(next === 'delete_pending' ? { deletePendingAt: now } : {}),\n };\n this.#manifest.set(tenantKey(tenant, entry.hash), updated);\n return updated;\n }\n\n #recount(tenant: TenantId, entry: ObjectManifestEntry): ObjectManifestEntry {\n const refPrefix = tenantKey(tenant, entry.hash, '');\n let refCount = 0;\n for (const key of this.#references.keys()) {\n if (key.startsWith(refPrefix)) refCount += 1;\n }\n const updated: ObjectManifestEntry = { ...entry, refCount, updatedAt: this.#now() };\n this.#manifest.set(tenantKey(tenant, entry.hash), updated);\n return updated;\n }\n\n #require(tenant: TenantId, hash: ContentHash): ObjectManifestEntry {\n const entry = this.#manifest.get(tenantKey(tenant, hash));\n if (entry === undefined) {\n throw new ByokCoreError(\n 'object_not_found',\n `Object ${hash} has no manifest row in this tenant.`,\n );\n }\n return entry;\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n\nexport interface InMemoryObjectBytes {\n deleteObject(tenant: TenantId, hash: ContentHash): void;\n}\n","import { CollectExpiredFailure } from '../retention';\nimport { InMemoryStorageLedger, type ReservationRecord } from './storage-ledger';\nimport { assertCollectExpiredInput, type CollectExpiredResult } from '../retention';\nimport type { QuotaCollectExpiredInput } from '../quota';\n/**\n * In-memory {@link QuotaStore} reference (§12.7.6-12.7.7).\n *\n * The invariant this file exists to hold is\n * `committed + reserved + expected <= hardLimitBytes`, checked inside\n * {@link InMemoryQuotaStore.reserve} before any bytes are handed out. A\n * Postgres composition does the same check inside a row-locked transaction;\n * both must reject the same set of concurrent reservations, which is what the\n * conformance suite asserts.\n *\n * Per-tenant hash deduplication lives here rather than in the object manifest\n * because usage accounting is what deduplication is *for* (§12.7.6: same\n * tenant, same hash, counted once). In SQL this set is a join against\n * `object_manifest`; here it is an explicit set, and the observable behavior is\n * identical: finalizing an already-committed hash releases the reservation and\n * adds nothing.\n */\nimport { ByokCoreError, CoreConflictError } from '../errors';\nimport type { ObjectStore } from '../blob';\nimport type {\n StorageFinalizeInput,\n StorageFinalizeResult,\n StorageReservation,\n StorageReservationInput,\n StorageStatus,\n StorageWritePosture,\n QuotaStore,\n TenantStorageEntitlement,\n TenantStorageEntitlementInput,\n TenantStorageUsage,\n} from '../quota';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport { assertCanonicalTimestamp } from '../time';\n\n/** Warning threshold from §12.7.8: 80% of the hard limit. */\nconst WARNING_NUMERATOR = 80n;\nconst WARNING_DENOMINATOR = 100n;\n\n\n\nexport class InMemoryQuotaStore implements QuotaStore {\n readonly #entitlements = new Map<string, TenantStorageEntitlement>();\n readonly #clock: Clock;\n readonly #objects: ObjectStore;\n\n constructor(clock: Clock, objects: ObjectStore, private readonly ledger: InMemoryStorageLedger) {\n this.#clock = clock;\n this.#objects = objects;\n }\n\n async readEntitlement(tenant: TenantId): Promise<TenantStorageEntitlement | undefined> {\n return this.#entitlements.get(tenant);\n }\n\n async writeEntitlement(\n tenant: TenantId,\n input: TenantStorageEntitlementInput,\n ): Promise<TenantStorageEntitlement> {\n // Validated before the version CAS: an unusable deadline is a bad write\n // regardless of which version wins, and `readStatus` compares this field as\n // a string (canonical form is what makes that equal a time comparison).\n if (input.downgradeGraceUntil !== undefined) {\n assertCanonicalTimestamp(input.downgradeGraceUntil, 'downgradeGraceUntil');\n }\n const existing = this.#entitlements.get(tenant);\n if (existing !== undefined && input.version <= existing.version) {\n throw new CoreConflictError(\n 'storage_entitlement_version_conflict',\n `Entitlement is at version ${String(existing.version)}; refusing to apply version ${String(input.version)}.`,\n existing,\n this.#now(),\n );\n }\n const entitlement: TenantStorageEntitlement = {\n tenantId: tenant,\n version: input.version,\n hardLimitBytes: input.hardLimitBytes,\n maxObjectBytes: input.maxObjectBytes,\n maxInlineBytes: input.maxInlineBytes,\n mailboxLimitBytes: input.mailboxLimitBytes,\n retentionPolicyId: input.retentionPolicyId,\n ...(input.downgradeGraceUntil === undefined\n ? {}\n : { downgradeGraceUntil: input.downgradeGraceUntil }),\n };\n this.#entitlements.set(tenant, entitlement);\n return entitlement;\n }\n\n async readUsage(tenant: TenantId): Promise<TenantStorageUsage> {\n return this.#usageOf(tenant);\n }\n\n async readStatus(tenant: TenantId): Promise<StorageStatus> {\n const entitlement = this.#requireEntitlement(tenant);\n const usage = this.#usageOf(tenant);\n const used = this.#usedBytes(usage);\n const graceActive =\n entitlement.downgradeGraceUntil !== undefined &&\n this.#now() < entitlement.downgradeGraceUntil;\n return {\n entitlement,\n usage,\n posture: this.#posture(entitlement, usage, graceActive),\n availableBytes:\n used >= entitlement.hardLimitBytes ? 0n : entitlement.hardLimitBytes - used,\n graceActive,\n };\n }\n\n async readReservation(\n tenant: TenantId,\n reservationId: string,\n ): Promise<StorageReservation | undefined> {\n return this.ledger.readReservation(tenantKey(tenant, reservationId))?.reservation;\n }\n\n async reserve(\n tenant: TenantId,\n input: StorageReservationInput,\n ): Promise<StorageReservation> {\n const entitlement = this.#requireEntitlement(tenant);\n // Admission is the bounded product-side reap point. A daemon may die\n // after receiving a grant and never call finalize/abort; expired holds\n // therefore have to be settled before they can deny the next write.\n // Exhaust the same expiry iterator used by the bounded maintenance pass.\n await Array.from(this.#expireReservations(tenant));\n const key = tenantKey(tenant, input.reservationId);\n const existing = this.ledger.readReservation(key);\n if (existing !== undefined) {\n if (existing.reservation.state === 'reserved') {\n if (\n existing.reservation.kind !== input.kind ||\n existing.reservation.expectedBytes !== input.expectedBytes ||\n existing.reservation.contentHash !== input.contentHash ||\n existing.reservation.contentType !== input.contentType\n ) {\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Reservation ${input.reservationId} already binds a different storage declaration.`,\n );\n }\n return existing.reservation;\n }\n throw new ByokCoreError(\n 'storage_reservation_expired',\n `Reservation ${input.reservationId} is already ${existing.reservation.state}.`,\n );\n }\n\n const usage = this.#usageOf(tenant);\n const graceActive =\n entitlement.downgradeGraceUntil !== undefined &&\n this.#now() < entitlement.downgradeGraceUntil;\n if (this.#posture(entitlement, usage, graceActive) === 'suspended') {\n throw new ByokCoreError(\n 'storage_write_suspended',\n 'Tenant is over its hard limit and its downgrade grace has ended; durable writes are suspended.',\n );\n }\n\n const perObjectLimit =\n input.kind === 'object' ? entitlement.maxObjectBytes : entitlement.maxInlineBytes;\n if (input.expectedBytes > perObjectLimit) {\n throw new ByokCoreError(\n 'storage_object_too_large',\n `${String(input.expectedBytes)} bytes exceeds the ${input.kind} limit of ${String(perObjectLimit)} bytes.`,\n );\n }\n if (this.#usedBytes(usage) + input.expectedBytes > entitlement.hardLimitBytes) {\n throw new ByokCoreError(\n 'storage_quota_exceeded',\n `Reserving ${String(input.expectedBytes)} bytes would exceed the hard limit of ${String(entitlement.hardLimitBytes)} bytes.`,\n );\n }\n\n const now = this.#now();\n const reservation: StorageReservation = {\n tenantId: tenant,\n reservationId: input.reservationId,\n state: 'reserved',\n kind: input.kind,\n expectedBytes: input.expectedBytes,\n contentHash: input.contentHash,\n contentType: input.contentType,\n createdAt: now,\n expiresAt: new Date(this.#clock.now().getTime() + input.ttlMs).toISOString(),\n };\n this.ledger.writeReservation(key, { reservation, deduplicated: false });\n this.#setUsage(tenant, { ...usage, reservedBytes: usage.reservedBytes + input.expectedBytes });\n return reservation;\n }\n\n async finalizeReservation(\n tenant: TenantId,\n input: StorageFinalizeInput,\n ): Promise<StorageFinalizeResult> {\n const key = tenantKey(tenant, input.reservationId);\n const record = this.#requireReservation(tenant, input.reservationId);\n const reservation = record.reservation;\n\n if (reservation.state === 'committed') {\n return {\n reservation,\n usage: this.#usageOf(tenant),\n deduplicated: record.deduplicated,\n };\n }\n if (reservation.state !== 'reserved') {\n throw new ByokCoreError(\n 'storage_reservation_expired',\n `Reservation ${input.reservationId} is ${reservation.state}.`,\n );\n }\n if (this.#now() >= reservation.expiresAt) {\n this.#settle(tenant, key, record, 'expired');\n throw new ByokCoreError(\n 'storage_reservation_expired',\n `Reservation ${input.reservationId} expired at ${reservation.expiresAt}.`,\n );\n }\n if (\n input.observedByteSize !== reservation.expectedBytes ||\n input.observedContentType !== reservation.contentType\n ) {\n // §12.7.7 step 6: a failed finalize releases the bytes; the uploaded\n // object becomes an orphan candidate for the GC worker.\n this.#settle(tenant, key, record, 'aborted');\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Observed object does not match reservation ${input.reservationId}.`,\n );\n }\n\n if (reservation.kind === 'object') {\n try {\n await this.#objects.commit(tenant, {\n hash: reservation.contentHash,\n observedByteSize: input.observedByteSize,\n observedContentType: input.observedContentType,\n });\n } catch (error) {\n this.#settle(tenant, key, record, 'aborted');\n if (\n error instanceof ByokCoreError &&\n (error.code === 'object_not_found' || error.code === 'object_state_invalid')\n ) {\n throw new ByokCoreError(\n 'storage_integrity_mismatch',\n `Reservation ${input.reservationId} has no committable object manifest.`,\n { cause: error },\n );\n }\n throw error;\n }\n }\n\n // Same tenant, same hash, counted once (§12.7.6). `#settle` has already\n // released the reserved bytes, so a deduplicated finalize adds nothing.\n const deduplicated = this.ledger.isCounted(tenant, reservation.contentHash);\n const settled = this.#settle(tenant, key, record, 'committed', deduplicated);\n\n if (!deduplicated) {\n this.ledger.recordCommitted(tenant, reservation);\n const current = this.#usageOf(tenant);\n this.#setUsage(tenant, {\n ...current,\n committedObjectBytes:\n reservation.kind === 'object'\n ? current.committedObjectBytes + reservation.expectedBytes\n : current.committedObjectBytes,\n committedInlineBytes:\n reservation.kind === 'inline'\n ? current.committedInlineBytes + reservation.expectedBytes\n : current.committedInlineBytes,\n objectCount:\n reservation.kind === 'object' ? current.objectCount + 1n : current.objectCount,\n });\n }\n\n return { reservation: settled, usage: this.#usageOf(tenant), deduplicated };\n }\n\n async abortReservation(\n tenant: TenantId,\n reservationId: string,\n ): Promise<StorageReservation> {\n const key = tenantKey(tenant, reservationId);\n const record = this.#requireReservation(tenant, reservationId);\n if (record.reservation.state !== 'reserved') return record.reservation;\n return this.#settle(tenant, key, record, 'aborted');\n }\n\n *#expireReservations(tenant: TenantId, now = this.#now(), limit = Number.MAX_SAFE_INTEGER): IterableIterator<StorageReservation> {\n const prefix = tenantKey(tenant, '');\n let expired = 0;\n for (const [key, record] of this.ledger.reservations()) {\n if (!key.startsWith(prefix) || record.reservation.state !== 'reserved' || now < record.reservation.expiresAt) continue;\n yield this.#settle(tenant, key, record, 'expired', false, now);\n if (++expired === limit) return;\n }\n }\n\n async collectExpired(tenant: TenantId, input: QuotaCollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n assertCanonicalTimestamp(input.settledBefore, 'settledBefore');\n let expired = 0, releasedBytes = 0n, removed = 0, more = false;\n try {\n for (const reservation of this.#expireReservations(tenant, input.now, input.limit)) {\n expired++;\n releasedBytes += reservation.expectedBytes;\n }\n } catch (cause) {\n throw new CollectExpiredFailure({ removed, expired, releasedBytes }, 1, true, { cause });\n }\n const prefix = tenantKey(tenant, '');\n try {\n for (const [key, record] of this.ledger.reservations()) {\n if (!key.startsWith(prefix)) continue;\n const row = record.reservation;\n const shouldExpire = row.state === 'reserved' && row.expiresAt <= input.now;\n const shouldRemove = (row.state === 'expired' || row.state === 'aborted') && row.settledAt !== undefined && row.settledAt < input.settledBefore;\n if (!shouldExpire && !shouldRemove) continue;\n if (shouldExpire || removed + expired === input.limit) { more = true; continue; }\n this.ledger.deleteReservation(key); removed++;\n }\n } catch (cause) {\n throw new CollectExpiredFailure({ removed, expired, releasedBytes }, 0, undefined, { cause });\n }\n return { removed, expired, releasedBytes, more };\n }\n\n #settle(\n tenant: TenantId,\n key: string,\n record: ReservationRecord,\n state: Exclude<StorageReservation['state'], 'reserved'>,\n deduplicated = false,\n settledAt = this.#now(),\n ): StorageReservation {\n const settled: StorageReservation = {\n ...record.reservation,\n state,\n settledAt,\n };\n const usage = this.#usageOf(tenant);\n if (usage.reservedBytes < record.reservation.expectedBytes) {\n throw new ByokCoreError('storage_integrity_mismatch', 'Reservation settlement would underflow reserved usage.');\n }\n this.ledger.writeReservation(key, { reservation: settled, deduplicated });\n this.#setUsage(tenant, { ...usage, reservedBytes: usage.reservedBytes - record.reservation.expectedBytes });\n return settled;\n }\n\n #posture(\n entitlement: TenantStorageEntitlement,\n usage: TenantStorageUsage,\n graceActive: boolean,\n ): StorageWritePosture {\n const used = this.#usedBytes(usage);\n if (used >= entitlement.hardLimitBytes) {\n // A tenant that was downgraded gets its configured grace window; once it\n // ends and usage is still over the limit, the tenant is read-only (423)\n // rather than merely unable to add bytes (507).\n const graceConfigured = entitlement.downgradeGraceUntil !== undefined;\n return graceConfigured && !graceActive ? 'suspended' : 'blocked';\n }\n if (\n entitlement.hardLimitBytes > 0n &&\n used * WARNING_DENOMINATOR >= entitlement.hardLimitBytes * WARNING_NUMERATOR\n ) {\n return 'warning';\n }\n return 'normal';\n }\n\n #usedBytes(usage: TenantStorageUsage): bigint {\n return usage.committedObjectBytes + usage.committedInlineBytes + usage.reservedBytes;\n }\n\n #usageOf(tenant: TenantId): TenantStorageUsage { return this.ledger.readUsage(tenant); }\n #setUsage(tenant: TenantId, usage: TenantStorageUsage): void {\n this.ledger.writeUsage(tenant, { ...usage, updatedAt: this.#now() });\n }\n\n #requireEntitlement(tenant: TenantId): TenantStorageEntitlement {\n const entitlement = this.#entitlements.get(tenant);\n if (entitlement === undefined) {\n throw new ByokCoreError(\n 'storage_entitlement_missing',\n 'No storage entitlement has been issued for this tenant.',\n );\n }\n return entitlement;\n }\n\n #requireReservation(tenant: TenantId, reservationId: string): ReservationRecord {\n const record = this.ledger.readReservation(tenantKey(tenant, reservationId));\n if (record === undefined) {\n throw new ByokCoreError(\n 'storage_reservation_not_found',\n `Reservation ${reservationId} does not exist in this tenant.`,\n );\n }\n return record;\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n","/**\n * In-memory {@link SkillPackStore} reference (plan `skill-pack-delivery-channel`).\n *\n * The interesting property is what `publish` refuses. This store cannot hash —\n * core has no crypto — so it is NOT the integrity authority for a pack, and it\n * does not pretend to be: the publisher mints the addresses and the installing\n * device re-derives and verifies every one of them. What this store CAN check\n * without crypto, it checks, and rejects rather than storing a pack whose\n * manifest and bytes already disagree at publish time: the declared path set\n * must be exactly the delivered path set, and every delivered file's UTF-8 byte\n * length must equal what its row declared.\n *\n * Storing that pair unchecked would be the worse failure mode by far — the\n * device would fetch, verify, reject, and have no way to tell a corrupt\n * publication from a tampered response.\n */\nimport {\n SKILL_PACK_ENTRY_PATH,\n checkSkillPackEntry,\n checkSkillPackManifest,\n type SkillPackFileContent,\n type SkillPackListQuery,\n type SkillPackManifest,\n type SkillPackPublishInput,\n type SkillPackStore,\n} from '../skill-pack';\nimport { ByokCoreError } from '../errors';\nimport { tenantKey, type TenantId } from '../tenant';\n\nconst DEFAULT_LIST_LIMIT = 50;\n\ninterface StoredPack {\n readonly manifest: SkillPackManifest;\n readonly contents: ReadonlyMap<string, string>;\n}\n\nexport class InMemorySkillPackStore implements SkillPackStore {\n readonly #packs = new Map<string, StoredPack>();\n\n async publish(tenant: TenantId, input: SkillPackPublishInput): Promise<SkillPackManifest> {\n const { manifest } = input;\n const structural = checkSkillPackManifest(manifest);\n if (!structural.ok) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${structural.reason} — ${structural.detail}`,\n );\n }\n\n const contents = new Map<string, string>();\n for (const file of input.files) {\n if (contents.has(file.path)) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(file.path)} was supplied twice.`,\n );\n }\n contents.set(file.path, file.content);\n }\n\n for (const declared of manifest.files) {\n const content = contents.get(declared.path);\n if (content === undefined) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(declared.path)} is declared but was not supplied.`,\n );\n }\n const bytes = new TextEncoder().encode(content).length;\n if (bytes !== declared.byteSize) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(declared.path)} declares ${declared.byteSize} bytes and supplies ${bytes}.`,\n );\n }\n }\n if (contents.size !== manifest.files.length) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${contents.size} files were supplied for ${manifest.files.length} declared rows.`,\n );\n }\n\n const entry = checkSkillPackEntry(manifest, contents.get(SKILL_PACK_ENTRY_PATH)!);\n if (!entry.ok) {\n throw new ByokCoreError(\n 'skill_pack_manifest_invalid',\n `Refusing to publish ${JSON.stringify(manifest.name)}: ${entry.reason} — ${entry.detail}`,\n );\n }\n\n this.#packs.set(tenantKey(tenant, manifest.name), { manifest, contents });\n return manifest;\n }\n\n async get(tenant: TenantId, name: string): Promise<SkillPackManifest | undefined> {\n return this.#packs.get(tenantKey(tenant, name))?.manifest;\n }\n\n async list(tenant: TenantId, query: SkillPackListQuery): Promise<readonly SkillPackManifest[]> {\n const prefix = tenantKey(tenant, '');\n const manifests: SkillPackManifest[] = [];\n for (const [key, pack] of this.#packs.entries()) {\n if (!key.startsWith(prefix)) continue;\n manifests.push(pack.manifest);\n }\n manifests.sort((left, right) => (left.name < right.name ? -1 : left.name > right.name ? 1 : 0));\n return manifests.slice(0, query.limit ?? DEFAULT_LIST_LIMIT);\n }\n\n async readFile(\n tenant: TenantId,\n name: string,\n path: string,\n ): Promise<SkillPackFileContent | undefined> {\n const pack = this.#packs.get(tenantKey(tenant, name));\n if (pack === undefined) return undefined;\n const declared = pack.manifest.files.find((file) => file.path === path);\n const content = pack.contents.get(path);\n if (declared === undefined || content === undefined) return undefined;\n return {\n path: declared.path,\n contentHash: declared.contentHash,\n byteSize: declared.byteSize,\n content,\n };\n }\n}\n","/**\n * In-memory {@link TruthStore} reference (§12.3, §12.6.4).\n *\n * Two write models, one storage shape. The terminal path is first-write-wins\n * with hash-equality replay; the snapshot path is `expectedRev` CAS. Neither\n * ever merges bodies — a conflict hands back the record it lost to and stops,\n * because the device holding the context is the only party that can decide what\n * the merged truth should be.\n */\nimport { CoreConflictError } from '../errors';\nimport type { Clock } from '../stores';\nimport { tenantKey, type TenantId } from '../tenant';\nimport type {\n SnapshotWriteInput,\n TerminalWriteInput,\n TruthManifestEntry,\n TruthManifestQuery,\n TruthRecord,\n TruthRecordSelector,\n TruthStore,\n} from '../truth';\n\nconst DEFAULT_MANIFEST_LIMIT = 100;\n\nexport class InMemoryTruthStore implements TruthStore {\n readonly #records = new Map<string, TruthRecord>();\n readonly #clock: Clock;\n\n constructor(clock: Clock) {\n this.#clock = clock;\n }\n\n async writeTerminal(tenant: TenantId, input: TerminalWriteInput): Promise<TruthRecord> {\n const key = tenantKey(tenant, 'task.terminal', input.taskId);\n const existing = this.#records.get(key);\n if (existing !== undefined) {\n if (existing.contentHash === input.contentHash) {\n // Exact replay of a committed fact: return the original, unchanged.\n return existing;\n }\n throw new CoreConflictError(\n 'terminal_conflict',\n `Task ${input.taskId} already has an immutable terminal record with a different hash.`,\n existing,\n this.#now(),\n );\n }\n const record: TruthRecord = {\n tenantId: tenant,\n kind: 'task.terminal',\n recordKey: input.taskId,\n rev: 1,\n contentHash: input.contentHash,\n byteSize: input.byteSize,\n body: input.body,\n ...(input.label === undefined ? {} : { label: input.label }),\n ...(input.requestId === undefined ? {} : { requestId: input.requestId }),\n writtenAt: this.#now(),\n };\n this.#records.set(key, record);\n return record;\n }\n\n async writeSnapshot(tenant: TenantId, input: SnapshotWriteInput): Promise<TruthRecord> {\n const key = tenantKey(tenant, input.kind, input.recordKey);\n const existing = this.#records.get(key);\n const currentRev = existing?.rev ?? 0;\n if (input.expectedRev !== currentRev) {\n throw new CoreConflictError<TruthRecord | undefined>(\n 'truth_revision_conflict',\n `Record ${input.kind}/${input.recordKey} is at rev ${currentRev}, not ${input.expectedRev}.`,\n existing,\n this.#now(),\n );\n }\n const record: TruthRecord = {\n tenantId: tenant,\n kind: input.kind,\n recordKey: input.recordKey,\n rev: currentRev + 1,\n contentHash: input.contentHash,\n byteSize: input.byteSize,\n body: input.body,\n ...(input.label === undefined ? {} : { label: input.label }),\n ...(input.requestId === undefined ? {} : { requestId: input.requestId }),\n writtenAt: this.#now(),\n };\n this.#records.set(key, record);\n return record;\n }\n\n async getRecord(\n tenant: TenantId,\n selector: TruthRecordSelector,\n ): Promise<TruthRecord | undefined> {\n return this.#records.get(tenantKey(tenant, selector.kind, selector.recordKey));\n }\n\n async listManifest(\n tenant: TenantId,\n query: TruthManifestQuery,\n ): Promise<readonly TruthManifestEntry[]> {\n const prefix = tenantKey(tenant, '');\n const entries: TruthManifestEntry[] = [];\n for (const [key, record] of this.#records.entries()) {\n if (!key.startsWith(prefix)) continue;\n if (query.kind !== undefined && record.kind !== query.kind) continue;\n if (query.keyPrefix !== undefined && !record.recordKey.startsWith(query.keyPrefix)) {\n continue;\n }\n entries.push({\n kind: record.kind,\n recordKey: record.recordKey,\n rev: record.rev,\n contentHash: record.contentHash,\n byteSize: record.byteSize,\n ...(record.label === undefined ? {} : { label: record.label }),\n updatedAt: record.writtenAt,\n });\n }\n entries.sort(\n (left, right) =>\n left.kind.localeCompare(right.kind) || left.recordKey.localeCompare(right.recordKey),\n );\n return entries.slice(0, query.limit ?? DEFAULT_MANIFEST_LIMIT);\n }\n\n #now(): string {\n return this.#clock.now().toISOString();\n }\n}\n","/**\n * A deterministic clock for the in-memory reference and the conformance suite.\n *\n * TTL behavior (presence expiry, activity expiry, reservation expiry) is part\n * of the contract, and asserting it against a wall clock means either sleeping\n * or accepting flakes. A composition under test injects one of these and moves\n * time explicitly.\n */\nimport type { MutableClock } from '../stores';\n\n/** Fixed start instant, so golden-ish assertions in the suite read the same on every run. */\nexport const IN_MEMORY_CLOCK_EPOCH = '2026-01-01T00:00:00.000Z';\n\nexport function createMutableClock(start: Date = new Date(IN_MEMORY_CLOCK_EPOCH)): MutableClock {\n let current = start.getTime();\n return {\n now(): Date {\n return new Date(current);\n },\n advance(ms: number): void {\n current += ms;\n },\n set(instant: Date): void {\n current = instant.getTime();\n },\n };\n}\n","import { assertCollectExpiredInput, type CollectExpiredInput, type CollectExpiredResult } from '../retention';\nimport type { TenantId } from '../tenant';\nimport type {\n DeviceAssertionReplayConsumeInput,\n DeviceAssertionReplayAuthority,\n} from '../device-assertion';\n\n/**\n * The reference key, in the SAME segment order as the durable primary key\n * (`deploy/sql/0022_task_assertion_replay_schema.sql`):\n * `(tenant_id, issuer, product_id, device_id, audience, schema, jti)`.\n *\n * The `schema` segment is what contract §8.2(2) requires: one `jti` presented\n * as a device assertion and as a task assertion produces two distinct keys, so\n * each lane is consumed exactly once and neither occupies the other's slot.\n * Order matters only in that it must match the SQL key — a reference authority\n * that keyed differently from the durable one would let the two implementations\n * disagree about which credentials collide.\n */\nfunction replayKey(input: DeviceAssertionReplayConsumeInput): string {\n return JSON.stringify([\n input.tenantId,\n input.issuer,\n input.productId,\n input.deviceId,\n input.audience,\n input.schema,\n input.jti,\n ]);\n}\n\n/** Process-local reference authority. Production runtimes need durable atomic storage. */\nexport class InMemoryDeviceAssertionReplayAuthority implements DeviceAssertionReplayAuthority {\n readonly #expiresAtByKey = new Map<string, number>();\n\n async consume(input: DeviceAssertionReplayConsumeInput): Promise<boolean> {\n const expiresAt = Date.parse(input.expiresAt);\n if (!Number.isFinite(expiresAt)) throw new Error('device assertion replay expiry is invalid');\n const key = replayKey(input);\n if (this.#expiresAtByKey.has(key)) return false;\n this.#expiresAtByKey.set(key, expiresAt);\n return true;\n }\n\n async collectExpired(tenant: TenantId, input: CollectExpiredInput): Promise<CollectExpiredResult> {\n assertCollectExpiredInput(input);\n const cutoff = Date.parse(input.now);\n let removed = 0, more = false;\n for (const [key, expiresAt] of this.#expiresAtByKey) {\n if (JSON.parse(key)[0] !== tenant || expiresAt > cutoff) continue;\n if (removed === input.limit) { more = true; break; }\n this.#expiresAtByKey.delete(key); removed++;\n }\n return { removed, expired: 0, releasedBytes: 0n, more };\n }\n}\n","import { InMemoryStorageLedger } from './storage-ledger';\nimport type { InMemoryObjectBytes } from './blob';\n/**\n * The in-memory reference composition.\n *\n * This exists to be the first thing that passes the conformance suite, and to\n * stay the cheapest way to run it. It is a reference, not a production store:\n * everything lives in process memory and nothing survives a restart. What it\n * *does* guarantee is that the behavior the suite asserts is achievable without\n * a database, which is what makes the same assertions meaningful when a\n * Postgres + R2 composition runs them later.\n */\nimport { InMemoryPresenceStore } from './presence';\nimport { InMemoryBoardStore } from './board';\nimport { InMemoryMailboxStore } from './mailbox';\nimport { InMemoryObjectStore } from './blob';\nimport { InMemoryQuotaStore } from './quota';\nimport { InMemorySkillPackStore } from './skill-pack';\nimport { InMemoryTruthStore } from './truth';\nimport { createMutableClock } from './clock';\nimport type { Clock, CoreStores, MutableClock } from '../stores';\n\nexport { createMutableClock, IN_MEMORY_CLOCK_EPOCH } from './clock';\nexport { InMemoryMailboxStore } from './mailbox';\nexport { InMemoryBoardStore } from './board';\nexport { InMemoryTruthStore } from './truth';\nexport { InMemoryPresenceStore } from './presence';\nexport { InMemoryObjectStore } from './blob';\nexport { InMemoryQuotaStore } from './quota';\nexport { InMemorySkillPackStore } from './skill-pack';\nexport { InMemoryDeviceAssertionReplayAuthority } from './device-assertion-replay';\n\nexport interface InMemoryCoreOptions {\n readonly objectBytes: InMemoryObjectBytes;\n /** Defaults to a fresh {@link createMutableClock}, so TTL behavior is deterministic. */\n readonly clock?: Clock;\n}\n\nexport interface InMemoryCoreComposition {\n readonly stores: CoreStores;\n /** The clock the stores read. Mutable only when the caller did not inject its own. */\n readonly clock: Clock;\n}\n\nexport function createInMemoryCoreStores(\n options: InMemoryCoreOptions,\n): InMemoryCoreComposition {\n const clock: Clock = options.clock ?? createMutableClock();\n const ledger = new InMemoryStorageLedger(clock);\n const objects = new InMemoryObjectStore(clock, { ledger, bytes: options.objectBytes });\n const quota = new InMemoryQuotaStore(clock, objects, ledger);\n const stores: CoreStores = {\n mailbox: new InMemoryMailboxStore(clock, quota),\n board: new InMemoryBoardStore(clock),\n truth: new InMemoryTruthStore(clock),\n presence: new InMemoryPresenceStore(clock),\n objects,\n quota,\n skillPacks: new InMemorySkillPackStore(),\n };\n return { stores, clock };\n}\n\n/** Convenience for tests that need to move time: returns the composition and its mutable clock. */\nexport function createInMemoryCoreCompositionWithClock(objectBytes: InMemoryObjectBytes): {\n readonly stores: CoreStores;\n readonly clock: MutableClock;\n} {\n const clock = createMutableClock();\n return { stores: createInMemoryCoreStores({ clock, objectBytes }).stores, clock };\n}\n\nexport { InMemoryStorageLedger } from './storage-ledger';\nexport type { InMemoryObjectBytes } from './blob';\n","import { ByokCoreError } from './errors';\n\nexport const ROUTINE_DAYS_OF_WEEK = Object.freeze(['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'] as const);\nexport type RoutineDayOfWeek = (typeof ROUTINE_DAYS_OF_WEEK)[number];\n\n/**\n * One local time per matching day. No daysOfWeek and no dayOfMonth: every\n * day. daysOfWeek: those weekdays only. dayOfMonth: that day of every month,\n * or of `month` only. daysOfWeek and dayOfMonth never appear together;\n * `month` needs `dayOfMonth`.\n */\nexport interface RoutineSchedule {\n readonly minute: number;\n readonly hour: number;\n readonly daysOfWeek?: readonly RoutineDayOfWeek[];\n readonly dayOfMonth?: number;\n readonly month?: number;\n readonly tz: string;\n}\n/**\n * 368 days: a yearly date can be 366 days plus a DST shift apart (leap year\n * in between, DST state flips). The embedded wake limit must match this value.\n */\nexport const ROUTINE_HORIZON_MS = 368 * 86_400_000;\n/**\n * Supported `now`: [2000-01-01T00:00Z, 2200-01-01T00:00Z). Before 1972 some\n * zones have second-level offsets (Africa/Monrovia); past 2200 tz rules are\n * projections. Date and Intl themselves cover ±8.64e15 ms.\n */\nexport const ROUTINE_MIN_NOW = Date.UTC(2000, 0, 1);\nexport const ROUTINE_MAX_NOW = Date.UTC(2200, 0, 1);\nexport type RoutineScheduleIssueCode = 'schedule_invalid' | 'schedule_unreachable' | 'schedule_beyond_horizon' | 'tz_invalid';\nexport type RoutineScheduleCheck = { readonly ok: true } | { readonly ok: false; readonly code: RoutineScheduleIssueCode; readonly message: string };\n\nconst KEYS = new Set(['minute', 'hour', 'daysOfWeek', 'dayOfMonth', 'month', 'tz']);\n/** Days in each month of a common year; February 29 is handled apart. */\nconst COMMON_YEAR_DAYS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\nconst TZ_NAME = /^[A-Za-z][A-Za-z0-9_+-]*(?:\\/[A-Za-z0-9_+-]+)*$/;\nconst DAY_MS = 86_400_000;\n/** Date.getUTCDay() index (0 = Sunday) to the schedule's day name. */\nconst UTC_DAY_NAME: readonly RoutineDayOfWeek[] = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];\n\ninterface Parsed { minute: number; hour: number; days?: Set<RoutineDayOfWeek>; dayOfMonth?: number; month?: number; tz: string }\nclass ScheduleError extends Error {\n readonly code: RoutineScheduleIssueCode;\n constructor(code: RoutineScheduleIssueCode, message: string) { super(message); this.code = code; }\n}\nconst invalid = (message: string) => new ScheduleError('schedule_invalid', message);\n\nfunction integer(value: unknown, name: string, min: number, max: number): number {\n if (typeof value !== 'number' || !Number.isInteger(value) || value < min || value > max) throw invalid(`${name} must be an integer ${min}-${max}`);\n return value;\n}\n\nconst formatters = new Map<string, Intl.DateTimeFormat>();\nfunction formatter(tz: string): Intl.DateTimeFormat {\n let f = formatters.get(tz);\n if (!f) {\n f = new Intl.DateTimeFormat('en-US', { timeZone: tz, hourCycle: 'h23', year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' });\n if (formatters.size >= 64) formatters.delete(formatters.keys().next().value!);\n formatters.set(tz, f);\n }\n return f;\n}\n\nfunction checkTz(tz: unknown): string {\n if (typeof tz !== 'string' || !TZ_NAME.test(tz)) throw new ScheduleError('tz_invalid', `${JSON.stringify(tz)} is not an IANA zone name`);\n try { formatter(tz); } catch { throw new ScheduleError('tz_invalid', `\"${tz}\" is not a known IANA zone`); }\n return tz;\n}\n\nfunction parse(schedule: RoutineSchedule): Parsed {\n if (schedule === null || typeof schedule !== 'object' || Array.isArray(schedule)) throw invalid('schedule must be an object');\n for (const key of Object.keys(schedule)) if (!KEYS.has(key)) throw invalid(`unknown field ${key}`);\n const p: Parsed = { minute: integer(schedule.minute, 'minute', 0, 59), hour: integer(schedule.hour, 'hour', 0, 23), tz: checkTz(schedule.tz) };\n const s = schedule as { daysOfWeek?: unknown; dayOfMonth?: unknown; month?: unknown };\n if (s.daysOfWeek !== undefined && s.dayOfMonth !== undefined) throw invalid('daysOfWeek and dayOfMonth cannot both appear');\n if (s.month !== undefined && s.dayOfMonth === undefined) throw invalid('month needs dayOfMonth');\n if (s.daysOfWeek !== undefined) {\n if (!Array.isArray(s.daysOfWeek) || s.daysOfWeek.length < 1 || s.daysOfWeek.length > 7) throw invalid('daysOfWeek must list 1-7 days');\n for (const d of s.daysOfWeek) if (!(ROUTINE_DAYS_OF_WEEK as readonly unknown[]).includes(d)) throw invalid(`unknown day ${JSON.stringify(d)}`);\n p.days = new Set(s.daysOfWeek as RoutineDayOfWeek[]); // duplicates collapse\n }\n if (s.dayOfMonth !== undefined) {\n p.dayOfMonth = integer(s.dayOfMonth, 'dayOfMonth', 1, 31);\n if (s.month !== undefined) {\n p.month = integer(s.month, 'month', 1, 12);\n if (p.month === 2 && p.dayOfMonth === 29) {\n throw new ScheduleError('schedule_beyond_horizon', 'February 29 exists only in leap years; the next one can be up to 8 years away, beyond the 368-day horizon');\n }\n if (p.dayOfMonth > COMMON_YEAR_DAYS[p.month - 1]!) {\n throw new ScheduleError('schedule_unreachable', `month ${p.month} has no day ${p.dayOfMonth}`);\n }\n }\n }\n return p;\n}\n\n/** Validation only. The Host calls it when it applies create_routine / update_routine. */\nexport function checkRoutineSchedule(schedule: RoutineSchedule): RoutineScheduleCheck {\n try { parse(schedule); return { ok: true }; } catch (e) {\n if (e instanceof ScheduleError) return { ok: false, code: e.code, message: e.message };\n throw e;\n }\n}\n\n/** Local wall-clock fields of an instant, written as a UTC epoch (\"local as UTC\"). */\nfunction localAsUtc(tz: string, instant: number): number {\n const p: Record<string, number> = {};\n for (const part of formatter(tz).formatToParts(instant)) if (part.type !== 'literal') p[part.type] = Number(part.value);\n return Date.UTC(p.year!, p.month! - 1, p.day!, p.hour!, p.minute!, p.second!);\n}\nconst offsetAt = (tz: string, instant: number) => localAsUtc(tz, instant) - Math.floor(instant / 1000) * 1000;\n\n/**\n * Local wall time to instant, as Temporal `disambiguation: 'compatible'`:\n * a repeated time takes the earlier instant; a skipped time moves later by\n * the length of the gap.\n */\nfunction resolve(tz: string, local: number): { instant: number; shifted: boolean } {\n const before = offsetAt(tz, local - DAY_MS);\n const offsets = new Set([before, offsetAt(tz, local), offsetAt(tz, local + DAY_MS)]);\n const valid = [...offsets].map(o => local - o).filter(i => offsetAt(tz, i) === local - i);\n return valid.length ? { instant: Math.min(...valid), shifted: false } : { instant: local - before, shifted: true };\n}\n\nfunction matchesDate(p: Parsed, y: number, m: number, d: number): boolean {\n if (p.days) return p.days.has(UTC_DAY_NAME[new Date(Date.UTC(y, m - 1, d)).getUTCDay()]!);\n if (p.dayOfMonth !== undefined) return d === p.dayOfMonth && (p.month === undefined || m === p.month);\n return true;\n}\n\n/**\n * The first occurrence strictly after `now` (epoch ms): the instant at which\n * the zone's wall clock shows the schedule's whole local minute on a matching\n * date. Null when none falls within ROUTINE_HORIZON_MS. Throws on an invalid\n * schedule.\n *\n * Scan from the local date before `now`; keep the running minimum `best` of\n * candidates after `now`; stop at the first unshifted candidate, because a\n * later local time never resolves earlier. Assumes a gap is at most one day.\n */\nexport function nextRoutineOccurrence(schedule: RoutineSchedule, now: number): number | null {\n if (!Number.isSafeInteger(now) || now < ROUTINE_MIN_NOW || now >= ROUTINE_MAX_NOW) {\n throw new RangeError('now must be a safe integer epoch ms in [2000-01-01, 2200-01-01)');\n }\n let p: Parsed;\n try { p = parse(schedule); } catch (error) {\n if (error instanceof ScheduleError) throw new ByokCoreError('routine_schedule_invalid', error.message);\n throw error;\n }\n const start = localAsUtc(p.tz, now);\n const day0 = Date.UTC(new Date(start).getUTCFullYear(), new Date(start).getUTCMonth(), new Date(start).getUTCDate());\n let best = Infinity;\n for (let k = -1; k <= 368; k += 1) {\n const day = new Date(day0 + k * DAY_MS);\n const y = day.getUTCFullYear(), m = day.getUTCMonth() + 1, d = day.getUTCDate();\n if (!matchesDate(p, y, m, d)) continue;\n const { instant, shifted } = resolve(p.tz, Date.UTC(y, m - 1, d, p.hour, p.minute));\n if (instant <= now) continue;\n best = Math.min(best, instant);\n if (!shifted) break; // a later local time can never resolve earlier than an unshifted one\n }\n return best - now <= ROUTINE_HORIZON_MS ? best : null;\n}\n"]}