chainlesschain 0.166.65 → 0.166.69

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.
Files changed (200) hide show
  1. package/README.md +20 -12
  2. package/package.json +4 -4
  3. package/src/assets/web-panel/assets/{AIOps-Byz17CTN.js → AIOps-FhevRfL6.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-C5LiW2-J.js → ActionButton-rOeOykx5.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-D1INcvZF.js → Analytics-BK_wYlfz.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DZzHO1VV.js → AppLayout-_2cCtZKV.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-WfYQL6Ia.js → Artifacts-D5MSvVzk.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-DohBoGWO.js → Audit-yd-Ah-A3.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-Chtk-Hde.js → BackgroundAgents-yCaw_Gu_.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-B813PuMz.js → Backup-G3ADD4N-.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DaDdWWgK.js → BaseInput-ByDhkLbF.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-D4pJ6oZ7.js → Chat-BMrc7qjz.js} +4 -4
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-nA7n0I6S.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-Clo9TvO6.js → Checkbox-BHYgyZWA.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-uejLg8Ih.js → Codegen-DJfcy0jC.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-B7nbx-iJ.js → Col-C27zROxc.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-FEyjPK1j.js → Community-CuS5tq_1.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-B6Fk0Kn6.js → Compact-BrYJNe7Q.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BQG8goUl.js → Compliance-8hfahYHT.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CbBeEfHp.js → Cowork-DdE0n2lp.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-DPzlFcEZ.js → Cron-CUq3aSiX.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-B8pWJrbg.js → Crosschain-BM4XSPWG.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-gGQHUlFN.js → DID-CdaBY57N.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-C2TMFHrn.js → Dashboard-Cwtd52So.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BVPxGbll.js → Dropdown-BvlObh6U.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-CNPxs0hd.js → EmailListRenderer-e3fLhjnX.js} +1 -1
  27. package/src/assets/web-panel/assets/{EvolutionSettings-_XTiB7q1.js → EvolutionSettings-CTtk1Zo8.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-UyE3VWtI.js → FamilyGuardDashboard-BpPJUnCU.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-CLt6FHK-.js → Federation-vzjZ6_nQ.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-CdNQPRPw.js → FormItemContext-DEDNLhkE.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-BJ0AMhrh.js → GenericCardRenderer-DEl2Te5f.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-CQnvMfOM.js → Git-BzsYQnCq.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-deYsHC-o.js → Governance-zxJs6Y8s.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-qaSck43z.js → Inference-5JUsrmF1.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-De0aJ3Ls.js → KnowledgeGraph-Br8b5Htz.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-ZtS98jCm.js → Logs-D-tubDMJ.js} +2 -2
  37. package/src/assets/web-panel/assets/MarkdownRenderer-In4itZX2.js +1 -0
  38. package/src/assets/web-panel/assets/{Marketplace-Byz3xCBN.js → Marketplace-s8MmWkS9.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-DOZUUW6z.js → McpTools-Wu-WRg4M.js} +3 -3
  40. package/src/assets/web-panel/assets/{Memory-C33wC2hA.js → Memory-B_i-eX9w.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-zZe-T_6M.js → MobileBridge-Ca64kjVx.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-CRnUIume.js → MobileProjects-Cq9AFiO4.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-C1xlRVAN.js → Mtc-DKvGmG3y.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-D0U07bIi.js → MtcAudit-BVvWx8pF.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-DF8uvV3h.js → Multisig-wqeJ2O9x.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-bBPGAFlt.js → NLProgramming-DX87ysYu.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-BHAaOsgg.js → Notes-ChenGdu0.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-Cl0fG_rA.js → NotificationSettings-BZRa68-x.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-BEPAs8Zv.js → OrderTableRenderer-DZ6xG1M6.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-BAxSwgk5.js → Organization-BWJp4VPX.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-D68KubAu.js → Overflow-BoM4bYt5.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-bhdT17zk.js → P2P-Cvi8YV09.js} +2 -2
  53. package/src/assets/web-panel/assets/{PdhVaultBrowser-DqaO6wgH.js → PdhVaultBrowser-CNVC1NIj.js} +3 -3
  54. package/src/assets/web-panel/assets/{Permissions-Bq8fvkak.js → Permissions-DNd1MRjW.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-BYd2JEic.js → PersonalDataHub-DGSBYZ5-.js} +5 -5
  56. package/src/assets/web-panel/assets/{Pipeline-Csg_ja69.js → Pipeline-DkcoGMBo.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-lwxwLj4M.js → Privacy-DltwvMAW.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-BdBZkH8z.js → ProjectInit-ChYbpHg8.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-ClWgFy-K.js → ProjectSettings-B8FWiHTJ.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-Bu-qj8N1.js → Projects-DuyhtSm4.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-DEjxrxw3.js → Providers-Bo18Tx_6.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-eccy-8Vi.js → QrScannerModal-6W85KlsG.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-Vx3uDvFg.js → QuickAsk-DznRUedP.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-CfUivNps.js → Recommend-CQDN3_p-.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-BU4gk7GI.js → RemoteSession-CiJgokEj.js} +3 -3
  66. package/src/assets/web-panel/assets/{Reputation-CbPzdZ0C.js → Reputation-DexzGH7E.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-CYLrgfKA.js → Row-BgZOIvSi.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-DbY1oyuv.js → RssFeed-BWIZJ_Jr.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-QeW41K5r.js → Search-B376EwWJ.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-CJxf1kLZ.js → Security-92mUR5OD.js} +4 -4
  71. package/src/assets/web-panel/assets/{Services-CFO9ySZc.js → Services-ClSEAOHk.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-CQFjeQN0.js → Skeleton-DVhLbv99.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-CLLB4INW.js → Skills-JTcXs_xI.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-DxeLIJk0.js → Sla-DnKY9zy9.js} +1 -1
  75. package/src/assets/web-panel/assets/{SpeechSettings-D4FA9KYI.js → SpeechSettings-GO1JefAH.js} +1 -1
  76. package/src/assets/web-panel/assets/{SyncSettings-C6NOkcQK.js → SyncSettings-jX5tB2St.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-LmVPWDfQ.js → Tasks-BxRBzhUc.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-BdEfUoVB.js → Templates-CAVkbTG1.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-IUlESacN.js → Tenant-5Y7sHBkz.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-B9pDe7sn.js → Terminal-CbbLShYb.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-ZCwB-Pki.js → TimelineRenderer-2HptWihL.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-4qk16LX1.js → Tokens-B-jGxzHl.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-jXNyargn.js → Trigger-9DGa90DT.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-D13PydtT.js → Trust-BSJEkEOO.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-yPgws6mS.js → UkeySign-C807So5R.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-B329WjpG.js → VideoEditing-ByiieAv-.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-T8VM-Ttm.js → Wallet-BixbIOUv.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-XuRibrpP.js → WebAuthn-z7akhor4.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-D1Gwz3YR.js → WorkflowEditor-KvijuUuR.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-DjydtnT-.js → chat-BYKoh0YG.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-gFtBvPrr.js → colors-CLT8IYBt.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-CndxhGfx.js → compact-item-DlBIyYHF.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-DnfGpd0L.js → createContext-5XmAnNLr.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-BmcCIHwY.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-CmT5hRVW.js → hasIn-rPdRhm7K.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-DoBKSzqu.js → index-8un-eUDI.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DGbKeg8G.js → index-B-0nAxf5.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DreYqebI.js → index-B1VfBUPB.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-zQf599Uq.js → index-BBt2CSAx.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BlTcxT_L.js → index-BDtlwjSr.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CqpR0Des.js → index-BIRl2Ii5.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-C3HvYeA3.js → index-BgevTkUv.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-B0WFjxWs.js → index-Bve7Wsgf.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BNHdO6Jr.js → index-Bzd0sFkp.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DV2PR3Fa.js → index-C2sFDVb_.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-D2d7358Y.js → index-CErvHCDe.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DaEPE2DC.js → index-CM_a9spK.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DKyuE_Y2.js → index-CY6TMc2m.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-BVM_w30N.js → index-ChlzaTV3.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CZLDbPTa.js → index-CsnbOKdI.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-HHP1zzo7.js → index-D3-NL-x-.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BFif4Cev.js → index-D3f9Jzx2.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-C14jryXi.js → index-DCDSycWo.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CB27echm.js → index-DIVrVGvf.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BGlmPbl_.js → index-DI_tYFBe.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BsRKmb6k.js → index-DPS4mWnI.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BXNUTiW8.js → index-DTslLzPJ.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dbpk75MO.js → index-DW8vozBS.js} +1 -1
  119. package/src/assets/web-panel/assets/index-DY8rmd6x.js +1 -0
  120. package/src/assets/web-panel/assets/{index-DjY-3sMA.js → index-DZiSMYoD.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-DV6NrfJx.js → index-DZjGcIGU.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-ktN-K1Tf.js → index-Dea32nOK.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DjcR-CwS.js → index-Djd7uqwM.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CuOx4Pbe.js → index-Dntid6oj.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BW3nWiu0.js → index-DqZU4_7J.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-C4Mqhmas.js → index-DuvweiCz.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CRqz8TtI.js → index-DzExCCLS.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-D5na0B7G.js → index-LKT-Ol0A.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-_-wGLtAg.js → index-akwXS-FF.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CgMKElUh.js → index-b-rQCMkx.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DUlubR4l.js → index-eHbr3f5I.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D88-8bsB.js → index-kx6zDWew.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-DuAvYTmY.js → index-rRuCGdKW.js} +1 -1
  134. package/src/assets/web-panel/assets/index-sbwcUeRS.js +1 -0
  135. package/src/assets/web-panel/assets/{initDefaultProps-KV3V-PNH.js → initDefaultProps-a8411LiK.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-PFGQg7_X.js → motion-oVcQdpCm.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-Dnl79wq4.js → move-B-eyzzzL.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-Bwl5JH9V.js → mtc-parser-BCYIxuG7.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-DCcTtM1l.js → omit-DuFtWiYh.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-Cl6BjjDf.js → pickAttrs-CVAoJhGu.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-fdqhyo42.js → placementArrow-Y2iub2bO.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-DYQpmcDW.js → responsiveObserve-BHenWIVD.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-C4l-VfO4.js → slide-CKrMaL29.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-DYDw_dyZ.js → statusUtils-w8eb_1da.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-BEsubSMu.js → styleChecker-CCVi_Ww3.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-Cj82ggQ_.js → useFlexGapSupport-BsmR_q0r.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-B7L1eJ0V.js → useFs-a8GMBjnc.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-DVlJVD4d.js → usePersonalDataHub-BMUYSPn-.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-BBAbRN_Y.js → vnode-DL2pI31V.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-BYn48q-I.js → zoom-Cbi8fISi.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/data/changelog.json +33 -7
  153. package/src/lib/dependency-install-policy.js +1 -1
  154. package/src/lib/evolution/browser-download-action-authority.js +747 -0
  155. package/src/lib/evolution/browser-download-artifact-disposal-authority.js +436 -0
  156. package/src/lib/evolution/browser-filesystem-quarantine-custody.js +2453 -0
  157. package/src/lib/evolution/browser-filesystem-quarantine-disposal.js +36 -0
  158. package/src/lib/evolution/browser-keyboard-action-authority.js +560 -0
  159. package/src/lib/evolution/browser-navigation-action-authority.js +546 -0
  160. package/src/lib/evolution/browser-quarantine-lock-maintenance-authority.js +573 -0
  161. package/src/lib/evolution/browser-quarantine-operator-revocation-authority.js +442 -0
  162. package/src/lib/evolution/browser-quarantine-retention-authority.js +503 -0
  163. package/src/lib/evolution/browser-quarantine-retention-scheduler.js +207 -0
  164. package/src/lib/evolution/browser-quarantined-download-executor.js +525 -0
  165. package/src/lib/evolution/browser-tab-open-action-authority.js +491 -0
  166. package/src/lib/evolution/browser-vision-action-authority.js +444 -0
  167. package/src/lib/evolution/browser-vision-observation-authority.js +304 -0
  168. package/src/lib/evolution/evolution-deployment-loader.js +241 -1
  169. package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +5 -0
  170. package/src/lib/evolution/evolution-eval-gate.js +2 -1
  171. package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +71 -9
  172. package/src/lib/evolution/evolution-eval-process-supervisor.js +276 -9
  173. package/src/lib/evolution/evolution-workbench-metrics.js +81 -21
  174. package/src/lib/evolution/pm-exploration-benchmark.js +747 -0
  175. package/src/lib/evolution/pm-exploration-budget-executor.js +106 -9
  176. package/src/lib/evolution/pm-exploration-egress-authority.js +382 -0
  177. package/src/lib/evolution/pm-exploration-evidence-bundle.js +149 -44
  178. package/src/lib/evolution/pm-exploration-execution-host.js +1254 -8
  179. package/src/lib/evolution/pm-exploration-process-grader.js +458 -0
  180. package/src/lib/evolution/pm-exploration-process-reviewer.js +456 -0
  181. package/src/lib/evolution/pm-exploration-process-runner.js +500 -0
  182. package/src/lib/evolution/pm-exploration-receipts.js +211 -11
  183. package/src/lib/evolution/pm-exploration-recovery-snapshot-store.js +465 -46
  184. package/src/lib/evolution/pm-exploration-transition-committer.js +185 -34
  185. package/src/lib/evolution/skill-outcome-index-authority.js +7 -3
  186. package/src/lib/evolution/skill-writer-inventory-manifest.js +0 -39
  187. package/src/lib/evolution/volcengine-function-execution-authority.js +2949 -0
  188. package/src/lib/evolution/volcengine-function-process-executor.js +615 -0
  189. package/src/lib/evolution/volcengine-function-replay-store.js +836 -0
  190. package/src/lib/evolution/volcengine-function-revocation-status-floor-store.js +480 -0
  191. package/src/lib/governance-coverage.js +1 -1
  192. package/src/lib/headless-manifest.js +1 -1
  193. package/src/lib/protocol-replay.js +1 -1
  194. package/src/lib/skill-outcome-transcript-authority.js +45 -5
  195. package/src/runtime/agent-core.js +17 -0
  196. package/src/assets/web-panel/assets/ChatBubbleRenderer-Cf3LLgDc.js +0 -1
  197. package/src/assets/web-panel/assets/MarkdownRenderer-CTsYo9NN.js +0 -1
  198. package/src/assets/web-panel/assets/devWarning-D60SbiD-.js +0 -1
  199. package/src/assets/web-panel/assets/index-C0yR4_7h.js +0 -1
  200. package/src/assets/web-panel/assets/index-D4xuvo03.js +0 -1
@@ -13,6 +13,12 @@ export const PM_EXPLORATION_RECOVERY_SNAPSHOT_REQUEST_SCHEMA =
13
13
  "chainlesschain.pm-exploration-recovery-snapshot-request/v1";
14
14
  export const PM_EXPLORATION_RECOVERY_SNAPSHOT_ACK_SCHEMA =
15
15
  "chainlesschain.pm-exploration-recovery-snapshot-ack/v1";
16
+ export const PM_EXPLORATION_RECOVERY_SET_REQUEST_SCHEMA =
17
+ "chainlesschain.pm-exploration-recovery-snapshot-request/v2";
18
+ export const PM_EXPLORATION_RECOVERY_SET_ACK_SCHEMA =
19
+ "chainlesschain.pm-exploration-recovery-snapshot-ack/v2";
20
+ export const PM_EXPLORATION_RECOVERY_SNAPSHOT_RESOLUTION_SCHEMA =
21
+ "chainlesschain.pm-exploration-recovery-snapshot-resolution/v1";
16
22
  export const PM_EXPLORATION_RECOVERY_SNAPSHOT_CORRUPT_CODE =
17
23
  "CC_PM_RECOVERY_SNAPSHOT_CORRUPT";
18
24
 
@@ -20,10 +26,17 @@ const DATABASE_SEAL_SCHEMA =
20
26
  "chainlesschain.desktop-pm-database-pre-run-seal/v1";
21
27
  const DATABASE_SNAPSHOT_DOMAIN =
22
28
  "chainlesschain.desktop-pm-database-snapshot/v1";
29
+ const WORKSPACE_SEAL_SCHEMA = "chainlesschain.desktop-pm-workspace-seal/v1";
30
+ const WORKSPACE_SNAPSHOT_DOMAIN =
31
+ "chainlesschain.desktop-pm-workspace-snapshot/v1";
32
+ const RECOVERY_SET_SCHEMA = "chainlesschain.pm-exploration-recovery-set/v1";
33
+ const RECOVERY_SET_MAGIC = Buffer.from("CCPMRECOVERYSET1\0", "ascii");
23
34
  const SNAPSHOT_TYPE = "pm-exploration-database-recovery-snapshot";
35
+ const RECOVERY_SET_TYPE = "pm-exploration-recovery-set";
24
36
  const DIGEST = /^sha256:[a-f0-9]{64}$/u;
25
37
  const ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
26
38
  const MAX_SNAPSHOT_BYTES = 8 * 1024 * 1024 * 1024;
39
+ const MAX_WORKSPACE_SNAPSHOT_BYTES = 2 * 1024 * 1024 * 1024;
27
40
  const STORES = new WeakMap();
28
41
 
29
42
  function canonical(value) {
@@ -146,7 +159,65 @@ function databaseSeal(value) {
146
159
  return seal;
147
160
  }
148
161
 
149
- function snapshotBytes(value) {
162
+ function workspaceSeal(value, expectedManifestDigest) {
163
+ exact(
164
+ value,
165
+ [
166
+ "schema",
167
+ "manifestDigest",
168
+ "workspaceRootDigest",
169
+ "capturePolicyDigest",
170
+ "workspaceSnapshotDigest",
171
+ "workspaceSnapshotBytes",
172
+ "workspaceFileCount",
173
+ "snapshotMethod",
174
+ "sealDigest",
175
+ ],
176
+ "PM recovery workspace seal",
177
+ );
178
+ if (
179
+ value.schema !== WORKSPACE_SEAL_SCHEMA ||
180
+ value.manifestDigest !== expectedManifestDigest ||
181
+ value.snapshotMethod !== "bounded-canonical-workspace-archive" ||
182
+ !Number.isSafeInteger(value.workspaceSnapshotBytes) ||
183
+ value.workspaceSnapshotBytes < 1 ||
184
+ value.workspaceSnapshotBytes > MAX_WORKSPACE_SNAPSHOT_BYTES ||
185
+ !Number.isSafeInteger(value.workspaceFileCount) ||
186
+ value.workspaceFileCount < 0 ||
187
+ value.workspaceFileCount > 100_000
188
+ ) {
189
+ throw new TypeError("PM recovery workspace seal is invalid");
190
+ }
191
+ const core = {
192
+ schema: value.schema,
193
+ manifestDigest: digest(value.manifestDigest, "manifestDigest"),
194
+ workspaceRootDigest: digest(
195
+ value.workspaceRootDigest,
196
+ "workspaceRootDigest",
197
+ ),
198
+ capturePolicyDigest: digest(
199
+ value.capturePolicyDigest,
200
+ "capturePolicyDigest",
201
+ ),
202
+ workspaceSnapshotDigest: digest(
203
+ value.workspaceSnapshotDigest,
204
+ "workspaceSnapshotDigest",
205
+ ),
206
+ workspaceSnapshotBytes: value.workspaceSnapshotBytes,
207
+ workspaceFileCount: value.workspaceFileCount,
208
+ snapshotMethod: value.snapshotMethod,
209
+ };
210
+ const seal = deepFreeze({
211
+ ...core,
212
+ sealDigest: digest(value.sealDigest, "workspace sealDigest"),
213
+ });
214
+ if (seal.sealDigest !== hash(WORKSPACE_SEAL_SCHEMA, core)) {
215
+ throw new Error("PM recovery workspace seal digest mismatch");
216
+ }
217
+ return seal;
218
+ }
219
+
220
+ function snapshotBytes(value, maximum = MAX_SNAPSHOT_BYTES) {
150
221
  if (
151
222
  !value ||
152
223
  typeof value !== "object" ||
@@ -160,11 +231,139 @@ function snapshotBytes(value) {
160
231
  ) {
161
232
  throw new TypeError("PM recovery snapshot bytes are invalid");
162
233
  }
163
- if (value.byteLength < 1 || value.byteLength > MAX_SNAPSHOT_BYTES)
234
+ if (value.byteLength < 1 || value.byteLength > maximum)
164
235
  throw new TypeError("PM recovery snapshot bytes exceed the allowed range");
165
236
  return Buffer.from(value);
166
237
  }
167
238
 
239
+ function boundedSnapshotBytes(value, maximum, label) {
240
+ try {
241
+ return snapshotBytes(value, maximum);
242
+ } catch (cause) {
243
+ throw new TypeError(`${label} bytes exceed the allowed range`, { cause });
244
+ }
245
+ }
246
+
247
+ function encodeRecoverySet(request) {
248
+ const header = Buffer.from(
249
+ canonical({
250
+ schema: RECOVERY_SET_SCHEMA,
251
+ databaseSeal: request.seal,
252
+ workspaceSeal: request.workspaceSeal,
253
+ }),
254
+ "utf8",
255
+ );
256
+ if (header.byteLength > 1024 * 1024) {
257
+ throw new TypeError("PM recovery set header exceeds the allowed range");
258
+ }
259
+ const prefix = Buffer.allocUnsafe(20);
260
+ prefix.writeUInt32BE(header.byteLength, 0);
261
+ prefix.writeBigUInt64BE(BigInt(request.bytes.byteLength), 4);
262
+ prefix.writeBigUInt64BE(BigInt(request.workspaceBytes.byteLength), 12);
263
+ return Buffer.concat([
264
+ RECOVERY_SET_MAGIC,
265
+ prefix,
266
+ header,
267
+ request.bytes,
268
+ request.workspaceBytes,
269
+ ]);
270
+ }
271
+
272
+ function decodeRecoverySet(value, acknowledgement, manifestDigest) {
273
+ const bytes = snapshotBytes(
274
+ value,
275
+ MAX_SNAPSHOT_BYTES + MAX_WORKSPACE_SNAPSHOT_BYTES + 1024 * 1024,
276
+ );
277
+ const prefixOffset = RECOVERY_SET_MAGIC.byteLength;
278
+ const headerOffset = prefixOffset + 20;
279
+ if (
280
+ bytes.byteLength < headerOffset ||
281
+ !bytes.subarray(0, prefixOffset).equals(RECOVERY_SET_MAGIC)
282
+ ) {
283
+ corrupt("PM recovery set magic is invalid");
284
+ }
285
+ const headerLength = bytes.readUInt32BE(prefixOffset);
286
+ const databaseLength = bytes.readBigUInt64BE(prefixOffset + 4);
287
+ const workspaceLength = bytes.readBigUInt64BE(prefixOffset + 12);
288
+ if (
289
+ headerLength < 1 ||
290
+ headerLength > 1024 * 1024 ||
291
+ databaseLength < 1n ||
292
+ databaseLength > BigInt(MAX_SNAPSHOT_BYTES) ||
293
+ workspaceLength < 1n ||
294
+ workspaceLength > BigInt(MAX_WORKSPACE_SNAPSHOT_BYTES) ||
295
+ databaseLength > BigInt(Number.MAX_SAFE_INTEGER) ||
296
+ workspaceLength > BigInt(Number.MAX_SAFE_INTEGER)
297
+ ) {
298
+ corrupt("PM recovery set lengths are invalid");
299
+ }
300
+ const databaseBytesLength = Number(databaseLength);
301
+ const workspaceBytesLength = Number(workspaceLength);
302
+ const databaseOffset = headerOffset + headerLength;
303
+ const workspaceOffset = databaseOffset + databaseBytesLength;
304
+ if (workspaceOffset + workspaceBytesLength !== bytes.byteLength) {
305
+ corrupt("PM recovery set length binding is invalid");
306
+ }
307
+ const headerText = bytes
308
+ .subarray(headerOffset, databaseOffset)
309
+ .toString("utf8");
310
+ let header;
311
+ try {
312
+ header = JSON.parse(headerText);
313
+ } catch (cause) {
314
+ corrupt("PM recovery set header is invalid JSON", { cause });
315
+ }
316
+ if (canonical(header) !== headerText) {
317
+ corrupt("PM recovery set header is not canonical");
318
+ }
319
+ exact(
320
+ header,
321
+ ["schema", "databaseSeal", "workspaceSeal"],
322
+ "PM recovery set header",
323
+ );
324
+ if (header.schema !== RECOVERY_SET_SCHEMA) {
325
+ corrupt("PM recovery set schema is invalid");
326
+ }
327
+ const normalizedDatabaseSeal = databaseSeal(header.databaseSeal);
328
+ const normalizedWorkspaceSeal = workspaceSeal(
329
+ header.workspaceSeal,
330
+ manifestDigest,
331
+ );
332
+ const databaseBytes = Buffer.from(
333
+ bytes.subarray(databaseOffset, workspaceOffset),
334
+ );
335
+ const workspaceBytes = Buffer.from(bytes.subarray(workspaceOffset));
336
+ if (
337
+ normalizedDatabaseSeal.sealDigest !== acknowledgement.sealDigest ||
338
+ normalizedDatabaseSeal.databaseSnapshotDigest !==
339
+ acknowledgement.databaseSnapshotDigest ||
340
+ normalizedDatabaseSeal.databaseSnapshotBytes !== databaseBytesLength ||
341
+ normalizedWorkspaceSeal.sealDigest !==
342
+ acknowledgement.workspaceSealDigest ||
343
+ normalizedWorkspaceSeal.workspaceRootDigest !==
344
+ acknowledgement.workspaceRootDigest ||
345
+ normalizedWorkspaceSeal.capturePolicyDigest !==
346
+ acknowledgement.capturePolicyDigest ||
347
+ normalizedWorkspaceSeal.workspaceSnapshotDigest !==
348
+ acknowledgement.workspaceSnapshotDigest ||
349
+ normalizedWorkspaceSeal.workspaceSnapshotBytes !== workspaceBytesLength ||
350
+ normalizedWorkspaceSeal.workspaceFileCount !==
351
+ acknowledgement.workspaceFileCount ||
352
+ hashBytes(databaseBytes, DATABASE_SNAPSHOT_DOMAIN) !==
353
+ normalizedDatabaseSeal.databaseSnapshotDigest ||
354
+ hashBytes(workspaceBytes, WORKSPACE_SNAPSHOT_DOMAIN) !==
355
+ normalizedWorkspaceSeal.workspaceSnapshotDigest
356
+ ) {
357
+ corrupt("PM recovery set contents differ from its acknowledgement");
358
+ }
359
+ return {
360
+ databaseSeal: normalizedDatabaseSeal,
361
+ databaseBytes,
362
+ workspaceSeal: normalizedWorkspaceSeal,
363
+ workspaceBytes,
364
+ };
365
+ }
366
+
168
367
  function captureAuthority(value) {
169
368
  exact(
170
369
  value,
@@ -225,23 +424,40 @@ function validateAuthorityReceipt(value, binding, authorityId, schema, label) {
225
424
  }
226
425
 
227
426
  function normalizeRequest(value, expectedManifestDigest) {
427
+ const composite =
428
+ value?.schema === PM_EXPLORATION_RECOVERY_SET_REQUEST_SCHEMA;
228
429
  exact(
229
430
  value,
230
- [
231
- "schema",
232
- "manifestDigest",
233
- "transitionKind",
234
- "snapshotRole",
235
- "evidenceDigest",
236
- "seal",
237
- "bytes",
238
- ],
431
+ composite
432
+ ? [
433
+ "schema",
434
+ "manifestDigest",
435
+ "transitionKind",
436
+ "snapshotRole",
437
+ "evidenceDigest",
438
+ "seal",
439
+ "bytes",
440
+ "workspaceSeal",
441
+ "workspaceBytes",
442
+ ]
443
+ : [
444
+ "schema",
445
+ "manifestDigest",
446
+ "transitionKind",
447
+ "snapshotRole",
448
+ "evidenceDigest",
449
+ "seal",
450
+ "bytes",
451
+ ],
239
452
  "PM recovery snapshot request",
240
453
  );
241
454
  const expectedRole =
242
455
  value.transitionKind === "success" ? "post-run" : "pre-run";
243
456
  if (
244
- value.schema !== PM_EXPLORATION_RECOVERY_SNAPSHOT_REQUEST_SCHEMA ||
457
+ ![
458
+ PM_EXPLORATION_RECOVERY_SNAPSHOT_REQUEST_SCHEMA,
459
+ PM_EXPLORATION_RECOVERY_SET_REQUEST_SCHEMA,
460
+ ].includes(value.schema) ||
245
461
  value.manifestDigest !== expectedManifestDigest ||
246
462
  !["success", "failure"].includes(value.transitionKind) ||
247
463
  value.snapshotRole !== expectedRole
@@ -256,19 +472,44 @@ function normalizeRequest(value, expectedManifestDigest) {
256
472
  ) {
257
473
  corrupt("PM recovery snapshot bytes differ from the database seal");
258
474
  }
475
+ const normalizedWorkspaceSeal = composite
476
+ ? workspaceSeal(value.workspaceSeal, expectedManifestDigest)
477
+ : null;
478
+ const workspaceBytes = composite
479
+ ? boundedSnapshotBytes(
480
+ value.workspaceBytes,
481
+ MAX_WORKSPACE_SNAPSHOT_BYTES,
482
+ "PM recovery workspace snapshot",
483
+ )
484
+ : null;
485
+ if (
486
+ composite &&
487
+ (normalizedWorkspaceSeal.workspaceSnapshotBytes !==
488
+ workspaceBytes.byteLength ||
489
+ normalizedWorkspaceSeal.workspaceSnapshotDigest !==
490
+ hashBytes(workspaceBytes, WORKSPACE_SNAPSHOT_DOMAIN))
491
+ ) {
492
+ corrupt("PM recovery workspace bytes differ from the workspace seal");
493
+ }
259
494
  return {
495
+ schema: value.schema,
260
496
  manifestDigest: expectedManifestDigest,
261
497
  transitionKind: value.transitionKind,
262
498
  snapshotRole: value.snapshotRole,
263
499
  evidenceDigest: digest(value.evidenceDigest, "evidenceDigest"),
264
500
  seal,
265
501
  bytes,
502
+ workspaceSeal: normalizedWorkspaceSeal,
503
+ workspaceBytes,
266
504
  };
267
505
  }
268
506
 
269
507
  function ackCore(binding, request, authorityId, durabilityReceiptDigest) {
270
- return {
271
- schema: PM_EXPLORATION_RECOVERY_SNAPSHOT_ACK_SCHEMA,
508
+ const core = {
509
+ schema:
510
+ request.workspaceSeal === null
511
+ ? PM_EXPLORATION_RECOVERY_SNAPSHOT_ACK_SCHEMA
512
+ : PM_EXPLORATION_RECOVERY_SET_ACK_SCHEMA,
272
513
  authenticated: true,
273
514
  durable: true,
274
515
  readbackVerified: true,
@@ -285,6 +526,16 @@ function ackCore(binding, request, authorityId, durabilityReceiptDigest) {
285
526
  durabilityReceiptDigest,
286
527
  qualifiesForPromotion: false,
287
528
  };
529
+ if (request.workspaceSeal !== null) {
530
+ core.workspaceSealDigest = request.workspaceSeal.sealDigest;
531
+ core.workspaceRootDigest = request.workspaceSeal.workspaceRootDigest;
532
+ core.capturePolicyDigest = request.workspaceSeal.capturePolicyDigest;
533
+ core.workspaceSnapshotDigest =
534
+ request.workspaceSeal.workspaceSnapshotDigest;
535
+ core.workspaceSnapshotBytes = request.workspaceSeal.workspaceSnapshotBytes;
536
+ core.workspaceFileCount = request.workspaceSeal.workspaceFileCount;
537
+ }
538
+ return core;
288
539
  }
289
540
 
290
541
  export function verifyPmExplorationRecoverySnapshotAck(value, expected = {}) {
@@ -302,6 +553,7 @@ export function verifyPmExplorationRecoverySnapshotAck(value, expected = {}) {
302
553
  "transitionKind",
303
554
  "evidenceDigest",
304
555
  "sealDigest",
556
+ "workspaceSealDigest",
305
557
  ]);
306
558
  for (const key of Reflect.ownKeys(expected)) {
307
559
  const descriptor = Object.getOwnPropertyDescriptor(expected, key);
@@ -317,27 +569,54 @@ export function verifyPmExplorationRecoverySnapshotAck(value, expected = {}) {
317
569
  );
318
570
  }
319
571
  }
572
+ const composite = value?.schema === PM_EXPLORATION_RECOVERY_SET_ACK_SCHEMA;
320
573
  exact(
321
574
  value,
322
- [
323
- "schema",
324
- "authenticated",
325
- "durable",
326
- "readbackVerified",
327
- "manifestDigest",
328
- "transitionKind",
329
- "snapshotRole",
330
- "evidenceDigest",
331
- "sealDigest",
332
- "databaseSnapshotDigest",
333
- "databaseSnapshotBytes",
334
- "artifactDigest",
335
- "artifactRef",
336
- "durabilityAuthorityId",
337
- "durabilityReceiptDigest",
338
- "qualifiesForPromotion",
339
- "snapshotAckDigest",
340
- ],
575
+ composite
576
+ ? [
577
+ "schema",
578
+ "authenticated",
579
+ "durable",
580
+ "readbackVerified",
581
+ "manifestDigest",
582
+ "transitionKind",
583
+ "snapshotRole",
584
+ "evidenceDigest",
585
+ "sealDigest",
586
+ "databaseSnapshotDigest",
587
+ "databaseSnapshotBytes",
588
+ "workspaceSealDigest",
589
+ "workspaceRootDigest",
590
+ "capturePolicyDigest",
591
+ "workspaceSnapshotDigest",
592
+ "workspaceSnapshotBytes",
593
+ "workspaceFileCount",
594
+ "artifactDigest",
595
+ "artifactRef",
596
+ "durabilityAuthorityId",
597
+ "durabilityReceiptDigest",
598
+ "qualifiesForPromotion",
599
+ "snapshotAckDigest",
600
+ ]
601
+ : [
602
+ "schema",
603
+ "authenticated",
604
+ "durable",
605
+ "readbackVerified",
606
+ "manifestDigest",
607
+ "transitionKind",
608
+ "snapshotRole",
609
+ "evidenceDigest",
610
+ "sealDigest",
611
+ "databaseSnapshotDigest",
612
+ "databaseSnapshotBytes",
613
+ "artifactDigest",
614
+ "artifactRef",
615
+ "durabilityAuthorityId",
616
+ "durabilityReceiptDigest",
617
+ "qualifiesForPromotion",
618
+ "snapshotAckDigest",
619
+ ],
341
620
  "PM recovery snapshot acknowledgement",
342
621
  );
343
622
  const core = {
@@ -367,8 +646,31 @@ export function verifyPmExplorationRecoverySnapshotAck(value, expected = {}) {
367
646
  ),
368
647
  qualifiesForPromotion: value.qualifiesForPromotion,
369
648
  };
649
+ if (composite) {
650
+ core.workspaceSealDigest = digest(
651
+ value.workspaceSealDigest,
652
+ "workspaceSealDigest",
653
+ );
654
+ core.workspaceRootDigest = digest(
655
+ value.workspaceRootDigest,
656
+ "workspaceRootDigest",
657
+ );
658
+ core.capturePolicyDigest = digest(
659
+ value.capturePolicyDigest,
660
+ "capturePolicyDigest",
661
+ );
662
+ core.workspaceSnapshotDigest = digest(
663
+ value.workspaceSnapshotDigest,
664
+ "workspaceSnapshotDigest",
665
+ );
666
+ core.workspaceSnapshotBytes = value.workspaceSnapshotBytes;
667
+ core.workspaceFileCount = value.workspaceFileCount;
668
+ }
370
669
  if (
371
- core.schema !== PM_EXPLORATION_RECOVERY_SNAPSHOT_ACK_SCHEMA ||
670
+ ![
671
+ PM_EXPLORATION_RECOVERY_SNAPSHOT_ACK_SCHEMA,
672
+ PM_EXPLORATION_RECOVERY_SET_ACK_SCHEMA,
673
+ ].includes(core.schema) ||
372
674
  core.authenticated !== true ||
373
675
  core.durable !== true ||
374
676
  core.readbackVerified !== true ||
@@ -378,15 +680,28 @@ export function verifyPmExplorationRecoverySnapshotAck(value, expected = {}) {
378
680
  !Number.isSafeInteger(core.databaseSnapshotBytes) ||
379
681
  core.databaseSnapshotBytes < 1 ||
380
682
  core.databaseSnapshotBytes > MAX_SNAPSHOT_BYTES ||
683
+ (composite &&
684
+ (!Number.isSafeInteger(core.workspaceSnapshotBytes) ||
685
+ core.workspaceSnapshotBytes < 1 ||
686
+ core.workspaceSnapshotBytes > MAX_WORKSPACE_SNAPSHOT_BYTES ||
687
+ !Number.isSafeInteger(core.workspaceFileCount) ||
688
+ core.workspaceFileCount < 0 ||
689
+ core.workspaceFileCount > 100_000)) ||
381
690
  core.qualifiesForPromotion !== false
382
691
  ) {
383
692
  throw new Error("PM recovery snapshot acknowledgement is invalid");
384
693
  }
694
+ if (expected.workspaceSealDigest !== undefined && !composite) {
695
+ throw new Error(
696
+ "PM recovery snapshot acknowledgement workspaceSealDigest mismatch",
697
+ );
698
+ }
385
699
  for (const key of [
386
700
  "manifestDigest",
387
701
  "transitionKind",
388
702
  "evidenceDigest",
389
703
  "sealDigest",
704
+ ...(composite ? ["workspaceSealDigest"] : []),
390
705
  ]) {
391
706
  if (expected[key] !== undefined && core[key] !== expected[key])
392
707
  throw new Error(`PM recovery snapshot acknowledgement ${key} mismatch`);
@@ -395,10 +710,7 @@ export function verifyPmExplorationRecoverySnapshotAck(value, expected = {}) {
395
710
  value.snapshotAckDigest,
396
711
  "snapshotAckDigest",
397
712
  );
398
- if (
399
- snapshotAckDigest !==
400
- hash(PM_EXPLORATION_RECOVERY_SNAPSHOT_ACK_SCHEMA, core)
401
- ) {
713
+ if (snapshotAckDigest !== hash(core.schema, core)) {
402
714
  throw new Error("PM recovery snapshot acknowledgement digest mismatch");
403
715
  }
404
716
  return deepFreeze({ ...core, snapshotAckDigest });
@@ -433,7 +745,11 @@ export function capturePmExplorationRecoverySnapshotStore(value) {
433
745
  manifestDigest: captured.manifestDigest,
434
746
  retainTransitionSnapshot: (input) => {
435
747
  const request = normalizeRequest(input, captured.manifestDigest);
436
- const artifactDigest = hashBytes(request.bytes);
748
+ const artifactBytes =
749
+ request.workspaceBytes === null
750
+ ? request.bytes
751
+ : encodeRecoverySet(request);
752
+ const artifactDigest = hashBytes(artifactBytes);
437
753
  const binding = deepFreeze({
438
754
  artifactTenantId: captured.artifactTenantId,
439
755
  digest: artifactDigest,
@@ -441,12 +757,13 @@ export function capturePmExplorationRecoverySnapshotStore(value) {
441
757
  ref: `cc-pm-recovery-snapshot:${request.manifestDigest.slice(7)}:${request.evidenceDigest.slice(7)}:${request.snapshotRole}`,
442
758
  retention: "ledger",
443
759
  schema: EVOLUTION_ARTIFACT_DURABILITY_BINDING_SCHEMA,
444
- type: SNAPSHOT_TYPE,
760
+ type:
761
+ request.workspaceBytes === null ? SNAPSHOT_TYPE : RECOVERY_SET_TYPE,
445
762
  });
446
763
  const retained = captured.authority.retain(
447
764
  Object.freeze({
448
765
  binding,
449
- bytes: Buffer.from(request.bytes),
766
+ bytes: Buffer.from(artifactBytes),
450
767
  schema: EVOLUTION_ARTIFACT_DURABILITY_RETAIN_REQUEST_SCHEMA,
451
768
  }),
452
769
  );
@@ -500,8 +817,11 @@ export function capturePmExplorationRecoverySnapshotStore(value) {
500
817
  EVOLUTION_ARTIFACT_DURABILITY_RESOLUTION_SCHEMA,
501
818
  "PM recovery snapshot durability resolution",
502
819
  );
503
- const readback = snapshotBytes(resolved.bytes);
504
- if (!readback.equals(request.bytes))
820
+ const readback = snapshotBytes(
821
+ resolved.bytes,
822
+ MAX_SNAPSHOT_BYTES + MAX_WORKSPACE_SNAPSHOT_BYTES + 1024 * 1024,
823
+ );
824
+ if (!readback.equals(artifactBytes))
505
825
  corrupt("PM recovery snapshot durability readback differs");
506
826
  const core = ackCore(
507
827
  binding,
@@ -511,10 +831,109 @@ export function capturePmExplorationRecoverySnapshotStore(value) {
511
831
  );
512
832
  return deepFreeze({
513
833
  ...core,
514
- snapshotAckDigest: hash(
515
- PM_EXPLORATION_RECOVERY_SNAPSHOT_ACK_SCHEMA,
516
- core,
834
+ snapshotAckDigest: hash(core.schema, core),
835
+ });
836
+ },
837
+ resolveTransitionSnapshot: (input) => {
838
+ const acknowledgement = verifyPmExplorationRecoverySnapshotAck(input, {
839
+ manifestDigest: captured.manifestDigest,
840
+ });
841
+ const composite =
842
+ acknowledgement.schema === PM_EXPLORATION_RECOVERY_SET_ACK_SCHEMA;
843
+ const binding = deepFreeze({
844
+ artifactTenantId: captured.artifactTenantId,
845
+ digest: acknowledgement.artifactDigest,
846
+ purpose: captured.purpose,
847
+ ref: acknowledgement.artifactRef,
848
+ retention: "ledger",
849
+ schema: EVOLUTION_ARTIFACT_DURABILITY_BINDING_SCHEMA,
850
+ type: composite ? RECOVERY_SET_TYPE : SNAPSHOT_TYPE,
851
+ });
852
+ const resolved = captured.authority.resolve(
853
+ Object.freeze({
854
+ artifactTenantId: binding.artifactTenantId,
855
+ digest: binding.digest,
856
+ purpose: binding.purpose,
857
+ ref: binding.ref,
858
+ retention: binding.retention,
859
+ schema: EVOLUTION_ARTIFACT_DURABILITY_RESOLVE_REQUEST_SCHEMA,
860
+ }),
861
+ );
862
+ if (isPromise(resolved)) {
863
+ corrupt("PM recovery snapshot resolve must be synchronous");
864
+ }
865
+ exact(
866
+ resolved,
867
+ [
868
+ "schema",
869
+ "authenticated",
870
+ "durable",
871
+ "authorityId",
872
+ "artifactTenantId",
873
+ "digest",
874
+ "purpose",
875
+ "ref",
876
+ "retention",
877
+ "type",
878
+ "receiptDigest",
879
+ "bytes",
880
+ ],
881
+ "PM recovery snapshot durability resolution",
882
+ );
883
+ validateAuthorityReceipt(
884
+ Object.fromEntries(
885
+ Reflect.ownKeys(resolved)
886
+ .filter((key) => key !== "bytes")
887
+ .map((key) => [key, resolved[key]]),
517
888
  ),
889
+ binding,
890
+ captured.authority.id,
891
+ EVOLUTION_ARTIFACT_DURABILITY_RESOLUTION_SCHEMA,
892
+ "PM recovery snapshot durability resolution",
893
+ );
894
+ const artifactBytes = snapshotBytes(
895
+ resolved.bytes,
896
+ MAX_SNAPSHOT_BYTES + MAX_WORKSPACE_SNAPSHOT_BYTES + 1024 * 1024,
897
+ );
898
+ if (hashBytes(artifactBytes) !== acknowledgement.artifactDigest) {
899
+ corrupt("PM recovery snapshot resolution digest mismatch");
900
+ }
901
+ const decoded = composite
902
+ ? decodeRecoverySet(
903
+ artifactBytes,
904
+ acknowledgement,
905
+ captured.manifestDigest,
906
+ )
907
+ : {
908
+ databaseSeal: null,
909
+ databaseBytes: artifactBytes,
910
+ workspaceSeal: null,
911
+ workspaceBytes: null,
912
+ };
913
+ if (
914
+ decoded.databaseBytes.byteLength !==
915
+ acknowledgement.databaseSnapshotBytes ||
916
+ hashBytes(decoded.databaseBytes, DATABASE_SNAPSHOT_DOMAIN) !==
917
+ acknowledgement.databaseSnapshotDigest
918
+ ) {
919
+ corrupt("PM recovery database snapshot resolution is invalid");
920
+ }
921
+ return Object.freeze({
922
+ schema: PM_EXPLORATION_RECOVERY_SNAPSHOT_RESOLUTION_SCHEMA,
923
+ authenticated: true,
924
+ durable: true,
925
+ readbackVerified: true,
926
+ manifestDigest: captured.manifestDigest,
927
+ acknowledgement,
928
+ databaseSeal: decoded.databaseSeal,
929
+ databaseBytes: Buffer.from(decoded.databaseBytes),
930
+ workspaceSeal: decoded.workspaceSeal,
931
+ workspaceBytes:
932
+ decoded.workspaceBytes === null
933
+ ? null
934
+ : Buffer.from(decoded.workspaceBytes),
935
+ durabilityReceiptDigest: resolved.receiptDigest,
936
+ qualifiesForPromotion: false,
518
937
  });
519
938
  },
520
939
  });