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.
- package/README.md +20 -12
- package/package.json +4 -4
- package/src/assets/web-panel/assets/{AIOps-Byz17CTN.js → AIOps-FhevRfL6.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C5LiW2-J.js → ActionButton-rOeOykx5.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D1INcvZF.js → Analytics-BK_wYlfz.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DZzHO1VV.js → AppLayout-_2cCtZKV.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-WfYQL6Ia.js → Artifacts-D5MSvVzk.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DohBoGWO.js → Audit-yd-Ah-A3.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Chtk-Hde.js → BackgroundAgents-yCaw_Gu_.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-B813PuMz.js → Backup-G3ADD4N-.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DaDdWWgK.js → BaseInput-ByDhkLbF.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D4pJ6oZ7.js → Chat-BMrc7qjz.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-nA7n0I6S.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Clo9TvO6.js → Checkbox-BHYgyZWA.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-uejLg8Ih.js → Codegen-DJfcy0jC.js} +1 -1
- package/src/assets/web-panel/assets/{Col-B7nbx-iJ.js → Col-C27zROxc.js} +1 -1
- package/src/assets/web-panel/assets/{Community-FEyjPK1j.js → Community-CuS5tq_1.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B6Fk0Kn6.js → Compact-BrYJNe7Q.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BQG8goUl.js → Compliance-8hfahYHT.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CbBeEfHp.js → Cowork-DdE0n2lp.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DPzlFcEZ.js → Cron-CUq3aSiX.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B8pWJrbg.js → Crosschain-BM4XSPWG.js} +1 -1
- package/src/assets/web-panel/assets/{DID-gGQHUlFN.js → DID-CdaBY57N.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-C2TMFHrn.js → Dashboard-Cwtd52So.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BVPxGbll.js → Dropdown-BvlObh6U.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CNPxs0hd.js → EmailListRenderer-e3fLhjnX.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-_XTiB7q1.js → EvolutionSettings-CTtk1Zo8.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-UyE3VWtI.js → FamilyGuardDashboard-BpPJUnCU.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CLt6FHK-.js → Federation-vzjZ6_nQ.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CdNQPRPw.js → FormItemContext-DEDNLhkE.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BJ0AMhrh.js → GenericCardRenderer-DEl2Te5f.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CQnvMfOM.js → Git-BzsYQnCq.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-deYsHC-o.js → Governance-zxJs6Y8s.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-qaSck43z.js → Inference-5JUsrmF1.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-De0aJ3Ls.js → KnowledgeGraph-Br8b5Htz.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-ZtS98jCm.js → Logs-D-tubDMJ.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-In4itZX2.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Byz3xCBN.js → Marketplace-s8MmWkS9.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DOZUUW6z.js → McpTools-Wu-WRg4M.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-C33wC2hA.js → Memory-B_i-eX9w.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-zZe-T_6M.js → MobileBridge-Ca64kjVx.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CRnUIume.js → MobileProjects-Cq9AFiO4.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-C1xlRVAN.js → Mtc-DKvGmG3y.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-D0U07bIi.js → MtcAudit-BVvWx8pF.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DF8uvV3h.js → Multisig-wqeJ2O9x.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-bBPGAFlt.js → NLProgramming-DX87ysYu.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BHAaOsgg.js → Notes-ChenGdu0.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-Cl0fG_rA.js → NotificationSettings-BZRa68-x.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BEPAs8Zv.js → OrderTableRenderer-DZ6xG1M6.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BAxSwgk5.js → Organization-BWJp4VPX.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-D68KubAu.js → Overflow-BoM4bYt5.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-bhdT17zk.js → P2P-Cvi8YV09.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DqaO6wgH.js → PdhVaultBrowser-CNVC1NIj.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-Bq8fvkak.js → Permissions-DNd1MRjW.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BYd2JEic.js → PersonalDataHub-DGSBYZ5-.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-Csg_ja69.js → Pipeline-DkcoGMBo.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-lwxwLj4M.js → Privacy-DltwvMAW.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BdBZkH8z.js → ProjectInit-ChYbpHg8.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-ClWgFy-K.js → ProjectSettings-B8FWiHTJ.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Bu-qj8N1.js → Projects-DuyhtSm4.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DEjxrxw3.js → Providers-Bo18Tx_6.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-eccy-8Vi.js → QrScannerModal-6W85KlsG.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Vx3uDvFg.js → QuickAsk-DznRUedP.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CfUivNps.js → Recommend-CQDN3_p-.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BU4gk7GI.js → RemoteSession-CiJgokEj.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-CbPzdZ0C.js → Reputation-DexzGH7E.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CYLrgfKA.js → Row-BgZOIvSi.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DbY1oyuv.js → RssFeed-BWIZJ_Jr.js} +3 -3
- package/src/assets/web-panel/assets/{Search-QeW41K5r.js → Search-B376EwWJ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CJxf1kLZ.js → Security-92mUR5OD.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CFO9ySZc.js → Services-ClSEAOHk.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CQFjeQN0.js → Skeleton-DVhLbv99.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CLLB4INW.js → Skills-JTcXs_xI.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DxeLIJk0.js → Sla-DnKY9zy9.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-D4FA9KYI.js → SpeechSettings-GO1JefAH.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-C6NOkcQK.js → SyncSettings-jX5tB2St.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-LmVPWDfQ.js → Tasks-BxRBzhUc.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BdEfUoVB.js → Templates-CAVkbTG1.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-IUlESacN.js → Tenant-5Y7sHBkz.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B9pDe7sn.js → Terminal-CbbLShYb.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-ZCwB-Pki.js → TimelineRenderer-2HptWihL.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-4qk16LX1.js → Tokens-B-jGxzHl.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-jXNyargn.js → Trigger-9DGa90DT.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-D13PydtT.js → Trust-BSJEkEOO.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-yPgws6mS.js → UkeySign-C807So5R.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B329WjpG.js → VideoEditing-ByiieAv-.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-T8VM-Ttm.js → Wallet-BixbIOUv.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-XuRibrpP.js → WebAuthn-z7akhor4.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-D1Gwz3YR.js → WorkflowEditor-KvijuUuR.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DjydtnT-.js → chat-BYKoh0YG.js} +1 -1
- package/src/assets/web-panel/assets/{colors-gFtBvPrr.js → colors-CLT8IYBt.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CndxhGfx.js → compact-item-DlBIyYHF.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DnfGpd0L.js → createContext-5XmAnNLr.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BmcCIHwY.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CmT5hRVW.js → hasIn-rPdRhm7K.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoBKSzqu.js → index-8un-eUDI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGbKeg8G.js → index-B-0nAxf5.js} +1 -1
- package/src/assets/web-panel/assets/{index-DreYqebI.js → index-B1VfBUPB.js} +1 -1
- package/src/assets/web-panel/assets/{index-zQf599Uq.js → index-BBt2CSAx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlTcxT_L.js → index-BDtlwjSr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqpR0Des.js → index-BIRl2Ii5.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3HvYeA3.js → index-BgevTkUv.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0WFjxWs.js → index-Bve7Wsgf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNHdO6Jr.js → index-Bzd0sFkp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DV2PR3Fa.js → index-C2sFDVb_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2d7358Y.js → index-CErvHCDe.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaEPE2DC.js → index-CM_a9spK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKyuE_Y2.js → index-CY6TMc2m.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVM_w30N.js → index-ChlzaTV3.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZLDbPTa.js → index-CsnbOKdI.js} +1 -1
- package/src/assets/web-panel/assets/{index-HHP1zzo7.js → index-D3-NL-x-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFif4Cev.js → index-D3f9Jzx2.js} +1 -1
- package/src/assets/web-panel/assets/{index-C14jryXi.js → index-DCDSycWo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CB27echm.js → index-DIVrVGvf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGlmPbl_.js → index-DI_tYFBe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsRKmb6k.js → index-DPS4mWnI.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXNUTiW8.js → index-DTslLzPJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbpk75MO.js → index-DW8vozBS.js} +1 -1
- package/src/assets/web-panel/assets/index-DY8rmd6x.js +1 -0
- package/src/assets/web-panel/assets/{index-DjY-3sMA.js → index-DZiSMYoD.js} +3 -3
- package/src/assets/web-panel/assets/{index-DV6NrfJx.js → index-DZjGcIGU.js} +1 -1
- package/src/assets/web-panel/assets/{index-ktN-K1Tf.js → index-Dea32nOK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjcR-CwS.js → index-Djd7uqwM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CuOx4Pbe.js → index-Dntid6oj.js} +1 -1
- package/src/assets/web-panel/assets/{index-BW3nWiu0.js → index-DqZU4_7J.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4Mqhmas.js → index-DuvweiCz.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRqz8TtI.js → index-DzExCCLS.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5na0B7G.js → index-LKT-Ol0A.js} +1 -1
- package/src/assets/web-panel/assets/{index-_-wGLtAg.js → index-akwXS-FF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgMKElUh.js → index-b-rQCMkx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUlubR4l.js → index-eHbr3f5I.js} +1 -1
- package/src/assets/web-panel/assets/{index-D88-8bsB.js → index-kx6zDWew.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuAvYTmY.js → index-rRuCGdKW.js} +1 -1
- package/src/assets/web-panel/assets/index-sbwcUeRS.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-KV3V-PNH.js → initDefaultProps-a8411LiK.js} +1 -1
- package/src/assets/web-panel/assets/{motion-PFGQg7_X.js → motion-oVcQdpCm.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dnl79wq4.js → move-B-eyzzzL.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-Bwl5JH9V.js → mtc-parser-BCYIxuG7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DCcTtM1l.js → omit-DuFtWiYh.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Cl6BjjDf.js → pickAttrs-CVAoJhGu.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-fdqhyo42.js → placementArrow-Y2iub2bO.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DYQpmcDW.js → responsiveObserve-BHenWIVD.js} +1 -1
- package/src/assets/web-panel/assets/{slide-C4l-VfO4.js → slide-CKrMaL29.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DYDw_dyZ.js → statusUtils-w8eb_1da.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BEsubSMu.js → styleChecker-CCVi_Ww3.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Cj82ggQ_.js → useFlexGapSupport-BsmR_q0r.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-B7L1eJ0V.js → useFs-a8GMBjnc.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DVlJVD4d.js → usePersonalDataHub-BMUYSPn-.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BBAbRN_Y.js → vnode-DL2pI31V.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BYn48q-I.js → zoom-Cbi8fISi.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/data/changelog.json +33 -7
- package/src/lib/dependency-install-policy.js +1 -1
- package/src/lib/evolution/browser-download-action-authority.js +747 -0
- package/src/lib/evolution/browser-download-artifact-disposal-authority.js +436 -0
- package/src/lib/evolution/browser-filesystem-quarantine-custody.js +2453 -0
- package/src/lib/evolution/browser-filesystem-quarantine-disposal.js +36 -0
- package/src/lib/evolution/browser-keyboard-action-authority.js +560 -0
- package/src/lib/evolution/browser-navigation-action-authority.js +546 -0
- package/src/lib/evolution/browser-quarantine-lock-maintenance-authority.js +573 -0
- package/src/lib/evolution/browser-quarantine-operator-revocation-authority.js +442 -0
- package/src/lib/evolution/browser-quarantine-retention-authority.js +503 -0
- package/src/lib/evolution/browser-quarantine-retention-scheduler.js +207 -0
- package/src/lib/evolution/browser-quarantined-download-executor.js +525 -0
- package/src/lib/evolution/browser-tab-open-action-authority.js +491 -0
- package/src/lib/evolution/browser-vision-action-authority.js +444 -0
- package/src/lib/evolution/browser-vision-observation-authority.js +304 -0
- package/src/lib/evolution/evolution-deployment-loader.js +241 -1
- package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +5 -0
- package/src/lib/evolution/evolution-eval-gate.js +2 -1
- package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +71 -9
- package/src/lib/evolution/evolution-eval-process-supervisor.js +276 -9
- package/src/lib/evolution/evolution-workbench-metrics.js +81 -21
- package/src/lib/evolution/pm-exploration-benchmark.js +747 -0
- package/src/lib/evolution/pm-exploration-budget-executor.js +106 -9
- package/src/lib/evolution/pm-exploration-egress-authority.js +382 -0
- package/src/lib/evolution/pm-exploration-evidence-bundle.js +149 -44
- package/src/lib/evolution/pm-exploration-execution-host.js +1254 -8
- package/src/lib/evolution/pm-exploration-process-grader.js +458 -0
- package/src/lib/evolution/pm-exploration-process-reviewer.js +456 -0
- package/src/lib/evolution/pm-exploration-process-runner.js +500 -0
- package/src/lib/evolution/pm-exploration-receipts.js +211 -11
- package/src/lib/evolution/pm-exploration-recovery-snapshot-store.js +465 -46
- package/src/lib/evolution/pm-exploration-transition-committer.js +185 -34
- package/src/lib/evolution/skill-outcome-index-authority.js +7 -3
- package/src/lib/evolution/skill-writer-inventory-manifest.js +0 -39
- package/src/lib/evolution/volcengine-function-execution-authority.js +2949 -0
- package/src/lib/evolution/volcengine-function-process-executor.js +615 -0
- package/src/lib/evolution/volcengine-function-replay-store.js +836 -0
- package/src/lib/evolution/volcengine-function-revocation-status-floor-store.js +480 -0
- package/src/lib/governance-coverage.js +1 -1
- package/src/lib/headless-manifest.js +1 -1
- package/src/lib/protocol-replay.js +1 -1
- package/src/lib/skill-outcome-transcript-authority.js +45 -5
- package/src/runtime/agent-core.js +17 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-Cf3LLgDc.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-CTsYo9NN.js +0 -1
- package/src/assets/web-panel/assets/devWarning-D60SbiD-.js +0 -1
- package/src/assets/web-panel/assets/index-C0yR4_7h.js +0 -1
- 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
|
|
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 >
|
|
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
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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
|
-
|
|
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
|
-
|
|
271
|
-
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
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
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
|
|
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:
|
|
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(
|
|
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(
|
|
504
|
-
|
|
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
|
-
|
|
516
|
-
|
|
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
|
});
|