chainlesschain 0.166.65 → 0.166.68

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 (198) 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-CXkSNOGY.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-C5LiW2-J.js → ActionButton-ysMR6gTs.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-D1INcvZF.js → Analytics-WGZ0sWuw.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-DZzHO1VV.js → AppLayout-Cs2iRlQG.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-WfYQL6Ia.js → Artifacts-5IdfxWz0.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-DohBoGWO.js → Audit-U9V434QX.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-Chtk-Hde.js → BackgroundAgents-BvFwxPlC.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-B813PuMz.js → Backup-C9yTr9hO.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DaDdWWgK.js → BaseInput-BdsSwUgE.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-D4pJ6oZ7.js → Chat-BB_2oBgH.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-Bpf1hDUl.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-Clo9TvO6.js → Checkbox-v6M5m7dK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-uejLg8Ih.js → Codegen-CtouWSIz.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-B7nbx-iJ.js → Col-CqQJ4ORW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-FEyjPK1j.js → Community-BO__QCOy.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-B6Fk0Kn6.js → Compact-D0Kq4xlH.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BQG8goUl.js → Compliance-BSLKKBjA.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-CbBeEfHp.js → Cowork-VsujXW5o.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-DPzlFcEZ.js → Cron-j8DbLGi5.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-B8pWJrbg.js → Crosschain-DWpYH1yN.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-gGQHUlFN.js → DID-mLaRxLQh.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-C2TMFHrn.js → Dashboard-Cff033Jr.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-BVPxGbll.js → Dropdown-B1Upt6fP.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-CNPxs0hd.js → EmailListRenderer-CPtb8joV.js} +1 -1
  27. package/src/assets/web-panel/assets/{EvolutionSettings-_XTiB7q1.js → EvolutionSettings-CVh4Uv4g.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-UyE3VWtI.js → FamilyGuardDashboard-CrD1PhbF.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-CLt6FHK-.js → Federation-ftxrvqW5.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-CdNQPRPw.js → FormItemContext-9O80slC1.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-BJ0AMhrh.js → GenericCardRenderer-DaYvYIj9.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-CQnvMfOM.js → Git-BKZh0YE5.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-deYsHC-o.js → Governance-vWbN873j.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-qaSck43z.js → Inference-BN6RR-l8.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-De0aJ3Ls.js → KnowledgeGraph-x49x9m7Q.js} +1 -1
  36. package/src/assets/web-panel/assets/Logs-Co2EPLsJ.js +2 -0
  37. package/src/assets/web-panel/assets/MarkdownRenderer-D7wIB-c7.js +1 -0
  38. package/src/assets/web-panel/assets/{Marketplace-Byz3xCBN.js → Marketplace-DpPu6XQp.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-DOZUUW6z.js → McpTools-BR0ksiax.js} +3 -3
  40. package/src/assets/web-panel/assets/{Memory-C33wC2hA.js → Memory-BXznJ5-C.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-zZe-T_6M.js → MobileBridge-BHSOpfv7.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-CRnUIume.js → MobileProjects-DdWmgIup.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-C1xlRVAN.js → Mtc-D9Rk_IGT.js} +5 -5
  44. package/src/assets/web-panel/assets/{MtcAudit-D0U07bIi.js → MtcAudit--i8q1lKc.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-DF8uvV3h.js → Multisig-BHnNG7R9.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-bBPGAFlt.js → NLProgramming-Duo1ij2_.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-BHAaOsgg.js → Notes-B44Le73p.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-Cl0fG_rA.js → NotificationSettings-C3oy_7Gf.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-BEPAs8Zv.js → OrderTableRenderer-Da_73SI5.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-BAxSwgk5.js → Organization-ChsSwKxT.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-D68KubAu.js → Overflow-DR5G_cCn.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-bhdT17zk.js → P2P-yfaobqow.js} +2 -2
  53. package/src/assets/web-panel/assets/PdhVaultBrowser-DgimH6Jp.js +7 -0
  54. package/src/assets/web-panel/assets/{Permissions-Bq8fvkak.js → Permissions-DhinFvtE.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-BYd2JEic.js → PersonalDataHub-CfeNVic1.js} +5 -5
  56. package/src/assets/web-panel/assets/{Pipeline-Csg_ja69.js → Pipeline-CGKO26Nk.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-lwxwLj4M.js → Privacy-CxxfYEJh.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-BdBZkH8z.js → ProjectInit-CZsaAab9.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-ClWgFy-K.js → ProjectSettings-BUm_6clQ.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-Bu-qj8N1.js → Projects-Capr8bVq.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-DEjxrxw3.js → Providers-D28VqPja.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-eccy-8Vi.js → QrScannerModal-Cj200vUb.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-Vx3uDvFg.js → QuickAsk-BGpnEiam.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-CfUivNps.js → Recommend-Ix79Tpni.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-BU4gk7GI.js → RemoteSession-BdGAFbIk.js} +3 -3
  66. package/src/assets/web-panel/assets/{Reputation-CbPzdZ0C.js → Reputation-B1Lis0Wk.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-CYLrgfKA.js → Row-Ba_okwOW.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-DbY1oyuv.js → RssFeed-DDbEuI-m.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-QeW41K5r.js → Search-D89wAkMy.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-CJxf1kLZ.js → Security-CJKCKAU-.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-CFO9ySZc.js → Services-mitEc1XV.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-CQFjeQN0.js → Skeleton-CnBjLDfX.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-CLLB4INW.js → Skills-DSzDYvH3.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-DxeLIJk0.js → Sla-CglJ_4p3.js} +1 -1
  75. package/src/assets/web-panel/assets/SpeechSettings-BicWJS7f.js +1 -0
  76. package/src/assets/web-panel/assets/{SyncSettings-C6NOkcQK.js → SyncSettings-Cq7o6fmr.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-LmVPWDfQ.js → Tasks-DOxFOBpU.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-BdEfUoVB.js → Templates-bY0wSbQM.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-IUlESacN.js → Tenant-BAyyl0qX.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-B9pDe7sn.js → Terminal-BGBhSpqc.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-ZCwB-Pki.js → TimelineRenderer-BvW5lXYz.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-4qk16LX1.js → Tokens-Ua_LIx8-.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-jXNyargn.js → Trigger-BGwb2KL1.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-D13PydtT.js → Trust-CD2IEHvj.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-yPgws6mS.js → UkeySign-D5LetK6P.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-B329WjpG.js → VideoEditing-oP7ehFgR.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-T8VM-Ttm.js → Wallet-BBtu4-xa.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-XuRibrpP.js → WebAuthn-iSPRU4Ht.js} +5 -5
  89. package/src/assets/web-panel/assets/{WorkflowEditor-D1Gwz3YR.js → WorkflowEditor-DuEDhQmB.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-DjydtnT-.js → chat-DGDgqvvm.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-gFtBvPrr.js → colors-DGQMWa1-.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-CndxhGfx.js → compact-item-COVznBL4.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-DnfGpd0L.js → createContext-DIxVeHXI.js} +1 -1
  94. package/src/assets/web-panel/assets/devWarning-CjR9h-Z_.js +1 -0
  95. package/src/assets/web-panel/assets/{hasIn-CmT5hRVW.js → hasIn-DkxZO3E9.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BGlmPbl_.js → index-0ToBFsvW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BsRKmb6k.js → index-2JZizEPc.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-C14jryXi.js → index-BAL2p7YC.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B0WFjxWs.js → index-BAlrovUm.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-BlTcxT_L.js → index-BBw2MLIe.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DjcR-CwS.js → index-BHH95jcm.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DreYqebI.js → index-BOTshZNx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DaEPE2DC.js → index-BQm7ntcn.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BNHdO6Jr.js → index-BUqwlzc8.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C3HvYeA3.js → index-BY6MSbWT.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DUlubR4l.js → index-BY9Ossof.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Dbpk75MO.js → index-BgM-3a1w.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CqpR0Des.js → index-Bv0_u0ze.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DjY-3sMA.js → index-C3XeNS82.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-DV6NrfJx.js → index-C3bN6751.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DuAvYTmY.js → index-CNRRrP3-.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BW3nWiu0.js → index-CV0KnNqR.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CZLDbPTa.js → index-CcNGQWum.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-D5na0B7G.js → index-Ci34vbh0.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DoBKSzqu.js → index-ClQVcrFt.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CuOx4Pbe.js → index-Cligb-Dl.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CgMKElUh.js → index-CokrhbY2.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BFif4Cev.js → index-CpZxDiVK.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-HHP1zzo7.js → index-CyMHF2Bi.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-_-wGLtAg.js → index-DDwPBGdA.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-ktN-K1Tf.js → index-DU1ArKl5.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-C4Mqhmas.js → index-DV0H83eS.js} +1 -1
  123. package/src/assets/web-panel/assets/index-D_nxBMX5.js +1 -0
  124. package/src/assets/web-panel/assets/{index-BXNUTiW8.js → index-DaWQSp5a.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DKyuE_Y2.js → index-DmduvOYT.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DV2PR3Fa.js → index-ECoDhyH3.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BVM_w30N.js → index-ZcqTvPnt.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CRqz8TtI.js → index-b2_M6o20.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CB27echm.js → index-b_0qTo8O.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-D88-8bsB.js → index-dfYkGovV.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DGbKeg8G.js → index-jo7DbU0w.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D2d7358Y.js → index-usmG13jq.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-zQf599Uq.js → index-vXrktF3e.js} +1 -1
  134. package/src/assets/web-panel/assets/index-z_cTUMX-.js +1 -0
  135. package/src/assets/web-panel/assets/{initDefaultProps-KV3V-PNH.js → initDefaultProps-CkSeiBwL.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-PFGQg7_X.js → motion-CSzhDP0s.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-Dnl79wq4.js → move-mgCt4iC6.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-Bwl5JH9V.js → mtc-parser-BEZBLcKt.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-DCcTtM1l.js → omit-BsHctMEr.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-Cl6BjjDf.js → pickAttrs-1BHamnGW.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-fdqhyo42.js → placementArrow--Vb4Bd7l.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-DYQpmcDW.js → responsiveObserve-DD33SqCm.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-C4l-VfO4.js → slide-DfrLtxgK.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-DYDw_dyZ.js → statusUtils-D9Pe_gXW.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-BEsubSMu.js → styleChecker-0NY5iMun.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-Cj82ggQ_.js → useFlexGapSupport-DSsZstwg.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-B7L1eJ0V.js → useFs-BU8HyH59.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-DVlJVD4d.js → usePersonalDataHub-D_xttink.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-BBAbRN_Y.js → vnode-39VhX2lM.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-BYn48q-I.js → zoom-D5KQ8Pks.js} +1 -1
  151. package/src/assets/web-panel/index.html +1 -1
  152. package/src/data/changelog.json +20 -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 +202 -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/governance-coverage.js +1 -1
  187. package/src/lib/headless-manifest.js +1 -1
  188. package/src/lib/protocol-replay.js +1 -1
  189. package/src/lib/skill-outcome-transcript-authority.js +45 -5
  190. package/src/runtime/agent-core.js +17 -0
  191. package/src/assets/web-panel/assets/ChatBubbleRenderer-Cf3LLgDc.js +0 -1
  192. package/src/assets/web-panel/assets/Logs-ZtS98jCm.js +0 -2
  193. package/src/assets/web-panel/assets/MarkdownRenderer-CTsYo9NN.js +0 -1
  194. package/src/assets/web-panel/assets/PdhVaultBrowser-DqaO6wgH.js +0 -7
  195. package/src/assets/web-panel/assets/SpeechSettings-D4FA9KYI.js +0 -1
  196. package/src/assets/web-panel/assets/devWarning-D60SbiD-.js +0 -1
  197. package/src/assets/web-panel/assets/index-C0yR4_7h.js +0 -1
  198. package/src/assets/web-panel/assets/index-D4xuvo03.js +0 -1
@@ -0,0 +1,436 @@
1
+ import { createHash } from "node:crypto";
2
+ import { types } from "node:util";
3
+
4
+ export const BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_DESCRIPTOR_SCHEMA =
5
+ "chainlesschain.browser-download-artifact-disposal-descriptor/v1";
6
+ export const BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_REQUEST_SCHEMA =
7
+ "chainlesschain.browser-download-artifact-disposal-request/v1";
8
+ export const BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_RECEIPT_SCHEMA =
9
+ "chainlesschain.browser-download-artifact-disposal-receipt/v1";
10
+ export const BROWSER_DOWNLOAD_ARTIFACT_DELETION_ACK_SCHEMA =
11
+ "chainlesschain.browser-download-artifact-deletion-ack/v1";
12
+
13
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
14
+ const ID = /^[A-Za-z0-9._:-]{1,128}$/u;
15
+ const ARTIFACT_REF = /^quarantine:[A-Za-z0-9][A-Za-z0-9._-]{0,95}$/u;
16
+ const REASONS = new Set([
17
+ "user-discard",
18
+ "expired",
19
+ "revoked",
20
+ "delivery-failed",
21
+ ]);
22
+ const authorities = new WeakMap();
23
+
24
+ function canonical(value) {
25
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
26
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
27
+ return `{${Object.keys(value)
28
+ .sort()
29
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
30
+ .join(",")}}`;
31
+ }
32
+
33
+ function digest(domain, value) {
34
+ return `sha256:${createHash("sha256")
35
+ .update(`${domain}\0`)
36
+ .update(canonical(value))
37
+ .digest("hex")}`;
38
+ }
39
+
40
+ function exact(value, keys, label) {
41
+ if (
42
+ !value ||
43
+ typeof value !== "object" ||
44
+ Array.isArray(value) ||
45
+ types.isProxy(value) ||
46
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
47
+ Reflect.ownKeys(value).length !== keys.length ||
48
+ keys.some((key) => {
49
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
50
+ return !descriptor?.enumerable || !("value" in descriptor);
51
+ })
52
+ )
53
+ throw new TypeError(`${label} has an invalid shape`);
54
+ }
55
+
56
+ function snapshotJson(value, label) {
57
+ let nodes = 0;
58
+ const visit = (entry, depth) => {
59
+ if (++nodes > 2048 || depth > 12)
60
+ throw new TypeError(`${label} exceeds its structure budget`);
61
+ if (
62
+ entry === null ||
63
+ typeof entry === "boolean" ||
64
+ (typeof entry === "number" && Number.isFinite(entry)) ||
65
+ typeof entry === "string"
66
+ )
67
+ return entry;
68
+ if (
69
+ !entry ||
70
+ typeof entry !== "object" ||
71
+ types.isProxy(entry) ||
72
+ ![Object.prototype, null, Array.prototype].includes(
73
+ Object.getPrototypeOf(entry),
74
+ )
75
+ )
76
+ throw new TypeError(`${label} must be finite plain JSON data`);
77
+ if (Array.isArray(entry))
78
+ return Object.freeze(entry.map((item) => visit(item, depth + 1)));
79
+ const output = {};
80
+ for (const key of Object.keys(entry)) {
81
+ const descriptor = Object.getOwnPropertyDescriptor(entry, key);
82
+ if (!descriptor?.enumerable || !("value" in descriptor))
83
+ throw new TypeError(`${label} must contain plain data`);
84
+ output[key] = visit(descriptor.value, depth + 1);
85
+ }
86
+ return Object.freeze(output);
87
+ };
88
+ const result = visit(value, 0);
89
+ if (Buffer.byteLength(canonical(result), "utf8") > 16 * 1024)
90
+ throw new TypeError(`${label} exceeds its byte budget`);
91
+ return result;
92
+ }
93
+
94
+ function normalizeDescriptor(value) {
95
+ exact(
96
+ value,
97
+ [
98
+ "schema",
99
+ "authorityId",
100
+ "tenantId",
101
+ "handlerArtifactDigest",
102
+ "policyRevision",
103
+ "maxGrantTtlMs",
104
+ "approvalMode",
105
+ "auditMode",
106
+ "effectMode",
107
+ ],
108
+ "download artifact disposal descriptor",
109
+ );
110
+ if (
111
+ value.schema !== BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_DESCRIPTOR_SCHEMA ||
112
+ !ID.test(value.authorityId) ||
113
+ !ID.test(value.tenantId) ||
114
+ !DIGEST.test(value.handlerArtifactDigest) ||
115
+ !ID.test(value.policyRevision) ||
116
+ !Number.isSafeInteger(value.maxGrantTtlMs) ||
117
+ value.maxGrantTtlMs < 1 ||
118
+ value.maxGrantTtlMs > 30_000 ||
119
+ value.approvalMode !== "interactive" ||
120
+ value.auditMode !== "authenticated-durable-readback" ||
121
+ value.effectMode !== "irreversible-byte-disposal"
122
+ )
123
+ throw new TypeError("download artifact disposal descriptor is invalid");
124
+ return Object.freeze({ ...value });
125
+ }
126
+
127
+ function normalizeRequest(value) {
128
+ exact(
129
+ value,
130
+ [
131
+ "schema",
132
+ "requestId",
133
+ "senderId",
134
+ "frameUrlDigest",
135
+ "operation",
136
+ "artifactRef",
137
+ "artifactDigest",
138
+ "sourceActionReceiptDigest",
139
+ "reason",
140
+ "inputDigest",
141
+ "authorization",
142
+ "requestedAt",
143
+ ],
144
+ "download artifact disposal request",
145
+ );
146
+ const inputCore = Object.freeze({
147
+ operation: value.operation,
148
+ artifactRef: value.artifactRef,
149
+ artifactDigest: value.artifactDigest,
150
+ sourceActionReceiptDigest: value.sourceActionReceiptDigest,
151
+ reason: value.reason,
152
+ });
153
+ if (
154
+ value.schema !== BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_REQUEST_SCHEMA ||
155
+ !ID.test(value.requestId) ||
156
+ !Number.isSafeInteger(value.senderId) ||
157
+ value.senderId < 1 ||
158
+ !DIGEST.test(value.frameUrlDigest) ||
159
+ value.operation !== "discard-download-artifact" ||
160
+ !ARTIFACT_REF.test(value.artifactRef) ||
161
+ !DIGEST.test(value.artifactDigest) ||
162
+ !DIGEST.test(value.sourceActionReceiptDigest) ||
163
+ !REASONS.has(value.reason) ||
164
+ value.inputDigest !==
165
+ digest(
166
+ "chainlesschain.browser-download-artifact-disposal-input/v1",
167
+ inputCore,
168
+ ) ||
169
+ !Number.isFinite(Date.parse(value.requestedAt))
170
+ )
171
+ throw new TypeError("download artifact disposal request is invalid");
172
+ return Object.freeze({
173
+ ...value,
174
+ authorization: snapshotJson(
175
+ value.authorization,
176
+ "download artifact disposal authorization",
177
+ ),
178
+ });
179
+ }
180
+
181
+ function requestEvidence(request) {
182
+ const core = Object.freeze({
183
+ schema: request.schema,
184
+ requestId: request.requestId,
185
+ senderId: request.senderId,
186
+ frameUrlDigest: request.frameUrlDigest,
187
+ operation: request.operation,
188
+ artifactRefDigest: digest(
189
+ "chainlesschain.browser-download-artifact-ref/v1",
190
+ request.artifactRef,
191
+ ),
192
+ artifactDigest: request.artifactDigest,
193
+ sourceActionReceiptDigest: request.sourceActionReceiptDigest,
194
+ reason: request.reason,
195
+ inputDigest: request.inputDigest,
196
+ authorizationDigest: digest(
197
+ "chainlesschain.browser-download-artifact-disposal-authorization/v1",
198
+ request.authorization,
199
+ ),
200
+ requestedAt: request.requestedAt,
201
+ });
202
+ return Object.freeze({
203
+ ...core,
204
+ requestDigest: digest(
205
+ BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_REQUEST_SCHEMA,
206
+ core,
207
+ ),
208
+ });
209
+ }
210
+
211
+ function normalizeDecision(value) {
212
+ if (!value || typeof value !== "object" || types.isProxy(value))
213
+ throw new TypeError("download artifact disposal decision is invalid");
214
+ if (value.decision === "deny") {
215
+ exact(
216
+ value,
217
+ Object.hasOwn(value, "reason") ? ["decision", "reason"] : ["decision"],
218
+ "download artifact disposal decision",
219
+ );
220
+ if (
221
+ value.reason !== undefined &&
222
+ (typeof value.reason !== "string" || value.reason.length > 512)
223
+ )
224
+ throw new TypeError(
225
+ "download artifact disposal denial reason is invalid",
226
+ );
227
+ return Object.freeze({ decision: "deny", reason: value.reason ?? null });
228
+ }
229
+ exact(
230
+ value,
231
+ ["decision", "approvalEvidenceRef", "validUntil"],
232
+ "download artifact disposal decision",
233
+ );
234
+ if (value.decision !== "allow")
235
+ throw new TypeError("download artifact disposal decision is invalid");
236
+ return Object.freeze({ ...value });
237
+ }
238
+
239
+ function normalizeDeletionAck(value, descriptor, issued) {
240
+ exact(
241
+ value,
242
+ [
243
+ "schema",
244
+ "authorityId",
245
+ "tenantId",
246
+ "handlerArtifactDigest",
247
+ "actionReceiptDigest",
248
+ "requestDigest",
249
+ "artifactRef",
250
+ "artifactDigest",
251
+ "sourceActionReceiptDigest",
252
+ "discardedAt",
253
+ "deletionReceiptDigest",
254
+ "authenticated",
255
+ "durable",
256
+ "readbackVerified",
257
+ "bytesUnavailable",
258
+ "qualifiesForPromotion",
259
+ ],
260
+ "download artifact deletion acknowledgement",
261
+ );
262
+ if (
263
+ value.schema !== BROWSER_DOWNLOAD_ARTIFACT_DELETION_ACK_SCHEMA ||
264
+ value.authorityId !== descriptor.authorityId ||
265
+ value.tenantId !== descriptor.tenantId ||
266
+ value.handlerArtifactDigest !== descriptor.handlerArtifactDigest ||
267
+ value.actionReceiptDigest !== issued.receipt.receiptDigest ||
268
+ value.requestDigest !== issued.receipt.requestDigest ||
269
+ value.artifactRef !== issued.request.artifactRef ||
270
+ value.artifactDigest !== issued.request.artifactDigest ||
271
+ value.sourceActionReceiptDigest !==
272
+ issued.request.sourceActionReceiptDigest ||
273
+ !Number.isFinite(Date.parse(value.discardedAt)) ||
274
+ !DIGEST.test(value.deletionReceiptDigest) ||
275
+ value.authenticated !== true ||
276
+ value.durable !== true ||
277
+ value.readbackVerified !== true ||
278
+ value.bytesUnavailable !== true ||
279
+ value.qualifiesForPromotion !== false
280
+ )
281
+ throw new Error("download artifact deletion acknowledgement is invalid");
282
+ return Object.freeze({ ...value });
283
+ }
284
+
285
+ export function createBrowserDownloadArtifactDisposalAuthority({
286
+ descriptor,
287
+ authorize,
288
+ disposeArtifact,
289
+ now = Date.now,
290
+ } = {}) {
291
+ const normalizedDescriptor = normalizeDescriptor(descriptor);
292
+ for (const [name, port] of Object.entries({
293
+ authorize,
294
+ disposeArtifact,
295
+ now,
296
+ })) {
297
+ if (typeof port !== "function" || types.isProxy(port))
298
+ throw new TypeError(`download artifact disposal ${name} port is invalid`);
299
+ }
300
+ const authority = Object.freeze({});
301
+ authorities.set(authority, {
302
+ descriptor: normalizedDescriptor,
303
+ authorize,
304
+ disposeArtifact,
305
+ now,
306
+ issued: new Map(),
307
+ });
308
+ return authority;
309
+ }
310
+
311
+ export function captureBrowserDownloadArtifactDisposalAuthority(value) {
312
+ const captured = authorities.get(value);
313
+ if (!captured)
314
+ throw new TypeError(
315
+ "A branded browser download artifact disposal authority is required",
316
+ );
317
+ return Object.freeze({
318
+ descriptor: captured.descriptor,
319
+ authorizeDisposal: async (input) => {
320
+ const request = normalizeRequest(input);
321
+ const evidence = requestEvidence(request);
322
+ const decision = normalizeDecision(
323
+ await captured.authorize(
324
+ Object.freeze({ ...request, requestDigest: evidence.requestDigest }),
325
+ ),
326
+ );
327
+ if (decision.decision !== "allow") {
328
+ const error = new Error(
329
+ decision.reason ?? "Download artifact disposal was denied",
330
+ );
331
+ error.code = "BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_DENIED";
332
+ throw error;
333
+ }
334
+ const nowMs = captured.now();
335
+ const validUntilMs = Date.parse(decision.validUntil);
336
+ if (
337
+ typeof decision.approvalEvidenceRef !== "string" ||
338
+ decision.approvalEvidenceRef.length < 1 ||
339
+ decision.approvalEvidenceRef.length > 512 ||
340
+ !Number.isFinite(nowMs) ||
341
+ !Number.isFinite(validUntilMs) ||
342
+ validUntilMs <= nowMs ||
343
+ validUntilMs > nowMs + captured.descriptor.maxGrantTtlMs
344
+ )
345
+ throw new Error("Download artifact disposal decision is invalid");
346
+ const core = Object.freeze({
347
+ schema: BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_RECEIPT_SCHEMA,
348
+ authorityId: captured.descriptor.authorityId,
349
+ tenantId: captured.descriptor.tenantId,
350
+ handlerArtifactDigest: captured.descriptor.handlerArtifactDigest,
351
+ policyRevision: captured.descriptor.policyRevision,
352
+ approvalMode: captured.descriptor.approvalMode,
353
+ auditMode: captured.descriptor.auditMode,
354
+ effectMode: captured.descriptor.effectMode,
355
+ requestId: request.requestId,
356
+ senderId: request.senderId,
357
+ frameUrlDigest: request.frameUrlDigest,
358
+ operation: request.operation,
359
+ artifactRefDigest: evidence.artifactRefDigest,
360
+ artifactDigest: request.artifactDigest,
361
+ sourceActionReceiptDigest: request.sourceActionReceiptDigest,
362
+ reason: request.reason,
363
+ inputDigest: request.inputDigest,
364
+ authorizationDigest: evidence.authorizationDigest,
365
+ requestDigest: evidence.requestDigest,
366
+ approvalEvidenceRef: decision.approvalEvidenceRef,
367
+ authorizedAt: new Date(nowMs).toISOString(),
368
+ validUntil: new Date(validUntilMs).toISOString(),
369
+ });
370
+ const receipt = Object.freeze({
371
+ ...core,
372
+ receiptDigest: digest(
373
+ BROWSER_DOWNLOAD_ARTIFACT_DISPOSAL_RECEIPT_SCHEMA,
374
+ core,
375
+ ),
376
+ });
377
+ captured.issued.set(receipt.receiptDigest, {
378
+ request,
379
+ receipt,
380
+ consumed: false,
381
+ });
382
+ return receipt;
383
+ },
384
+ disposeAuthorizedArtifact: async (input) => {
385
+ exact(
386
+ input,
387
+ ["receiptDigest", "requestDigest"],
388
+ "download artifact disposal execution request",
389
+ );
390
+ const issued = captured.issued.get(input.receiptDigest);
391
+ const nowMs = captured.now();
392
+ if (
393
+ !DIGEST.test(input.receiptDigest) ||
394
+ !DIGEST.test(input.requestDigest) ||
395
+ !issued ||
396
+ issued.receipt.requestDigest !== input.requestDigest ||
397
+ issued.consumed ||
398
+ !Number.isFinite(nowMs) ||
399
+ nowMs >= Date.parse(issued.receipt.validUntil)
400
+ )
401
+ throw new Error("download artifact disposal grant is invalid or spent");
402
+ issued.consumed = true;
403
+ const acknowledgement = normalizeDeletionAck(
404
+ await captured.disposeArtifact(
405
+ Object.freeze({
406
+ actionReceiptDigest: issued.receipt.receiptDigest,
407
+ requestDigest: issued.receipt.requestDigest,
408
+ artifactRef: issued.request.artifactRef,
409
+ artifactDigest: issued.request.artifactDigest,
410
+ sourceActionReceiptDigest: issued.request.sourceActionReceiptDigest,
411
+ reason: issued.request.reason,
412
+ }),
413
+ ),
414
+ captured.descriptor,
415
+ issued,
416
+ );
417
+ captured.issued.delete(input.receiptDigest);
418
+ const core = Object.freeze({
419
+ status: "discarded",
420
+ artifactRefDigest: issued.receipt.artifactRefDigest,
421
+ artifactDigest: issued.request.artifactDigest,
422
+ sourceActionReceiptDigest: issued.request.sourceActionReceiptDigest,
423
+ reason: issued.request.reason,
424
+ discardedAt: acknowledgement.discardedAt,
425
+ deletionReceiptDigest: acknowledgement.deletionReceiptDigest,
426
+ });
427
+ return Object.freeze({
428
+ ...core,
429
+ resultDigest: digest(
430
+ "chainlesschain.browser-download-artifact-disposal-result/v1",
431
+ core,
432
+ ),
433
+ });
434
+ },
435
+ });
436
+ }