chainlesschain 0.166.64 → 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 (199) hide show
  1. package/README.md +29 -12
  2. package/package.json +4 -4
  3. package/src/assets/web-panel/assets/{AIOps-BFbLDWTF.js → AIOps-CXkSNOGY.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CAHMtgNB.js → ActionButton-ysMR6gTs.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-CkrSj0oR.js → Analytics-WGZ0sWuw.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-BTb0Ws1l.js → AppLayout-Cs2iRlQG.js} +4 -4
  7. package/src/assets/web-panel/assets/{Artifacts-C2Pgepj-.js → Artifacts-5IdfxWz0.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-ZweyxXW8.js → Audit-U9V434QX.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-BS8tAnzP.js → BackgroundAgents-BvFwxPlC.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CLkG_74M.js → Backup-C9yTr9hO.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-MIfNcdUZ.js → BaseInput-BdsSwUgE.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-DBwqlWWr.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-DdBYhlVX.js → Checkbox-v6M5m7dK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-BR6MhiDo.js → Codegen-CtouWSIz.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-yO-5EbbM.js → Col-CqQJ4ORW.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-B608q_m7.js → Community-BO__QCOy.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-BmVHi7Z7.js → Compact-D0Kq4xlH.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-BQ-DzutA.js → Compliance-BSLKKBjA.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-BEfLyXvi.js → Cowork-VsujXW5o.js} +3 -3
  21. package/src/assets/web-panel/assets/{Cron-Cld6NX-_.js → Cron-j8DbLGi5.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-CUA3nDId.js → Crosschain-DWpYH1yN.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DSI3E9zv.js → DID-mLaRxLQh.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-CoWtEdhO.js → Dashboard-Cff033Jr.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-CGhZ1Dyy.js → Dropdown-B1Upt6fP.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-BHZe2K5q.js → EmailListRenderer-CPtb8joV.js} +1 -1
  27. package/src/assets/web-panel/assets/{EvolutionSettings-Corjo98k.js → EvolutionSettings-CVh4Uv4g.js} +1 -1
  28. package/src/assets/web-panel/assets/{FamilyGuardDashboard-dPSWF3Pt.js → FamilyGuardDashboard-CrD1PhbF.js} +1 -1
  29. package/src/assets/web-panel/assets/{Federation-DT-Zr78c.js → Federation-ftxrvqW5.js} +1 -1
  30. package/src/assets/web-panel/assets/{FormItemContext-CzKq63B0.js → FormItemContext-9O80slC1.js} +1 -1
  31. package/src/assets/web-panel/assets/{GenericCardRenderer-CDkKrmu0.js → GenericCardRenderer-DaYvYIj9.js} +1 -1
  32. package/src/assets/web-panel/assets/{Git-BrwRnLOv.js → Git-BKZh0YE5.js} +2 -2
  33. package/src/assets/web-panel/assets/{Governance-C4PtCzod.js → Governance-vWbN873j.js} +1 -1
  34. package/src/assets/web-panel/assets/{Inference-CVPv5nwa.js → Inference-BN6RR-l8.js} +1 -1
  35. package/src/assets/web-panel/assets/{KnowledgeGraph-CmT9lvED.js → KnowledgeGraph-x49x9m7Q.js} +1 -1
  36. package/src/assets/web-panel/assets/{Logs-DaRgv7pL.js → Logs-Co2EPLsJ.js} +2 -2
  37. package/src/assets/web-panel/assets/{MarkdownRenderer-B3zZwlSz.js → MarkdownRenderer-D7wIB-c7.js} +1 -1
  38. package/src/assets/web-panel/assets/{Marketplace-Bm0GGEaL.js → Marketplace-DpPu6XQp.js} +1 -1
  39. package/src/assets/web-panel/assets/{McpTools-71L5h0en.js → McpTools-BR0ksiax.js} +3 -3
  40. package/src/assets/web-panel/assets/{Memory-BoWrfASi.js → Memory-BXznJ5-C.js} +2 -2
  41. package/src/assets/web-panel/assets/{MobileBridge-Dp4FcX_-.js → MobileBridge-BHSOpfv7.js} +1 -1
  42. package/src/assets/web-panel/assets/{MobileProjects-00ja0Z7O.js → MobileProjects-DdWmgIup.js} +1 -1
  43. package/src/assets/web-panel/assets/{Mtc-BZF6YNYp.js → Mtc-D9Rk_IGT.js} +4 -4
  44. package/src/assets/web-panel/assets/{MtcAudit-Bp_vcI6H.js → MtcAudit--i8q1lKc.js} +2 -2
  45. package/src/assets/web-panel/assets/{Multisig-CnCo56CS.js → Multisig-BHnNG7R9.js} +3 -3
  46. package/src/assets/web-panel/assets/{NLProgramming-BCSzNHpv.js → NLProgramming-Duo1ij2_.js} +1 -1
  47. package/src/assets/web-panel/assets/{Notes-kXoQk8B7.js → Notes-B44Le73p.js} +3 -3
  48. package/src/assets/web-panel/assets/{NotificationSettings-oN-1fkcy.js → NotificationSettings-C3oy_7Gf.js} +1 -1
  49. package/src/assets/web-panel/assets/{OrderTableRenderer-5ZVHrVZ9.js → OrderTableRenderer-Da_73SI5.js} +1 -1
  50. package/src/assets/web-panel/assets/{Organization-D4_T9Tdc.js → Organization-ChsSwKxT.js} +4 -4
  51. package/src/assets/web-panel/assets/{Overflow-d8vZwo9w.js → Overflow-DR5G_cCn.js} +1 -1
  52. package/src/assets/web-panel/assets/{P2P-0HGUdmTv.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-XHd6pVQB.js → Permissions-DhinFvtE.js} +4 -4
  55. package/src/assets/web-panel/assets/{PersonalDataHub-CB5bZU9T.js → PersonalDataHub-CfeNVic1.js} +3 -3
  56. package/src/assets/web-panel/assets/{Pipeline-Dy_qx4-0.js → Pipeline-CGKO26Nk.js} +1 -1
  57. package/src/assets/web-panel/assets/{Privacy-BgR0-uEu.js → Privacy-CxxfYEJh.js} +1 -1
  58. package/src/assets/web-panel/assets/{ProjectInit-DAcRi1Nx.js → ProjectInit-CZsaAab9.js} +2 -2
  59. package/src/assets/web-panel/assets/{ProjectSettings-Bd1Q0rK_.js → ProjectSettings-BUm_6clQ.js} +2 -2
  60. package/src/assets/web-panel/assets/{Projects-DVc9DcbM.js → Projects-Capr8bVq.js} +1 -1
  61. package/src/assets/web-panel/assets/{Providers-C3c4QfUT.js → Providers-D28VqPja.js} +1 -1
  62. package/src/assets/web-panel/assets/{QrScannerModal-Ba_GbitW.js → QrScannerModal-Cj200vUb.js} +1 -1
  63. package/src/assets/web-panel/assets/{QuickAsk-CSn5tIkO.js → QuickAsk-BGpnEiam.js} +1 -1
  64. package/src/assets/web-panel/assets/{Recommend-B3-8PLX0.js → Recommend-Ix79Tpni.js} +1 -1
  65. package/src/assets/web-panel/assets/{RemoteSession-Bd_7Zmi-.js → RemoteSession-BdGAFbIk.js} +2 -2
  66. package/src/assets/web-panel/assets/{Reputation-BU2A_wy5.js → Reputation-B1Lis0Wk.js} +1 -1
  67. package/src/assets/web-panel/assets/{Row-I0JFMjCz.js → Row-Ba_okwOW.js} +1 -1
  68. package/src/assets/web-panel/assets/{RssFeed-CNc4Dgfz.js → RssFeed-DDbEuI-m.js} +3 -3
  69. package/src/assets/web-panel/assets/{Search-uAA6ceLl.js → Search-D89wAkMy.js} +1 -1
  70. package/src/assets/web-panel/assets/{Security-U1SWj5nP.js → Security-CJKCKAU-.js} +3 -3
  71. package/src/assets/web-panel/assets/{Services-BFjZ5ASY.js → Services-mitEc1XV.js} +2 -2
  72. package/src/assets/web-panel/assets/{Skeleton-B8InBvQf.js → Skeleton-CnBjLDfX.js} +1 -1
  73. package/src/assets/web-panel/assets/{Skills-BDYwf3QV.js → Skills-DSzDYvH3.js} +1 -1
  74. package/src/assets/web-panel/assets/{Sla-Dcc6iq3q.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-BNHEYO95.js → SyncSettings-Cq7o6fmr.js} +2 -2
  77. package/src/assets/web-panel/assets/{Tasks-JbV6L1FX.js → Tasks-DOxFOBpU.js} +1 -1
  78. package/src/assets/web-panel/assets/{Templates-Yp0CUTBz.js → Templates-bY0wSbQM.js} +1 -1
  79. package/src/assets/web-panel/assets/{Tenant-CToNYxCo.js → Tenant-BAyyl0qX.js} +1 -1
  80. package/src/assets/web-panel/assets/{Terminal-D7W9UqSD.js → Terminal-BGBhSpqc.js} +2 -2
  81. package/src/assets/web-panel/assets/{TimelineRenderer-B7rqc1kE.js → TimelineRenderer-BvW5lXYz.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tokens-QP7K4ppA.js → Tokens-Ua_LIx8-.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trigger-CAWowQCR.js → Trigger-BGwb2KL1.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trust-B-0XOP97.js → Trust-CD2IEHvj.js} +1 -1
  85. package/src/assets/web-panel/assets/{UkeySign-BtiZbiuj.js → UkeySign-D5LetK6P.js} +1 -1
  86. package/src/assets/web-panel/assets/{VideoEditing-Dee11JI0.js → VideoEditing-oP7ehFgR.js} +1 -1
  87. package/src/assets/web-panel/assets/{Wallet-y7qOmaWY.js → Wallet-BBtu4-xa.js} +4 -4
  88. package/src/assets/web-panel/assets/{WebAuthn-CjyRRWGK.js → WebAuthn-iSPRU4Ht.js} +3 -3
  89. package/src/assets/web-panel/assets/{WorkflowEditor-D7Kiz25Q.js → WorkflowEditor-DuEDhQmB.js} +1 -1
  90. package/src/assets/web-panel/assets/{chat-4F_yB-Gw.js → chat-DGDgqvvm.js} +1 -1
  91. package/src/assets/web-panel/assets/{colors-CrczPd-t.js → colors-DGQMWa1-.js} +1 -1
  92. package/src/assets/web-panel/assets/{compact-item-AenPL6fz.js → compact-item-COVznBL4.js} +1 -1
  93. package/src/assets/web-panel/assets/{createContext-BcwoqPgi.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-YouHmap8.js → hasIn-DkxZO3E9.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-fCuM1NPH.js → index-0ToBFsvW.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-D0dXNgvi.js → index-2JZizEPc.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-BHA5Fyjc.js → index-BAL2p7YC.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CedvtJA_.js → index-BAlrovUm.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-5GHNjmnt.js → index-BBw2MLIe.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-C5hpEYbx.js → index-BHH95jcm.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-D8a1AEVK.js → index-BOTshZNx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-D7m5Z4We.js → index-BQm7ntcn.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-D_4VsL-L.js → index-BUqwlzc8.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-GP5u18DV.js → index-BY6MSbWT.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CHNKoexH.js → index-BY9Ossof.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DNHmbdGm.js → index-BgM-3a1w.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-YX4dcbgh.js → index-Bv0_u0ze.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D5Rvq67L.js → index-C3XeNS82.js} +3 -3
  110. package/src/assets/web-panel/assets/{index-DAGfuEUu.js → index-C3bN6751.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CZT-LLGS.js → index-CNRRrP3-.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-4r7B8sTx.js → index-CV0KnNqR.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-B5Vmr0CM.js → index-CcNGQWum.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DE3qPp9l.js → index-Ci34vbh0.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CWgIKCVS.js → index-ClQVcrFt.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-31dhJpt3.js → index-Cligb-Dl.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BsGhFk79.js → index-CokrhbY2.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-B_I1INkw.js → index-CpZxDiVK.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BaguGDJP.js → index-CyMHF2Bi.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DPrzFdCg.js → index-DDwPBGdA.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-gy1H_PJk.js → index-DU1ArKl5.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DAh5KwVL.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-q_9aqSgF.js → index-DaWQSp5a.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-B8EXHVmM.js → index-DmduvOYT.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DVrgnhfu.js → index-ECoDhyH3.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BwUqDg9_.js → index-ZcqTvPnt.js} +1 -1
  128. package/src/assets/web-panel/assets/{index--xwN0ZvG.js → index-b2_M6o20.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CZ9Ikuo6.js → index-b_0qTo8O.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BoVeUGhC.js → index-dfYkGovV.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-COgeZETv.js → index-jo7DbU0w.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-Dfw3WyZU.js → index-usmG13jq.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BzyDSW_e.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-Ci6zc6ZA.js → initDefaultProps-CkSeiBwL.js} +1 -1
  136. package/src/assets/web-panel/assets/{motion-DS3kjIxw.js → motion-CSzhDP0s.js} +1 -1
  137. package/src/assets/web-panel/assets/{move-DCdWAKk4.js → move-mgCt4iC6.js} +1 -1
  138. package/src/assets/web-panel/assets/{mtc-parser-B0Wfce9U.js → mtc-parser-BEZBLcKt.js} +1 -1
  139. package/src/assets/web-panel/assets/{omit-Clx9TR6z.js → omit-BsHctMEr.js} +1 -1
  140. package/src/assets/web-panel/assets/{pickAttrs-CqSiqUvN.js → pickAttrs-1BHamnGW.js} +1 -1
  141. package/src/assets/web-panel/assets/{placementArrow-BWe_v-40.js → placementArrow--Vb4Bd7l.js} +1 -1
  142. package/src/assets/web-panel/assets/{responsiveObserve-BSJ68bw6.js → responsiveObserve-DD33SqCm.js} +1 -1
  143. package/src/assets/web-panel/assets/{slide-VRPlLxZB.js → slide-DfrLtxgK.js} +1 -1
  144. package/src/assets/web-panel/assets/{statusUtils-BFBVDPdB.js → statusUtils-D9Pe_gXW.js} +1 -1
  145. package/src/assets/web-panel/assets/{styleChecker-CehOXy1f.js → styleChecker-0NY5iMun.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFlexGapSupport-BCOdfK18.js → useFlexGapSupport-DSsZstwg.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFs-BMKrjfJQ.js → useFs-BU8HyH59.js} +1 -1
  148. package/src/assets/web-panel/assets/{usePersonalDataHub-BIjZ7IgI.js → usePersonalDataHub-D_xttink.js} +1 -1
  149. package/src/assets/web-panel/assets/{vnode-oD0MXddQ.js → vnode-39VhX2lM.js} +1 -1
  150. package/src/assets/web-panel/assets/{zoom-D7WqH2Ai.js → zoom-D5KQ8Pks.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 +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/read-file-loop-guard.js +5 -8
  190. package/src/lib/remote-read-loop-guard.js +25 -18
  191. package/src/lib/skill-outcome-transcript-authority.js +45 -5
  192. package/src/lib/tool-recovery-result.js +11 -0
  193. package/src/runtime/agent-core.js +26 -3
  194. package/src/assets/web-panel/assets/ChatBubbleRenderer-6T0uoJuS.js +0 -1
  195. package/src/assets/web-panel/assets/PdhVaultBrowser-Cx8vp92z.js +0 -7
  196. package/src/assets/web-panel/assets/SpeechSettings-C3Ta-mC9.js +0 -1
  197. package/src/assets/web-panel/assets/devWarning-C4qWsAvh.js +0 -1
  198. package/src/assets/web-panel/assets/index-C-ltOW-O.js +0 -1
  199. package/src/assets/web-panel/assets/index-D7Ir0TiS.js +0 -1
@@ -0,0 +1,442 @@
1
+ import { createHash } from "node:crypto";
2
+ import { types } from "node:util";
3
+
4
+ import { captureBrowserFilesystemQuarantineCustody } from "./browser-filesystem-quarantine-custody.js";
5
+ export { BROWSER_FILESYSTEM_QUARANTINE_OPERATOR_REVOCATION_DESCRIPTOR_SCHEMA } from "./browser-filesystem-quarantine-custody.js";
6
+
7
+ export const BROWSER_QUARANTINE_OPERATOR_REVOCATION_REQUEST_SCHEMA =
8
+ "chainlesschain.browser-quarantine-operator-revocation-request/v1";
9
+ export const BROWSER_QUARANTINE_OPERATOR_REVOCATION_RECEIPT_SCHEMA =
10
+ "chainlesschain.browser-quarantine-operator-revocation-receipt/v1";
11
+ export const BROWSER_QUARANTINE_OPERATOR_REVOCATION_OUTCOME_REQUEST_SCHEMA =
12
+ "chainlesschain.browser-quarantine-operator-revocation-outcome-request/v1";
13
+ export const BROWSER_QUARANTINE_OPERATOR_REVOCATION_OUTCOME_ACK_SCHEMA =
14
+ "chainlesschain.browser-quarantine-operator-revocation-outcome-ack/v1";
15
+ export const BROWSER_QUARANTINE_OPERATOR_REVOCATION_RESULT_SCHEMA =
16
+ "chainlesschain.browser-quarantine-operator-revocation-result/v1";
17
+
18
+ const DELETION_ACK_SCHEMA =
19
+ "chainlesschain.browser-download-artifact-deletion-ack/v1";
20
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
21
+ const ID = /^[A-Za-z0-9._:-]{1,128}$/u;
22
+ const ARTIFACT_REF = /^quarantine:[A-Za-z0-9][A-Za-z0-9._-]{0,95}$/u;
23
+ const authorities = new WeakMap();
24
+
25
+ function canonical(value) {
26
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
27
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
28
+ return `{${Object.keys(value)
29
+ .sort()
30
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
31
+ .join(",")}}`;
32
+ }
33
+
34
+ function digest(domain, value) {
35
+ return `sha256:${createHash("sha256")
36
+ .update(`${domain}\0`)
37
+ .update(canonical(value))
38
+ .digest("hex")}`;
39
+ }
40
+
41
+ function exact(value, keys, label) {
42
+ if (
43
+ !value ||
44
+ typeof value !== "object" ||
45
+ Array.isArray(value) ||
46
+ types.isProxy(value) ||
47
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
48
+ Reflect.ownKeys(value).length !== keys.length ||
49
+ keys.some((key) => {
50
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
51
+ return !descriptor?.enumerable || !("value" in descriptor);
52
+ })
53
+ )
54
+ throw new TypeError(`${label} has unexpected or accessor fields`);
55
+ }
56
+
57
+ function snapshotJson(value, label) {
58
+ const visit = (entry, depth) => {
59
+ if (depth > 8) throw new TypeError(`${label} exceeds its depth budget`);
60
+ if (
61
+ entry === null ||
62
+ typeof entry === "string" ||
63
+ typeof entry === "boolean" ||
64
+ (typeof entry === "number" && Number.isFinite(entry))
65
+ )
66
+ return entry;
67
+ if (
68
+ !entry ||
69
+ typeof entry !== "object" ||
70
+ types.isProxy(entry) ||
71
+ ![Object.prototype, null, Array.prototype].includes(
72
+ Object.getPrototypeOf(entry),
73
+ )
74
+ )
75
+ throw new TypeError(`${label} must be finite plain JSON data`);
76
+ if (Array.isArray(entry))
77
+ return Object.freeze(entry.map((item) => visit(item, depth + 1)));
78
+ const result = {};
79
+ for (const key of Object.keys(entry)) {
80
+ const descriptor = Object.getOwnPropertyDescriptor(entry, key);
81
+ if (!descriptor?.enumerable || !("value" in descriptor))
82
+ throw new TypeError(`${label} must contain plain data`);
83
+ result[key] = visit(descriptor.value, depth + 1);
84
+ }
85
+ return Object.freeze(result);
86
+ };
87
+ const result = visit(value, 0);
88
+ if (Buffer.byteLength(canonical(result), "utf8") > 16 * 1024)
89
+ throw new TypeError(`${label} exceeds its byte budget`);
90
+ return result;
91
+ }
92
+
93
+ function normalizeRequest(value) {
94
+ exact(
95
+ value,
96
+ [
97
+ "schema",
98
+ "requestId",
99
+ "artifactRef",
100
+ "artifactDigest",
101
+ "sourceActionReceiptDigest",
102
+ "operatorIdDigest",
103
+ "authorization",
104
+ "requestedAt",
105
+ ],
106
+ "operator revocation request",
107
+ );
108
+ if (
109
+ value.schema !== BROWSER_QUARANTINE_OPERATOR_REVOCATION_REQUEST_SCHEMA ||
110
+ !ID.test(value.requestId) ||
111
+ !ARTIFACT_REF.test(value.artifactRef) ||
112
+ !DIGEST.test(value.artifactDigest) ||
113
+ !DIGEST.test(value.sourceActionReceiptDigest) ||
114
+ !DIGEST.test(value.operatorIdDigest) ||
115
+ !Number.isFinite(Date.parse(value.requestedAt))
116
+ )
117
+ throw new TypeError("operator revocation request is invalid");
118
+ return Object.freeze({
119
+ ...value,
120
+ authorization: snapshotJson(value.authorization, "operator authorization"),
121
+ });
122
+ }
123
+
124
+ function normalizeDecision(value, nowMs, maxGrantTtlMs) {
125
+ if (
126
+ !value ||
127
+ typeof value !== "object" ||
128
+ Array.isArray(value) ||
129
+ types.isProxy(value) ||
130
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value))
131
+ )
132
+ throw new TypeError("operator revocation decision is invalid");
133
+ const decision = Object.getOwnPropertyDescriptor(value, "decision");
134
+ if (!decision?.enumerable || !("value" in decision))
135
+ throw new TypeError("operator revocation decision is invalid");
136
+ if (decision.value === "deny") {
137
+ exact(value, ["decision", "reason"], "operator revocation denial");
138
+ if (
139
+ typeof value.reason !== "string" ||
140
+ value.reason.length < 1 ||
141
+ value.reason.length > 512
142
+ )
143
+ throw new TypeError("operator revocation denial is invalid");
144
+ return Object.freeze({ ...value });
145
+ }
146
+ exact(
147
+ value,
148
+ ["decision", "operatorEvidenceRef", "validUntil"],
149
+ "operator revocation decision",
150
+ );
151
+ const validUntilMs = Date.parse(value.validUntil);
152
+ if (
153
+ value.decision !== "allow" ||
154
+ typeof value.operatorEvidenceRef !== "string" ||
155
+ value.operatorEvidenceRef.length < 1 ||
156
+ value.operatorEvidenceRef.length > 512 ||
157
+ !Number.isFinite(validUntilMs) ||
158
+ validUntilMs <= nowMs ||
159
+ validUntilMs > nowMs + maxGrantTtlMs
160
+ )
161
+ throw new Error("operator revocation decision is invalid");
162
+ return Object.freeze({ ...value, validUntilMs });
163
+ }
164
+
165
+ function normalizeDeletionAck(value, descriptor, request, receiptDigest) {
166
+ exact(
167
+ value,
168
+ [
169
+ "schema",
170
+ "authorityId",
171
+ "tenantId",
172
+ "handlerArtifactDigest",
173
+ "actionReceiptDigest",
174
+ "requestDigest",
175
+ "artifactRef",
176
+ "artifactDigest",
177
+ "sourceActionReceiptDigest",
178
+ "discardedAt",
179
+ "deletionReceiptDigest",
180
+ "authenticated",
181
+ "durable",
182
+ "readbackVerified",
183
+ "bytesUnavailable",
184
+ "qualifiesForPromotion",
185
+ ],
186
+ "operator revocation deletion acknowledgement",
187
+ );
188
+ if (
189
+ value.schema !== DELETION_ACK_SCHEMA ||
190
+ value.authorityId !== descriptor.authorityId ||
191
+ value.tenantId !== descriptor.tenantId ||
192
+ value.handlerArtifactDigest !== descriptor.handlerArtifactDigest ||
193
+ value.actionReceiptDigest !== receiptDigest ||
194
+ !DIGEST.test(value.requestDigest) ||
195
+ value.artifactRef !== request.artifactRef ||
196
+ value.artifactDigest !== request.artifactDigest ||
197
+ value.sourceActionReceiptDigest !== request.sourceActionReceiptDigest ||
198
+ !Number.isFinite(Date.parse(value.discardedAt)) ||
199
+ !DIGEST.test(value.deletionReceiptDigest) ||
200
+ value.authenticated !== true ||
201
+ value.durable !== true ||
202
+ value.readbackVerified !== true ||
203
+ value.bytesUnavailable !== true ||
204
+ value.qualifiesForPromotion !== false
205
+ )
206
+ throw new Error("operator revocation deletion acknowledgement is invalid");
207
+ return value;
208
+ }
209
+
210
+ function normalizeOutcomeAck(value, descriptor, request) {
211
+ exact(
212
+ value,
213
+ [
214
+ "schema",
215
+ "authorityId",
216
+ "tenantId",
217
+ "handlerArtifactDigest",
218
+ "revocationReceiptDigest",
219
+ "outcomeRequestDigest",
220
+ "auditEventDigest",
221
+ "durabilityReceiptDigest",
222
+ "authenticated",
223
+ "durable",
224
+ "readbackVerified",
225
+ "qualifiesForPromotion",
226
+ ],
227
+ "operator revocation outcome acknowledgement",
228
+ );
229
+ if (
230
+ value.schema !==
231
+ BROWSER_QUARANTINE_OPERATOR_REVOCATION_OUTCOME_ACK_SCHEMA ||
232
+ value.authorityId !== descriptor.authorityId ||
233
+ value.tenantId !== descriptor.tenantId ||
234
+ value.handlerArtifactDigest !== descriptor.handlerArtifactDigest ||
235
+ value.revocationReceiptDigest !== request.revocationReceiptDigest ||
236
+ value.outcomeRequestDigest !== request.outcomeRequestDigest ||
237
+ !DIGEST.test(value.auditEventDigest) ||
238
+ !DIGEST.test(value.durabilityReceiptDigest) ||
239
+ value.authenticated !== true ||
240
+ value.durable !== true ||
241
+ value.readbackVerified !== true ||
242
+ value.qualifiesForPromotion !== false
243
+ )
244
+ throw new Error("operator revocation outcome acknowledgement is invalid");
245
+ return value;
246
+ }
247
+
248
+ export function createBrowserQuarantineOperatorRevocationAuthority(options) {
249
+ exact(
250
+ options,
251
+ ["descriptor", "custody", "authorizeRevocation", "recordOutcome", "now"],
252
+ "browser quarantine operator revocation authority",
253
+ );
254
+ const custody = captureBrowserFilesystemQuarantineCustody(options.custody);
255
+ const revokeArtifact = custody.bindOperatorRevocationAuthority(
256
+ options.descriptor,
257
+ );
258
+ for (const [name, port] of Object.entries({
259
+ authorizeRevocation: options.authorizeRevocation,
260
+ recordOutcome: options.recordOutcome,
261
+ now: options.now,
262
+ })) {
263
+ if (typeof port !== "function" || types.isProxy(port))
264
+ throw new TypeError(`operator revocation ${name} port is invalid`);
265
+ }
266
+ const authority = Object.freeze({});
267
+ authorities.set(authority, {
268
+ descriptor: Object.freeze({ ...options.descriptor }),
269
+ revokeArtifact,
270
+ authorizeRevocation: options.authorizeRevocation,
271
+ recordOutcome: options.recordOutcome,
272
+ now: options.now,
273
+ });
274
+ return authority;
275
+ }
276
+
277
+ export function captureBrowserQuarantineOperatorRevocationAuthority(value) {
278
+ const state = authorities.get(value);
279
+ if (!state)
280
+ throw new TypeError(
281
+ "A branded browser quarantine operator revocation authority is required",
282
+ );
283
+ return Object.freeze({
284
+ descriptor: state.descriptor,
285
+ revokeArtifact: async (input) => {
286
+ const request = normalizeRequest(input);
287
+ const nowMs = state.now();
288
+ if (!Number.isFinite(nowMs))
289
+ throw new Error("operator revocation clock is invalid");
290
+ const artifactRefDigest = digest(
291
+ "chainlesschain.browser-download-artifact-ref/v1",
292
+ request.artifactRef,
293
+ );
294
+ const authorizationDigest = digest(
295
+ "chainlesschain.browser-quarantine-operator-authorization/v1",
296
+ request.authorization,
297
+ );
298
+ const requestCore = Object.freeze({
299
+ schema: BROWSER_QUARANTINE_OPERATOR_REVOCATION_REQUEST_SCHEMA,
300
+ requestId: request.requestId,
301
+ artifactRefDigest,
302
+ artifactDigest: request.artifactDigest,
303
+ sourceActionReceiptDigest: request.sourceActionReceiptDigest,
304
+ operatorIdDigest: request.operatorIdDigest,
305
+ authorizationDigest,
306
+ requestedAt: request.requestedAt,
307
+ });
308
+ const requestDigest = digest(
309
+ BROWSER_QUARANTINE_OPERATOR_REVOCATION_REQUEST_SCHEMA,
310
+ requestCore,
311
+ );
312
+ const decision = normalizeDecision(
313
+ await state.authorizeRevocation(
314
+ Object.freeze({
315
+ ...requestCore,
316
+ requestDigest,
317
+ authorization: request.authorization,
318
+ }),
319
+ ),
320
+ nowMs,
321
+ state.descriptor.maxGrantTtlMs,
322
+ );
323
+ if (decision.decision === "deny") {
324
+ const error = new Error(decision.reason);
325
+ error.code = "BROWSER_QUARANTINE_OPERATOR_REVOCATION_DENIED";
326
+ throw error;
327
+ }
328
+ const receiptCore = Object.freeze({
329
+ schema: BROWSER_QUARANTINE_OPERATOR_REVOCATION_RECEIPT_SCHEMA,
330
+ authorityId: state.descriptor.authorityId,
331
+ tenantId: state.descriptor.tenantId,
332
+ handlerArtifactDigest: state.descriptor.handlerArtifactDigest,
333
+ policyRevision: state.descriptor.policyRevision,
334
+ requestId: request.requestId,
335
+ artifactRefDigest,
336
+ artifactDigest: request.artifactDigest,
337
+ sourceActionReceiptDigest: request.sourceActionReceiptDigest,
338
+ operatorIdDigest: request.operatorIdDigest,
339
+ requestDigest,
340
+ operatorEvidenceRef: decision.operatorEvidenceRef,
341
+ authorizedAt: new Date(nowMs).toISOString(),
342
+ validUntil: decision.validUntil,
343
+ });
344
+ const receiptDigest = digest(
345
+ BROWSER_QUARANTINE_OPERATOR_REVOCATION_RECEIPT_SCHEMA,
346
+ receiptCore,
347
+ );
348
+ let deletion = null;
349
+ let executionError = null;
350
+ try {
351
+ const executionMs = state.now();
352
+ if (
353
+ !Number.isFinite(executionMs) ||
354
+ executionMs >= decision.validUntilMs
355
+ )
356
+ throw new Error("operator revocation grant expired before execution");
357
+ deletion = normalizeDeletionAck(
358
+ await state.revokeArtifact({
359
+ actionReceiptDigest: receiptDigest,
360
+ requestDigest,
361
+ artifactRef: request.artifactRef,
362
+ artifactDigest: request.artifactDigest,
363
+ sourceActionReceiptDigest: request.sourceActionReceiptDigest,
364
+ reason: "revoked",
365
+ }),
366
+ state.descriptor,
367
+ request,
368
+ receiptDigest,
369
+ );
370
+ } catch (error) {
371
+ executionError = error;
372
+ }
373
+ const recordedAtMs = state.now();
374
+ if (!Number.isFinite(recordedAtMs))
375
+ throw new Error("operator revocation clock is invalid");
376
+ const outcomeCore = Object.freeze({
377
+ schema: BROWSER_QUARANTINE_OPERATOR_REVOCATION_OUTCOME_REQUEST_SCHEMA,
378
+ authorityId: state.descriptor.authorityId,
379
+ tenantId: state.descriptor.tenantId,
380
+ handlerArtifactDigest: state.descriptor.handlerArtifactDigest,
381
+ policyRevision: state.descriptor.policyRevision,
382
+ revocationReceiptDigest: receiptDigest,
383
+ requestDigest,
384
+ artifactRefDigest,
385
+ artifactDigest: request.artifactDigest,
386
+ operatorIdDigest: request.operatorIdDigest,
387
+ status: executionError === null ? "succeeded" : "failed",
388
+ deletionReceiptDigest: deletion?.deletionReceiptDigest ?? null,
389
+ failureDigest:
390
+ executionError === null
391
+ ? null
392
+ : digest(
393
+ "chainlesschain.browser-quarantine-operator-revocation-failure/v1",
394
+ {
395
+ name: executionError?.name ?? "Error",
396
+ code: executionError?.code ?? null,
397
+ },
398
+ ),
399
+ recordedAt: new Date(recordedAtMs).toISOString(),
400
+ });
401
+ const outcomeRequest = Object.freeze({
402
+ ...outcomeCore,
403
+ outcomeRequestDigest: digest(
404
+ BROWSER_QUARANTINE_OPERATOR_REVOCATION_OUTCOME_REQUEST_SCHEMA,
405
+ outcomeCore,
406
+ ),
407
+ });
408
+ const outcomeAck = normalizeOutcomeAck(
409
+ await state.recordOutcome(outcomeRequest),
410
+ state.descriptor,
411
+ outcomeRequest,
412
+ );
413
+ if (executionError !== null) {
414
+ const uncertain = new Error("operator revocation execution failed", {
415
+ cause: executionError,
416
+ });
417
+ uncertain.code = "BROWSER_QUARANTINE_OPERATOR_REVOCATION_FAILED";
418
+ throw uncertain;
419
+ }
420
+ const resultCore = Object.freeze({
421
+ schema: BROWSER_QUARANTINE_OPERATOR_REVOCATION_RESULT_SCHEMA,
422
+ status: "revoked",
423
+ artifactRefDigest,
424
+ artifactDigest: request.artifactDigest,
425
+ sourceActionReceiptDigest: request.sourceActionReceiptDigest,
426
+ operatorIdDigest: request.operatorIdDigest,
427
+ discardedAt: deletion.discardedAt,
428
+ deletionReceiptDigest: deletion.deletionReceiptDigest,
429
+ outcomeRequestDigest: outcomeRequest.outcomeRequestDigest,
430
+ auditEventDigest: outcomeAck.auditEventDigest,
431
+ durabilityReceiptDigest: outcomeAck.durabilityReceiptDigest,
432
+ });
433
+ return Object.freeze({
434
+ ...resultCore,
435
+ resultDigest: digest(
436
+ BROWSER_QUARANTINE_OPERATOR_REVOCATION_RESULT_SCHEMA,
437
+ resultCore,
438
+ ),
439
+ });
440
+ },
441
+ });
442
+ }