chainlesschain 0.166.37 → 0.166.39

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 (193) hide show
  1. package/package.json +7 -2
  2. package/scripts/governed-learning-local-attestor-service.mjs +222 -0
  3. package/scripts/governed-learning-local-attestor-trust-approval-service.mjs +338 -0
  4. package/scripts/governed-learning-local-attestor-trust-operations-service.mjs +575 -0
  5. package/scripts/governed-learning-windows-secure-pipe-broker.ps1 +375 -0
  6. package/src/assets/web-panel/assets/{AIOps-B_Nt1Qe4.js → AIOps-qWUdiFr5.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-CHQbie4X.js → ActionButton-B_f7go3E.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-Bm9364Lw.js → Analytics-hSGFlSkB.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-DTwlIh2v.js → AppLayout-CCYGgj71.js} +3 -3
  10. package/src/assets/web-panel/assets/{Artifacts-OibP0qB4.js → Artifacts-BdS1H9gq.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-B8Fwavkg.js → Audit-Cck9IebC.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-p1Vb2K2B.js → BackgroundAgents-DZzoM_QS.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-BI3QT-wI.js → Backup-D8H_QtGu.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-BW_VRWWu.js → BaseInput-CTsNF_pu.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-CUEhDQfq.js → Chat-CcEiTYY8.js} +4 -4
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-C5UVXdVE.js → ChatBubbleRenderer-9BY1DPuc.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-URYsaaxv.js → Checkbox-BPB9NNJx.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-DJAwC80a.js → Codegen-CKKMf7jD.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-DfRKFzc9.js → Col-DpSSB4Uu.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-GOkGHuly.js → Community-CfR6ikoH.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-CIMs13NC.js → Compact-CqnkGGjK.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-BE-TQIxV.js → Compliance-9IzhdVQb.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-CYmbJiWw.js → Cowork-eXsgH33N.js} +4 -4
  24. package/src/assets/web-panel/assets/{Cron-Be3OIWyM.js → Cron-DvkzHFRi.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-2xB2HS2D.js → Crosschain--az9d9f7.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-B_lJO2yF.js → DID-_Eb4kpnJ.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-DnVWqUER.js → Dashboard-aDVisdXj.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-C7ZJvHVa.js → Dropdown-oQ54XzS9.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-DLevT-0F.js → EmailListRenderer-BUPdMau1.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BwhQ5BRU.js → FamilyGuardDashboard-DtQTOCQI.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-BkGI-Xkq.js → Federation-Cpnb3Moe.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-BgIIbMd7.js → FormItemContext-DmsrJkeU.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-qL-qN8Nb.js → GenericCardRenderer-CpFDYnh3.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BTzgrC4U.js → Git-HFG17p7Q.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-p28vdCN4.js → Governance-D5Z5c7N8.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-Cqephrur.js → Inference-DH159h74.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-C3v5Q4Zp.js → KnowledgeGraph-DuL1pcJD.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-T6f0w32w.js → Logs-Gqn8hFsM.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-Dj5XPm3S.js → MarkdownRenderer-NHJaejHI.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-ClDsvHDH.js → Marketplace-BArcWifg.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-C4P-_snx.js → McpTools-Q1BfBSnd.js} +2 -2
  42. package/src/assets/web-panel/assets/{Memory-BZZfG6y6.js → Memory-Cz8nRL7N.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-DpIv_BLs.js → MobileBridge-CRuxLRJw.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-Buz3NIQg.js → MobileProjects-B1CQIAGp.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-HS2PJB79.js → Mtc-CFhXZbPk.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-UmBrcU27.js → MtcAudit-C69LqcZ5.js} +4 -4
  47. package/src/assets/web-panel/assets/{Multisig-C00sXiZf.js → Multisig-y7yZeTTG.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-Dj1ng_ph.js → NLProgramming-DgjhoWea.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-C4LEVKlk.js → Notes-DRc2WTDh.js} +4 -4
  50. package/src/assets/web-panel/assets/{NotificationSettings-BWXwnekv.js → NotificationSettings-CLPx24yn.js} +1 -1
  51. package/src/assets/web-panel/assets/{OrderTableRenderer-CZHfK8Nn.js → OrderTableRenderer-CMSNA4CO.js} +1 -1
  52. package/src/assets/web-panel/assets/{Organization-CFEtFPrV.js → Organization-Dm6LIyhZ.js} +4 -4
  53. package/src/assets/web-panel/assets/{Overflow-DSz4MJK1.js → Overflow-DP4DOYd-.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-DyTEytwG.js → P2P-HFwvtFI1.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-B5QNGLVx.js → PdhVaultBrowser-D9gPfKRM.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-wEC_X7x4.js → Permissions-Bdtxniwh.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-If5GZlGZ.js → PersonalDataHub-Dgl2AbES.js} +3 -3
  58. package/src/assets/web-panel/assets/{Pipeline-LB4gqqmX.js → Pipeline-DpZrzYwK.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-QVLhoxcN.js → Privacy-EQ551c0t.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-FaAbTYTo.js → ProjectInit-xUSeczsM.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-DhMeNA21.js → ProjectSettings-B66Sr_t8.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-5L4lkWAZ.js → Projects-B4zikj95.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-DhZFp8fO.js → Providers-DjLbqQPh.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-BZuJ7_xi.js → QrScannerModal-KVsAQCd_.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-TXddPYYb.js → QuickAsk-C4noJXu8.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-DDuXIKYt.js → Recommend-Cn15clqY.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-CDrTXImv.js → RemoteSession-DdonMFwH.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-B2xKaKzt.js → Reputation-Bqe3NwWN.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-DzAjWAOX.js → Row-CnxBgjkD.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-CKH38BLF.js → RssFeed-CSRrgZyK.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-CuPqJYoQ.js → Search-DTUYUfFx.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-DmAd2hxz.js → Security-BHExHVIm.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-Bt3nljnY.js → Services-B_IWqPes.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CP7RH093.js → Skeleton-C_oAtzmX.js} +1 -1
  75. package/src/assets/web-panel/assets/{Skills-DKNeMBTx.js → Skills-maJNokSL.js} +1 -1
  76. package/src/assets/web-panel/assets/{Sla-CbpM8Nrd.js → Sla-CMM_ZsLH.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-DTk-vTzF.js → SpeechSettings-D7w_oNwK.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-DKiplwmc.js → SyncSettings-D0Zl3NIr.js} +2 -2
  79. package/src/assets/web-panel/assets/{Tasks-z-lOm8fx.js → Tasks-Bs0H0ctR.js} +1 -1
  80. package/src/assets/web-panel/assets/{Templates-Rb-Q0DGX.js → Templates-C6T6oCpR.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-C2sqDUnR.js → Tenant-ByL-kAYO.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-DcyzskEE.js → Terminal-6JXNhc3b.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-lg0Eam7N.js → TimelineRenderer-KiuUtCsl.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-D9USIMIA.js → Tokens-C0TWTIER.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-BQpaQJ5k.js → Trigger-DpC5aaJu.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-C-Mik04s.js → Trust-lqqflCwv.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-DrnZ_o56.js → UkeySign-BYSlVfBc.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-BDOsoZi0.js → VideoEditing-DX08oo_R.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-Ct_bleI7.js → Wallet-CcIFPvzL.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-B6b6FDao.js → WebAuthn-D8DfxfVT.js} +5 -5
  91. package/src/assets/web-panel/assets/{WorkflowEditor-ZUJMaIHr.js → WorkflowEditor-Csadpaln.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-BII20OJy.js → chat-CewHWc_T.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-DEsJRV3n.js → colors-B8at89r3.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-DoDYAzN9.js → compact-item-v_gxtF5-.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-o_nofnVW.js → createContext-BOwFpJqA.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-DenB_kSS.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-CAsABTHC.js → hasIn-DjHUzt7E.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CeJSTcXw.js → index-1Tfwr_GA.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CVQSl1uY.js → index-5qmLo1us.js} +1 -1
  100. package/src/assets/web-panel/assets/index-B8bNwM9U.js +1 -0
  101. package/src/assets/web-panel/assets/{index-CQE-WMEU.js → index-BC20EQ7h.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DciLb_Ww.js → index-BGrmPk8T.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-Bqyg3PME.js → index-BPJ7uL2Q.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-DU2Rpx1m.js → index-BRNyE3Kb.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CeWJqXNX.js → index-BVPsegMN.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DWZNYecl.js → index-B_egGFcR.js} +3 -3
  107. package/src/assets/web-panel/assets/{index-TSwbtCYG.js → index-BdZLA7k9.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BrIIJ2s-.js → index-Bk_Te9OR.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D5Fd4tdL.js → index-Bz8C8VXx.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B4SfcwZA.js → index-C7MHbmwn.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Bn2ZPUXO.js → index-CFL1Hewx.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DsoFTdA2.js → index-CV1SgaBd.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-B9hYHPhs.js → index-CXIPAeAB.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Dgt1mKby.js → index-Ca8YZU2B.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DRAA2McB.js → index-Caf9UjhG.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BcYbQoY7.js → index-Cb1uNDOv.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-Bycj011d.js → index-CquUCUzS.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BzMA6Ra3.js → index-CwHoF-TP.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Dbb34cAr.js → index-Cxk0mCoQ.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BxT8yTwS.js → index-D3o-pacB.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DrsAF-Ar.js → index-DA3n0Y28.js} +1 -1
  122. package/src/assets/web-panel/assets/index-DC0cpgIP.js +1 -0
  123. package/src/assets/web-panel/assets/{index-B9Z75LfA.js → index-DRRK_8Eg.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-kIyLNyoF.js → index-DUMvVGyf.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DQmX_-hk.js → index-DdHdbXpy.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-tCeNfxv4.js → index-Ddw05Myq.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BDRh3v44.js → index-Dfrb3Prv.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Bmwo5wQG.js → index-DiKaYIdo.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-C1YDdyQ1.js → index-DmZLZsyC.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Dhnau6uw.js → index-FgUrhq_H.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Cf3sFEoE.js → index-Khw7wzVk.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-B0ApxOMw.js → index-San3zacc.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-D_CMB_wC.js → index-coOi37of.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BnbnmRqg.js → index-hyeBuocp.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DDQzBK3l.js → index-uk59xr0W.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CE2J04dA.js → index-wjvn8-9F.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-CNjeeoKE.js → initDefaultProps-Id2dFdjh.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-CBT8IZDm.js → motion-DRxtwxng.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-h1MOxjqv.js → move-BDYvdTb6.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-C_3pqNmn.js → mtc-parser-cz8LGI8Z.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-CMUnPFDk.js → omit-DHJeh6tH.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-p8_c1xq0.js → pickAttrs-XJEQIp7e.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-D6O67r23.js → placementArrow-AFcf8lEn.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-DquhepAK.js → responsiveObserve-CDEeBxs1.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-CZ-m6gmS.js → slide-CvbVfi6T.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-k9ejZFtd.js → statusUtils-DtCyuEnq.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-NX6_137R.js → styleChecker--UgmTsGY.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-bCqR70lP.js → useFlexGapSupport-D9i1as-Y.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-2l0vSqyY.js → useFs-CJx3zw01.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-1yccm4O7.js → usePersonalDataHub-ZsIKYdZv.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-CxQzajDo.js → vnode-B2RGEQG4.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-CrTKwFyb.js → zoom-ob-0px2z.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/evolution-attestor-trust.js +113 -0
  156. package/src/commands/evolution.js +2 -0
  157. package/src/commands/learning.js +34 -5
  158. package/src/data/changelog.json +26 -0
  159. package/src/lib/evolution/evolution-artifact-ports.js +21 -0
  160. package/src/lib/evolution/evolution-deployment-loader.js +56 -0
  161. package/src/lib/evolution/evolution-immutable-ledger-segment-store.js +812 -0
  162. package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +218 -0
  163. package/src/lib/evolution/evolution-ledger-manifest-catalog.js +472 -0
  164. package/src/lib/evolution/evolution-ledger-manifest-chain.js +997 -0
  165. package/src/lib/evolution/evolution-ledger-manifest-head-store.js +408 -0
  166. package/src/lib/evolution/evolution-ledger-manifest-witness-adapter.js +554 -0
  167. package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +460 -0
  168. package/src/lib/evolution/governed-skill-synthesis-attestor-ipc-endpoint.js +94 -0
  169. package/src/lib/evolution/governed-skill-synthesis-attestor-trust-approval-client.js +485 -0
  170. package/src/lib/evolution/governed-skill-synthesis-attestor-trust-ipc-capability.js +200 -0
  171. package/src/lib/evolution/governed-skill-synthesis-attestor-trust-ledger.js +1222 -0
  172. package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operations-cli-host.js +802 -0
  173. package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operations-client.js +445 -0
  174. package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operations.js +1082 -0
  175. package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operator-registry.js +1453 -0
  176. package/src/lib/evolution/governed-skill-synthesis-candidate-evaluator.js +147 -0
  177. package/src/lib/evolution/governed-skill-synthesis-cli-host.js +115 -0
  178. package/src/lib/evolution/governed-skill-synthesis-evaluation-ledger-adapter.js +715 -0
  179. package/src/lib/evolution/governed-skill-synthesis-external-attestor.js +499 -0
  180. package/src/lib/evolution/governed-skill-synthesis-model-evaluator.js +514 -0
  181. package/src/lib/evolution/governed-skill-synthesis-process-attestor-worker.mjs +208 -0
  182. package/src/lib/evolution/governed-skill-synthesis-process-attestor.js +557 -0
  183. package/src/lib/evolution/governed-skill-synthesis-process-grader-worker.mjs +143 -0
  184. package/src/lib/evolution/governed-skill-synthesis-process-grader.js +444 -0
  185. package/src/lib/evolution/governed-skill-synthesis-provider-chat.js +220 -0
  186. package/src/lib/evolution/governed-skill-synthesis-windows-secure-pipe-host.js +236 -0
  187. package/src/lib/hook-audit-store.js +68 -2
  188. package/src/lib/hooks-v2-runtime.js +52 -26
  189. package/src/lib/learning/skill-synthesizer.js +66 -5
  190. package/src/lib/remote-read-loop-guard.js +30 -3
  191. package/src/assets/web-panel/assets/devWarning-0tgDCszN.js +0 -1
  192. package/src/assets/web-panel/assets/index-CFF8XEFE.js +0 -1
  193. package/src/assets/web-panel/assets/index-DVUEISry.js +0 -1
@@ -0,0 +1,557 @@
1
+ import {
2
+ createHash,
3
+ createPrivateKey,
4
+ createPublicKey,
5
+ verify,
6
+ } from "node:crypto";
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import { fileURLToPath } from "node:url";
10
+ import { types as utilTypes } from "node:util";
11
+
12
+ import executionBroker, {
13
+ SANDBOX_BOUNDARIES,
14
+ } from "../process-execution-broker/index.js";
15
+
16
+ export const GOVERNED_SKILL_SYNTHESIS_PROCESS_ATTESTOR_SCHEMA =
17
+ "chainlesschain.governed-skill-synthesis-process-attestor/v1";
18
+ export const GOVERNED_SKILL_SYNTHESIS_EVALUATION_ATTESTATION_SCHEMA =
19
+ "chainlesschain.skill-synthesis-evaluation-attestation/v1";
20
+
21
+ const REQUEST_SCHEMA =
22
+ "chainlesschain.skill-synthesis-process-attestor-request/v1";
23
+ const WORKER = fileURLToPath(
24
+ new URL(
25
+ "./governed-skill-synthesis-process-attestor-worker.mjs",
26
+ import.meta.url,
27
+ ),
28
+ );
29
+ const CREDENTIAL_RESOLVER = fileURLToPath(
30
+ new URL(
31
+ "../process-execution-broker/credential-transport.js",
32
+ import.meta.url,
33
+ ),
34
+ );
35
+ const AUTHORITIES = new WeakSet();
36
+ const OPTION_KEYS = new Set([
37
+ "memoryLimitMb",
38
+ "privateKeyPem",
39
+ "publicKeyPem",
40
+ "timeoutMs",
41
+ ]);
42
+ const REQUEST_KEYS = new Set([
43
+ "candidateDigest",
44
+ "descriptor",
45
+ "receiptDigest",
46
+ ]);
47
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
48
+ const MAX_OUTPUT_BYTES = 32 * 1024;
49
+ const REQUIRED_SANDBOX_BOUNDARIES = Object.freeze([
50
+ SANDBOX_BOUNDARIES.PRIVILEGE_REDUCTION,
51
+ SANDBOX_BOUNDARIES.PROCESS_TREE,
52
+ SANDBOX_BOUNDARIES.RESOURCE_LIMITS,
53
+ ]);
54
+
55
+ function sha256(bytes) {
56
+ return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
57
+ }
58
+
59
+ function canonical(value) {
60
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
61
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
62
+ return `{${Object.keys(value)
63
+ .sort()
64
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
65
+ .join(",")}}`;
66
+ }
67
+
68
+ function exactRecord(value, label, keys) {
69
+ if (
70
+ !value ||
71
+ typeof value !== "object" ||
72
+ Array.isArray(value) ||
73
+ utilTypes.isProxy(value) ||
74
+ Object.getPrototypeOf(value) !== Object.prototype
75
+ ) {
76
+ throw new TypeError(`${label} must be a plain object`);
77
+ }
78
+ const descriptors = Object.getOwnPropertyDescriptors(value);
79
+ if (
80
+ Reflect.ownKeys(descriptors).length !== keys.size ||
81
+ Reflect.ownKeys(descriptors).some(
82
+ (key) =>
83
+ typeof key !== "string" ||
84
+ !keys.has(key) ||
85
+ !("value" in descriptors[key]) ||
86
+ descriptors[key].enumerable !== true,
87
+ )
88
+ ) {
89
+ throw new TypeError(`${label} has unexpected or missing fields`);
90
+ }
91
+ return value;
92
+ }
93
+
94
+ function allowedRecord(value, label, keys) {
95
+ if (
96
+ !value ||
97
+ typeof value !== "object" ||
98
+ Array.isArray(value) ||
99
+ utilTypes.isProxy(value) ||
100
+ Object.getPrototypeOf(value) !== Object.prototype
101
+ ) {
102
+ throw new TypeError(`${label} must be a plain object`);
103
+ }
104
+ const descriptors = Object.getOwnPropertyDescriptors(value);
105
+ if (
106
+ Reflect.ownKeys(descriptors).some(
107
+ (key) =>
108
+ typeof key !== "string" ||
109
+ !keys.has(key) ||
110
+ !("value" in descriptors[key]) ||
111
+ descriptors[key].enumerable !== true,
112
+ )
113
+ ) {
114
+ throw new TypeError(`${label} contains unsupported fields`);
115
+ }
116
+ return value;
117
+ }
118
+
119
+ function boundedString(value, label, maximum = 256) {
120
+ if (
121
+ typeof value !== "string" ||
122
+ value.length === 0 ||
123
+ value.length > maximum ||
124
+ value.trim() !== value ||
125
+ value.includes("\0")
126
+ ) {
127
+ throw new TypeError(`${label} must be a non-empty bounded string`);
128
+ }
129
+ return value;
130
+ }
131
+
132
+ function boundedSecret(value, label, maximum) {
133
+ if (
134
+ typeof value !== "string" ||
135
+ value.trim().length === 0 ||
136
+ value.length > maximum ||
137
+ value.includes("\0")
138
+ ) {
139
+ throw new TypeError(`${label} must be bounded text`);
140
+ }
141
+ return value;
142
+ }
143
+
144
+ function integer(value, label, minimum, maximum) {
145
+ if (!Number.isSafeInteger(value) || value < minimum || value > maximum) {
146
+ throw new TypeError(`${label} must be from ${minimum} to ${maximum}`);
147
+ }
148
+ return value;
149
+ }
150
+
151
+ function evaluatorDescriptor(value) {
152
+ exactRecord(
153
+ value,
154
+ "evaluation attestor descriptor",
155
+ new Set(["authorityId", "handlerArtifactDigest", "revision"]),
156
+ );
157
+ if (
158
+ !DIGEST.test(value.handlerArtifactDigest ?? "") ||
159
+ !Number.isSafeInteger(value.revision) ||
160
+ value.revision < 1
161
+ ) {
162
+ throw new TypeError("evaluation attestor descriptor binding is invalid");
163
+ }
164
+ return Object.freeze({
165
+ authorityId: boundedString(value.authorityId, "evaluation authority"),
166
+ handlerArtifactDigest: value.handlerArtifactDigest,
167
+ revision: value.revision,
168
+ });
169
+ }
170
+
171
+ function snapshot(target, label) {
172
+ const stat = fs.lstatSync(target);
173
+ if (!stat.isFile() || stat.isSymbolicLink() || stat.nlink !== 1) {
174
+ throw new Error(`${label} is not a single-link regular file`);
175
+ }
176
+ const physical = fs.realpathSync.native(target);
177
+ const bytes = fs.readFileSync(physical);
178
+ if (bytes.length === 0 || bytes.length > 128 * 1024) {
179
+ throw new Error(`${label} size is invalid`);
180
+ }
181
+ return Object.freeze({ physical, size: bytes.length, digest: sha256(bytes) });
182
+ }
183
+
184
+ function executionSnapshot() {
185
+ return Object.freeze({
186
+ worker: snapshot(WORKER, "process attestor worker"),
187
+ credentialResolver: snapshot(
188
+ CREDENTIAL_RESOLVER,
189
+ "process attestor credential resolver",
190
+ ),
191
+ });
192
+ }
193
+
194
+ function snapshotMatches(left, right) {
195
+ return ["worker", "credentialResolver"].every(
196
+ (key) =>
197
+ left[key].physical === right[key].physical &&
198
+ left[key].size === right[key].size &&
199
+ left[key].digest === right[key].digest,
200
+ );
201
+ }
202
+
203
+ function minimalEnvironment(privateKeyPem) {
204
+ const environment = { CC_EVOLUTION_ATTESTOR_PRIVATE_KEY: privateKeyPem };
205
+ if (process.platform !== "win32") return environment;
206
+ for (const key of ["SystemRoot", "WINDIR", "TEMP", "TMP"]) {
207
+ const value = process.env[key];
208
+ if (
209
+ typeof value === "string" &&
210
+ value.length > 0 &&
211
+ value.length <= 32 * 1024 &&
212
+ !value.includes("\0")
213
+ ) {
214
+ environment[key] = value;
215
+ }
216
+ }
217
+ if (!environment.SystemRoot && !environment.WINDIR) {
218
+ throw new Error("Windows process attestor requires a system root");
219
+ }
220
+ return environment;
221
+ }
222
+
223
+ function signingMessage(request, attestor) {
224
+ return Buffer.from(
225
+ `${GOVERNED_SKILL_SYNTHESIS_EVALUATION_ATTESTATION_SCHEMA}\0${canonical({
226
+ receiptDigest: request.receiptDigest,
227
+ candidateDigest: request.candidateDigest,
228
+ evaluatorDescriptor: request.descriptor,
229
+ attestor,
230
+ })}`,
231
+ "utf8",
232
+ );
233
+ }
234
+
235
+ function runAttestor({
236
+ request,
237
+ descriptor,
238
+ privateKeyPem,
239
+ snapshot: pinned,
240
+ timeoutMs,
241
+ memoryLimitMb,
242
+ }) {
243
+ return new Promise((resolve, reject) => {
244
+ const child = executionBroker.spawn(
245
+ process.execPath,
246
+ [
247
+ `--max-old-space-size=${memoryLimitMb}`,
248
+ ...(process.platform === "win32"
249
+ ? []
250
+ : [
251
+ "--experimental-permission",
252
+ `--allow-fs-read=${pinned.worker.physical}`,
253
+ `--allow-fs-read=${pinned.credentialResolver.physical}`,
254
+ ]),
255
+ pinned.worker.physical,
256
+ ],
257
+ {
258
+ cwd: path.dirname(pinned.worker.physical),
259
+ env: minimalEnvironment(privateKeyPem),
260
+ credentialTargetHost: descriptor.credentialTarget,
261
+ credentialTtlMs: descriptor.credentialTtlMs,
262
+ credentialMaxUses: descriptor.credentialMaxUses,
263
+ policy: "allow",
264
+ requirePersistentAudit: true,
265
+ sandboxPolicy: {
266
+ profile: descriptor.sandboxProfile,
267
+ requiredBoundaries: REQUIRED_SANDBOX_BOUNDARIES,
268
+ },
269
+ shell: false,
270
+ windowsHide: true,
271
+ stdio: ["pipe", "pipe", "pipe"],
272
+ origin: "governed-skill-synthesis-process-attestor",
273
+ reason: "Sign one bounded learning synthesis evaluation receipt",
274
+ },
275
+ );
276
+ let stdout = "";
277
+ let stderr = "";
278
+ let terminalError = null;
279
+ let settled = false;
280
+ const finish = (callback, value) => {
281
+ if (settled) return;
282
+ settled = true;
283
+ clearTimeout(timer);
284
+ callback(value);
285
+ };
286
+ const timer = setTimeout(() => {
287
+ terminalError = new Error(
288
+ `learning synthesis process attestor timed out after ${timeoutMs}ms`,
289
+ );
290
+ terminalError.code = "LEARNING_SYNTHESIS_PROCESS_ATTESTOR_TIMEOUT";
291
+ child.kill("SIGKILL");
292
+ }, timeoutMs);
293
+ timer.unref?.();
294
+ for (const [stream, append] of [
295
+ [child.stdout, (chunk) => (stdout += chunk.toString("utf8"))],
296
+ [child.stderr, (chunk) => (stderr += chunk.toString("utf8"))],
297
+ ]) {
298
+ stream.on("data", (chunk) => {
299
+ append(chunk);
300
+ if (
301
+ Buffer.byteLength(stream === child.stdout ? stdout : stderr, "utf8") >
302
+ MAX_OUTPUT_BYTES
303
+ ) {
304
+ terminalError = new Error(
305
+ "process attestor output exceeded its bound",
306
+ );
307
+ child.kill("SIGKILL");
308
+ }
309
+ });
310
+ }
311
+ child.once("error", (error) => finish(reject, error));
312
+ child.once("close", (code, signal) => {
313
+ if (terminalError) return finish(reject, terminalError);
314
+ if (code !== 0) {
315
+ return finish(
316
+ reject,
317
+ new Error(
318
+ `learning synthesis process attestor exited ${code ?? "null"}/${signal ?? "none"}: ${stderr.slice(0, 256)}`,
319
+ ),
320
+ );
321
+ }
322
+ try {
323
+ const lines = stdout.trimEnd().split("\n");
324
+ if (lines.length !== 1) throw new Error("multiple output records");
325
+ const result = JSON.parse(lines[0]);
326
+ exactRecord(
327
+ result,
328
+ "process attestor output",
329
+ new Set(["attestation", "ok"]),
330
+ );
331
+ if (result.ok !== true) throw new Error("attestor output was not ok");
332
+ finish(resolve, result.attestation);
333
+ } catch (cause) {
334
+ finish(
335
+ reject,
336
+ new Error("learning synthesis process attestor output is invalid", {
337
+ cause,
338
+ }),
339
+ );
340
+ }
341
+ });
342
+ child.stdin.once("error", (error) => {
343
+ terminalError ??= error;
344
+ });
345
+ child.stdin.end(
346
+ JSON.stringify({
347
+ schema: REQUEST_SCHEMA,
348
+ receiptDigest: request.receiptDigest,
349
+ candidateDigest: request.candidateDigest,
350
+ evaluatorDescriptor: request.descriptor,
351
+ attestor: descriptor,
352
+ }),
353
+ );
354
+ });
355
+ }
356
+
357
+ export function createGovernedSkillSynthesisProcessAttestationAuthority(
358
+ options = {},
359
+ ) {
360
+ allowedRecord(options, "process attestor options", OPTION_KEYS);
361
+ const privateKeyPem = boundedSecret(
362
+ options.privateKeyPem,
363
+ "process attestor privateKeyPem",
364
+ 16 * 1024,
365
+ );
366
+ const publicKeyPem = boundedSecret(
367
+ options.publicKeyPem,
368
+ "process attestor publicKeyPem",
369
+ 16 * 1024,
370
+ );
371
+ const privateKey = createPrivateKey(privateKeyPem);
372
+ const publicKey = createPublicKey(publicKeyPem);
373
+ if (
374
+ privateKey.asymmetricKeyType !== "ed25519" ||
375
+ publicKey.asymmetricKeyType !== "ed25519"
376
+ ) {
377
+ throw new TypeError("process attestor keys must be Ed25519");
378
+ }
379
+ const derivedPublic = createPublicKey(privateKey).export({
380
+ type: "spki",
381
+ format: "der",
382
+ });
383
+ const publicDer = publicKey.export({ type: "spki", format: "der" });
384
+ if (!Buffer.from(derivedPublic).equals(Buffer.from(publicDer))) {
385
+ throw new TypeError("process attestor key pair does not match");
386
+ }
387
+ const timeoutMs = integer(
388
+ options.timeoutMs ?? 5_000,
389
+ "process attestor timeoutMs",
390
+ 1_000,
391
+ 30_000,
392
+ );
393
+ const memoryLimitMb = integer(
394
+ options.memoryLimitMb ?? 64,
395
+ "process attestor memoryLimitMb",
396
+ 32,
397
+ 256,
398
+ );
399
+ const pinned = executionSnapshot();
400
+ const publicKeyDigest = sha256(publicDer);
401
+ const descriptor = Object.freeze({
402
+ schema: GOVERNED_SKILL_SYNTHESIS_PROCESS_ATTESTOR_SCHEMA,
403
+ algorithm: "Ed25519",
404
+ keyId: `key:ed25519:${publicKeyDigest.slice(7)}`,
405
+ publicKeyDigest,
406
+ isolation: "process",
407
+ workerArtifactDigest: pinned.worker.digest,
408
+ credentialResolverArtifactDigest: pinned.credentialResolver.digest,
409
+ credentialDelivery: "single-use-broker-reference",
410
+ credentialTarget: "governed-skill-attestor.local",
411
+ credentialMaxUses: 1,
412
+ credentialTtlMs: Math.min(timeoutMs + 5_000, 35_000),
413
+ hardDeadlineEnforced: true,
414
+ sandboxProfile: "network-only",
415
+ requiredSandboxBoundaries: REQUIRED_SANDBOX_BOUNDARIES,
416
+ persistentProcessAuditRequired: true,
417
+ });
418
+ const normalizeRequest = (value) => {
419
+ exactRecord(value, "process attestor request", REQUEST_KEYS);
420
+ if (
421
+ !DIGEST.test(value.receiptDigest ?? "") ||
422
+ !DIGEST.test(value.candidateDigest ?? "")
423
+ ) {
424
+ throw new TypeError("process attestor request digests are invalid");
425
+ }
426
+ return Object.freeze({
427
+ receiptDigest: value.receiptDigest,
428
+ candidateDigest: value.candidateDigest,
429
+ descriptor: evaluatorDescriptor(value.descriptor),
430
+ });
431
+ };
432
+ const attestReceipt = async (value) => {
433
+ const request = normalizeRequest(value);
434
+ if (!snapshotMatches(executionSnapshot(), pinned)) {
435
+ throw new Error("process attestor artifacts changed after construction");
436
+ }
437
+ const attestation = await runAttestor({
438
+ request,
439
+ descriptor,
440
+ privateKeyPem,
441
+ snapshot: pinned,
442
+ timeoutMs,
443
+ memoryLimitMb,
444
+ });
445
+ if (!snapshotMatches(executionSnapshot(), pinned)) {
446
+ throw new Error("process attestor artifacts changed during execution");
447
+ }
448
+ return attestation;
449
+ };
450
+ const verifyAttestation = async (value) => {
451
+ if (
452
+ !value ||
453
+ typeof value !== "object" ||
454
+ Array.isArray(value) ||
455
+ utilTypes.isProxy(value) ||
456
+ Object.getPrototypeOf(value) !== Object.prototype
457
+ ) {
458
+ return false;
459
+ }
460
+ const inputDescriptors = Object.getOwnPropertyDescriptors(value);
461
+ const inputKeys = new Set([
462
+ "attestation",
463
+ "candidateDigest",
464
+ "descriptor",
465
+ "receiptDigest",
466
+ ]);
467
+ if (
468
+ Reflect.ownKeys(inputDescriptors).length !== inputKeys.size ||
469
+ Reflect.ownKeys(inputDescriptors).some(
470
+ (key) =>
471
+ typeof key !== "string" ||
472
+ !inputKeys.has(key) ||
473
+ !("value" in inputDescriptors[key]) ||
474
+ inputDescriptors[key].enumerable !== true,
475
+ )
476
+ ) {
477
+ return false;
478
+ }
479
+ let request;
480
+ try {
481
+ request = normalizeRequest({
482
+ receiptDigest: inputDescriptors.receiptDigest.value,
483
+ candidateDigest: inputDescriptors.candidateDigest.value,
484
+ descriptor: inputDescriptors.descriptor.value,
485
+ });
486
+ } catch {
487
+ return false;
488
+ }
489
+ const attestation = inputDescriptors.attestation.value;
490
+ if (
491
+ !attestation ||
492
+ typeof attestation !== "object" ||
493
+ Array.isArray(attestation) ||
494
+ utilTypes.isProxy(attestation)
495
+ ) {
496
+ return false;
497
+ }
498
+ const descriptors = Object.getOwnPropertyDescriptors(attestation);
499
+ const expectedKeys = new Set([
500
+ ...Object.keys(descriptor).filter((key) => key !== "schema"),
501
+ "attestorSchema",
502
+ "schema",
503
+ "signature",
504
+ ]);
505
+ if (
506
+ Reflect.ownKeys(descriptors).length !== expectedKeys.size ||
507
+ Reflect.ownKeys(descriptors).some(
508
+ (key) =>
509
+ typeof key !== "string" ||
510
+ !expectedKeys.has(key) ||
511
+ !("value" in descriptors[key]) ||
512
+ descriptors[key].enumerable !== true,
513
+ )
514
+ ) {
515
+ return false;
516
+ }
517
+ const { schema, attestorSchema, signature, ...execution } = attestation;
518
+ if (
519
+ schema !== GOVERNED_SKILL_SYNTHESIS_EVALUATION_ATTESTATION_SCHEMA ||
520
+ attestorSchema !== descriptor.schema ||
521
+ canonical(execution) !==
522
+ canonical(
523
+ Object.fromEntries(
524
+ Object.entries(descriptor).filter(([key]) => key !== "schema"),
525
+ ),
526
+ ) ||
527
+ typeof signature !== "string" ||
528
+ signature.length === 0 ||
529
+ signature.length > 1024
530
+ ) {
531
+ return false;
532
+ }
533
+ try {
534
+ return verify(
535
+ null,
536
+ signingMessage(request, descriptor),
537
+ publicKey,
538
+ Buffer.from(signature, "base64"),
539
+ );
540
+ } catch {
541
+ return false;
542
+ }
543
+ };
544
+ Object.freeze(attestReceipt);
545
+ Object.freeze(verifyAttestation);
546
+ const authority = Object.freeze({
547
+ descriptor,
548
+ attestReceipt,
549
+ verifyAttestation,
550
+ });
551
+ AUTHORITIES.add(authority);
552
+ return authority;
553
+ }
554
+
555
+ export function isGovernedSkillSynthesisProcessAttestationAuthority(value) {
556
+ return AUTHORITIES.has(value);
557
+ }
@@ -0,0 +1,143 @@
1
+ import { resolveCredentialEnvironmentValue } from "../process-execution-broker/credential-transport.js";
2
+
3
+ const MAX_INPUT_BYTES = 96 * 1024;
4
+ const MAX_MESSAGES = 8;
5
+ const MAX_PROMPT_BYTES = 64 * 1024;
6
+ const ENDPOINT = "https://ark.cn-beijing.volces.com/api/v3";
7
+
8
+ function fail(message) {
9
+ throw new Error(message);
10
+ }
11
+
12
+ function boundedString(value, label, maximum) {
13
+ if (
14
+ typeof value !== "string" ||
15
+ value.length === 0 ||
16
+ value.length > maximum ||
17
+ value.trim() !== value ||
18
+ value.includes("\0")
19
+ ) {
20
+ fail(`${label} is invalid`);
21
+ }
22
+ return value;
23
+ }
24
+
25
+ function boundedText(value, label, maximum) {
26
+ if (
27
+ typeof value !== "string" ||
28
+ value.trim().length === 0 ||
29
+ value.length > maximum ||
30
+ value.includes("\0")
31
+ ) {
32
+ fail(`${label} is invalid`);
33
+ }
34
+ return value;
35
+ }
36
+
37
+ let input = "";
38
+ for await (const chunk of process.stdin) {
39
+ input += chunk.toString("utf8");
40
+ if (Buffer.byteLength(input, "utf8") > MAX_INPUT_BYTES) {
41
+ fail("grader input exceeds its byte limit");
42
+ }
43
+ }
44
+
45
+ let request;
46
+ try {
47
+ request = JSON.parse(input);
48
+ } catch {
49
+ fail("grader input is not JSON");
50
+ }
51
+ if (
52
+ !request ||
53
+ typeof request !== "object" ||
54
+ Array.isArray(request) ||
55
+ Object.keys(request).sort().join(",") !==
56
+ "baseUrl,maxTokens,messages,model,provider,schema,timeoutMs"
57
+ ) {
58
+ fail("grader input schema is invalid");
59
+ }
60
+ if (
61
+ request.schema !==
62
+ "chainlesschain.skill-synthesis-process-grader-request/v2" ||
63
+ request.provider !== "volcengine" ||
64
+ request.baseUrl.replace(/\/$/u, "") !== ENDPOINT
65
+ ) {
66
+ fail("grader provider boundary is invalid");
67
+ }
68
+ const model = boundedString(request.model, "grader model", 256);
69
+ if (
70
+ !Number.isSafeInteger(request.maxTokens) ||
71
+ request.maxTokens < 128 ||
72
+ request.maxTokens > 4096 ||
73
+ !Number.isSafeInteger(request.timeoutMs) ||
74
+ request.timeoutMs < 1000 ||
75
+ request.timeoutMs > 120000 ||
76
+ !Array.isArray(request.messages) ||
77
+ request.messages.length === 0 ||
78
+ request.messages.length > MAX_MESSAGES
79
+ ) {
80
+ fail("grader request bounds are invalid");
81
+ }
82
+ let promptBytes = 0;
83
+ const messages = request.messages.map((message) => {
84
+ if (
85
+ !message ||
86
+ typeof message !== "object" ||
87
+ Array.isArray(message) ||
88
+ Object.keys(message).sort().join(",") !== "content,role" ||
89
+ !["assistant", "system", "user"].includes(message.role)
90
+ ) {
91
+ fail("grader message schema is invalid");
92
+ }
93
+ const content = boundedText(
94
+ message.content,
95
+ "grader message content",
96
+ MAX_PROMPT_BYTES,
97
+ );
98
+ promptBytes += Buffer.byteLength(content, "utf8");
99
+ return { role: message.role, content };
100
+ });
101
+ if (promptBytes > MAX_PROMPT_BYTES)
102
+ fail("grader prompt exceeds its byte limit");
103
+
104
+ const controller = new AbortController();
105
+ const timer = setTimeout(() => controller.abort(), request.timeoutMs);
106
+ timer.unref?.();
107
+ try {
108
+ if (Object.hasOwn(process.env, "VOLCENGINE_API_KEY")) {
109
+ fail("grader refuses plaintext environment credentials");
110
+ }
111
+ const apiKey = boundedString(
112
+ await resolveCredentialEnvironmentValue("VOLCENGINE_API_KEY", {
113
+ env: process.env,
114
+ }),
115
+ "grader credential",
116
+ 16 * 1024,
117
+ );
118
+ const response = await fetch(`${ENDPOINT}/chat/completions`, {
119
+ method: "POST",
120
+ headers: {
121
+ Authorization: `Bearer ${apiKey}`,
122
+ "Content-Type": "application/json",
123
+ },
124
+ body: JSON.stringify({
125
+ model,
126
+ messages,
127
+ max_tokens: request.maxTokens,
128
+ stream: false,
129
+ }),
130
+ signal: controller.signal,
131
+ });
132
+ if (!response.ok)
133
+ fail(`grader provider rejected the request (${response.status})`);
134
+ const payload = await response.json();
135
+ const content = payload?.choices?.[0]?.message?.content;
136
+ boundedText(content, "grader provider response", 64 * 1024);
137
+ process.stdout.write(`${JSON.stringify({ ok: true, content })}\n`);
138
+ } catch (error) {
139
+ if (controller.signal.aborted) fail("grader provider deadline exceeded");
140
+ throw error;
141
+ } finally {
142
+ clearTimeout(timer);
143
+ }