chainlesschain 0.166.20 → 0.166.22

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 (222) hide show
  1. package/README.md +67 -9
  2. package/package.json +2 -2
  3. package/src/assets/web-panel/assets/{AIOps-CcJst5Zs.js → AIOps-oJ7USzMC.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-BpHPFKd3.js → ActionButton-BlgnZe_C.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-DHAsASuS.js → Analytics-D2rRbTLu.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-BTKwo5RC.js → AppLayout-FwS3f0B2.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-BcCBTggA.js → Artifacts-iF-_08Hi.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-z1JvJYbT.js → Audit-D24p0zQw.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-CJ7DCMDR.js → BackgroundAgents-Cg3mRVi9.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-CKpxw4uw.js → Backup-EOqht3H-.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-2jI_IlUB.js → BaseInput-9XWYq2hj.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-C_4RfBeN.js → Chat-Dq5yardA.js} +5 -5
  13. package/src/assets/web-panel/assets/ChatBubbleRenderer-Ds3pA-ET.js +1 -0
  14. package/src/assets/web-panel/assets/{Checkbox-BnF4z4N1.js → Checkbox-CuyCBoBf.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-m_LMamhM.js → Codegen-DjWtYHNe.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-DzMbA760.js → Col-CrVr_iuG.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-SScuZUcW.js → Community-C6QxpfGc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-CiOHRvwQ.js → Compact-B-v5r6Pa.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-97FzYz-6.js → Compliance-zNiLiFgD.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-C0ss-SRl.js → Cowork-D9K7lMOu.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-CCbdc9fp.js → Cron-DAjO36z4.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-BPnabXej.js → Crosschain-Bxqn0aqB.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-B65hFnHs.js → DID-DfRmLUe-.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-B6qR_TF2.js → Dashboard-Cz8KF3fr.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-6c-2Fxm-.js → Dropdown-C4oVfkP0.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-GD57mfiz.js → EmailListRenderer-ivyZKN8k.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-B2mxG6LN.js → FamilyGuardDashboard-DoxY1CPW.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-cZS-uvAo.js → Federation-C93gZxnb.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-UbSfBIe1.js → FormItemContext-D_lEjYJE.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-BMAtvGt1.js → GenericCardRenderer-BNFN9YjN.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-DAlhOiDA.js → Git-mUu2HcLI.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-B-RRVaP8.js → Governance-CNuosrge.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-DBl-pXYR.js → Inference-DwY5pbCB.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-DjqOkvgY.js → KnowledgeGraph-aRUxhACD.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-CEV7AEAD.js → Logs-DFfsWYy_.js} +2 -2
  36. package/src/assets/web-panel/assets/{MarkdownRenderer-BDCxa4d1.js → MarkdownRenderer-DqTx7_u1.js} +1 -1
  37. package/src/assets/web-panel/assets/{Marketplace-oRjzfmYJ.js → Marketplace-COI-ciM-.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BiTnznLw.js → McpTools-BJJwaIpe.js} +3 -3
  39. package/src/assets/web-panel/assets/{Memory-DR0C5K4N.js → Memory-CDO6SGDZ.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge--oR8wEcp.js → MobileBridge-BlZ5tFf4.js} +1 -1
  41. package/src/assets/web-panel/assets/{MobileProjects-DKqpYMuG.js → MobileProjects-DuoxbgWz.js} +1 -1
  42. package/src/assets/web-panel/assets/{Mtc-Dg0D6fDQ.js → Mtc-6ec9j70b.js} +2 -2
  43. package/src/assets/web-panel/assets/{MtcAudit-D4_-yWTK.js → MtcAudit-BuL7HkC7.js} +5 -5
  44. package/src/assets/web-panel/assets/{Multisig-Coz55FxA.js → Multisig-CJxR85lk.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-BWVjgW9Y.js → NLProgramming-B71O1S4l.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-BflVuGwr.js → Notes-Bsw5zbpV.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-CT0F_dJ7.js → NotificationSettings-BnAhXuK_.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-Dyrnqy_o.js → OrderTableRenderer-BJ0R5GGz.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-CMDTM2z5.js → Organization-B7wwNxoP.js} +2 -2
  50. package/src/assets/web-panel/assets/{Overflow-acKvvYpC.js → Overflow-CfAGr0gM.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CRq5j9Ax.js → P2P-KhMg22Fz.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-DmtzN6Kn.js → PdhVaultBrowser-NdAXI9ft.js} +4 -4
  53. package/src/assets/web-panel/assets/{Permissions-SZ-kjJDa.js → Permissions-CIYjqyT7.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-DXh-ZfgJ.js → PersonalDataHub-D2ht3P_R.js} +6 -6
  55. package/src/assets/web-panel/assets/{Pipeline-DhBU9ftP.js → Pipeline-i6flZW1m.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-BgEXpO_V.js → Privacy-DE0lhYVc.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-B2DJ-dmK.js → ProjectInit-BL3YbyxS.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-ve3SocWc.js → ProjectSettings-CEtdg7ni.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-5ZvFasSJ.js → Projects-CvtU5peJ.js} +1 -1
  60. package/src/assets/web-panel/assets/{Providers-C8fcF3BK.js → Providers-DKt_Cg-j.js} +1 -1
  61. package/src/assets/web-panel/assets/{QrScannerModal-unjO8lNO.js → QrScannerModal-DA61jNSx.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-BT1QtT7D.js → QuickAsk-fS9ryUmq.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-BSjFrY1w.js → Recommend-CR9dZU5Y.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-CWV0bICg.js → RemoteSession-BV0BR2Dz.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-BMjiMsk2.js → Reputation-BIeGUvYD.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-9XCY22PM.js → Row-DHDT1aro.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-DQ9PDy7Q.js → RssFeed-Cq6YKb1h.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-Boym2HwG.js → Search-DEF6vsy6.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-Gbq3lGQb.js → Security-CHtYiKY9.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-OcUfLdnu.js → Services-u16lvBJN.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-BjTog6cA.js → Skeleton-CGbizyDj.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-Dny4ft_1.js → Skills-BZMQcAa7.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-Cy_VnhpZ.js → Sla-Bm-CycVi.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-CrFuL_lp.js → SpeechSettings-BudpA5kr.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-k-FnjuOR.js → SyncSettings-B8q1C1eC.js} +2 -2
  76. package/src/assets/web-panel/assets/{Tasks-ZEqDSo0_.js → Tasks-SU1pBWc-.js} +1 -1
  77. package/src/assets/web-panel/assets/{Templates-CYYksYV5.js → Templates-CyOfJzmt.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-BvTTRTHS.js → Tenant-xqWSm2GP.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-DMOQOtkj.js → Terminal-D1Ttgjsi.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-CnudkJxk.js → TimelineRenderer-Da2lYs5D.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-VW6Wocdp.js → Tokens-B34-SduO.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-BtOxZqP6.js → Trigger-C8zyYm4R.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-XcGJoTQx.js → Trust-D1Pvqems.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-aASNCs5j.js → UkeySign-Do3VVnAy.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-Bz89M52u.js → VideoEditing-Dz7egVIA.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-uU4dSS_N.js → Wallet-Dcuw-OxR.js} +3 -3
  87. package/src/assets/web-panel/assets/{WebAuthn-Brrroxgr.js → WebAuthn-DPlw-QsB.js} +3 -3
  88. package/src/assets/web-panel/assets/{WorkflowEditor-Cny-evI9.js → WorkflowEditor-h4OsnU5q.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-CJ5iSwWq.js → chat-eO9wEwrW.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-DWa-2flG.js → colors-34lSmOXw.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-DFwUfptU.js → compact-item-CK4kEWJ4.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-FHWWcyeB.js → createContext-E0A57xed.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-CF3xafX2.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-QY_TElrN.js → hasIn-BD9ZMGAl.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-BcVr-LOk.js → index--N0u6kTG.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CUiTugu3.js → index-8qMA1DWQ.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-0umhind6.js → index-B0rkHxKK.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-wqiOz655.js → index-B_G_ElKO.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B18zERdP.js → index-BbX_Dted.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Dy2PnKZx.js → index-Bjs90Eh9.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-th467RN6.js → index-BmNbU2Z6.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-uRUZdL7I.js → index-Brqc9Emx.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-hw1J_Oxs.js → index-BsGmo6v1.js} +1 -1
  104. package/src/assets/web-panel/assets/index-C907rPwd.js +1 -0
  105. package/src/assets/web-panel/assets/{index-CjejB-z9.js → index-CT1_eRL-.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DaHvj4jA.js → index-CZBaqe3d.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B33frlaD.js → index-CZkFMeWL.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BYbwQ7SP.js → index-Ch175NUw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-va4Rt-yM.js → index-CsrKJJcX.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DDpXDi4J.js → index-CuSau5ya.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-D-Mhq8K6.js → index-Cx3Jn1r0.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-CKS7n6mE.js → index-Cz3unNfL.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BRsGZBHc.js → index-D4bB_x_v.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Bd7McYpJ.js → index-DCn-ECvK.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DUfILsc-.js → index-DFLE2qO9.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DUepuy7O.js → index-DGRxt5wj.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BR4RMPnB.js → index-DONOUtlz.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Dlq-u9E4.js → index-DP-UZAQN.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DCHMVYG1.js → index-Da5fmOHB.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BiHRihC0.js → index-DcE1BspQ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CGv5In_T.js → index-DcbgVLOH.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BQCtBurK.js → index-DeXNCyQJ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-D2rPJ6Sv.js → index-DiT_REby.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CUoLd1dt.js → index-DpfisY1g.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-2ufsNuVn.js → index-DrOalGut.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-aTiI7lOQ.js → index-DrSAAuJj.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BUNwuu5v.js → index-DrsDA_md.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CkmgbT7h.js → index-DvKcroix.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BEjwv2x6.js → index-DzXjP44T.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CeGn0A4W.js → index-MIg5Z8qe.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-C5F1vwec.js → index-o8pYehRq.js} +3 -3
  132. package/src/assets/web-panel/assets/index-wueRSK2d.js +1 -0
  133. package/src/assets/web-panel/assets/{index-w3SdYwaC.js → index-yAGBu2E0.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-BeSPUFDz.js → initDefaultProps-DMTkAomF.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-Dcajvjm9.js → motion-Cnti1F5g.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-B76orau-.js → move-CGxmHUga.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-zB6yFwcX.js → mtc-parser-CuwwLoq7.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-BsbNjz8w.js → omit-BpdlTkPM.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-BiJ9tssQ.js → pickAttrs-D7nWrThp.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-BdfMjMeN.js → placementArrow-Bhx0TV8F.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-rV4LGpbU.js → responsiveObserve-CZ1KesZh.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-HsVw1qFQ.js → slide-CnldF8J6.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-D1ry8XPE.js → statusUtils-CZfo_GOA.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-B1t6aQQ_.js → styleChecker-B2QCcAv5.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-C8qbl-9w.js → useFlexGapSupport-DzzjIS4J.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-R7g_mYTC.js → useFs-B_atg9M0.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-Cd-kCe7Z.js → usePersonalDataHub-DhZs3QYN.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-9WhK5UWA.js → vnode-DcePTYAm.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-CUqppPco.js → zoom-BYmlnjRk.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/command-help-index.json +2 -2
  152. package/src/commands/agent.js +19 -1
  153. package/src/commands/evolution-knowledge.js +54 -0
  154. package/src/commands/evolution-workbench.js +83 -0
  155. package/src/commands/evolution.js +6 -1
  156. package/src/commands/serve.js +47 -0
  157. package/src/commands/skill.js +158 -16
  158. package/src/data/changelog.json +26 -0
  159. package/src/gateways/ws/session-protocol.js +2 -0
  160. package/src/gateways/ws/ws-agent-handler.js +124 -69
  161. package/src/gateways/ws/ws-server.js +19 -0
  162. package/src/generated/cc-agent-protocol.schema.json +7 -1
  163. package/src/harness/jsonl-session-store.js +25 -1
  164. package/src/index.js +11 -3
  165. package/src/lazy-dispatch.js +9 -1
  166. package/src/lib/app-server/cli-agent-kernel-adapter.js +8 -0
  167. package/src/lib/app-server/graph-runtime.js +40 -1
  168. package/src/lib/app-server/server.js +181 -3
  169. package/src/lib/app-server/websocket-transport.js +23 -0
  170. package/src/lib/evolution/agent-evolution-runtime-composition-brand.js +17 -0
  171. package/src/lib/evolution/agent-evolution-runtime-composition.js +165 -1
  172. package/src/lib/evolution/controlled-skill-production-pilot.js +912 -0
  173. package/src/lib/evolution/evolution-artifact-ports.js +30 -0
  174. package/src/lib/evolution/evolution-deployment-loader.js +208 -0
  175. package/src/lib/evolution/evolution-raw-crypto-shred.js +185 -0
  176. package/src/lib/evolution/evolution-release-train-ledger-adapter.js +335 -0
  177. package/src/lib/evolution/evolution-release-train.js +538 -0
  178. package/src/lib/evolution/evolution-workbench-batch-executor.js +195 -0
  179. package/src/lib/evolution/evolution-workbench-cli-host.js +169 -0
  180. package/src/lib/evolution/evolution-workbench-metrics-ledger-adapter.js +648 -0
  181. package/src/lib/evolution/evolution-workbench-metrics.js +943 -0
  182. package/src/lib/evolution/evolution-workbench-projection.js +753 -0
  183. package/src/lib/evolution/evolution-workbench-version-control.js +272 -0
  184. package/src/lib/evolution/evolvable-artifact-ledger-adapter.js +688 -0
  185. package/src/lib/evolution/governed-knowledge-artifact-lifecycle.js +364 -0
  186. package/src/lib/evolution/governed-knowledge-conflict-merge.js +352 -0
  187. package/src/lib/evolution/governed-knowledge-dependency-authority.js +273 -0
  188. package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +646 -0
  189. package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +671 -0
  190. package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +310 -0
  191. package/src/lib/evolution/governed-knowledge-node-crypto-authority.js +348 -0
  192. package/src/lib/evolution/governed-knowledge-rbac-approval-authority.js +621 -0
  193. package/src/lib/evolution/governed-knowledge-review-host.js +249 -0
  194. package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +729 -0
  195. package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +312 -0
  196. package/src/lib/evolution/governed-knowledge-sync.js +795 -0
  197. package/src/lib/evolution/governed-knowledge-trust-ledger.js +707 -0
  198. package/src/lib/evolution/governed-skill-marketplace.js +430 -0
  199. package/src/lib/evolution/governed-wiki-pruning.js +435 -0
  200. package/src/lib/evolution/skill-outcome-index-authority.js +268 -0
  201. package/src/lib/evolution/skill-outcome-source-catalog-authority.js +237 -0
  202. package/src/lib/evolution/skill-writer-inventory-manifest.js +7 -6
  203. package/src/lib/evolution/statistical-progressive-canary.js +683 -0
  204. package/src/lib/evolution/wikiskill-benchmark.js +510 -0
  205. package/src/lib/public-ide-capability-manifest.js +4 -0
  206. package/src/lib/session-host-lease.js +11 -16
  207. package/src/lib/skill-outcome-authority.js +43 -0
  208. package/src/lib/skill-outcome-transcript-authority.js +252 -0
  209. package/src/lib/skill-retrieval-router-benchmark.js +135 -0
  210. package/src/lib/skill-retrieval-router.js +235 -0
  211. package/src/lib/skill-vector-authority.js +325 -0
  212. package/src/lib/skill-vector-process-authority.js +386 -0
  213. package/src/repl/agent-repl.js +7 -1
  214. package/src/runtime/agent-core.js +133 -13
  215. package/src/runtime/agent-runtime.js +42 -0
  216. package/src/runtime/headless-runner.js +32 -0
  217. package/src/runtime/headless-stream.js +39 -1
  218. package/src/runtime/runtime-factory.js +62 -4
  219. package/src/assets/web-panel/assets/ChatBubbleRenderer-eMmw1eZF.js +0 -1
  220. package/src/assets/web-panel/assets/devWarning-DxufPwXC.js +0 -1
  221. package/src/assets/web-panel/assets/index-ZMTB9p5z.js +0 -1
  222. package/src/assets/web-panel/assets/index-_PvIDelE.js +0 -1
@@ -0,0 +1,325 @@
1
+ import { createHash } from "node:crypto";
2
+ import { types as utilTypes } from "node:util";
3
+
4
+ export const SKILL_VECTOR_REQUEST_SCHEMA =
5
+ "chainlesschain.skill-vector-request/v1";
6
+ export const SKILL_VECTOR_RESULT_SCHEMA =
7
+ "chainlesschain.skill-vector-result/v1";
8
+ export const SKILL_VECTOR_AUTHORITY_SCHEMA =
9
+ "chainlesschain.skill-vector-authority/v1";
10
+ export const SKILL_VECTOR_ATTESTATION_SCHEMA =
11
+ "chainlesschain.skill-vector-attestation/v1";
12
+
13
+ const AUTHORITIES = new WeakSet();
14
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
15
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
16
+ const MAX_SKILLS = 10_000;
17
+ const MAX_TEXT_BYTES = 8 * 1024 * 1024;
18
+ const RESULT_KEYS = new Set([
19
+ "attestation",
20
+ "corpusDigest",
21
+ "indexDigest",
22
+ "modelId",
23
+ "modelRevision",
24
+ "requestDigest",
25
+ "resultDigest",
26
+ "schema",
27
+ "scores",
28
+ "tenantId",
29
+ ]);
30
+ const SCORE_KEYS = new Set(["digest", "score"]);
31
+ const ATTESTATION_KEYS = new Set(["algorithm", "keyId", "schema", "value"]);
32
+ const VERIFICATION_KEYS = new Set([
33
+ "authenticated",
34
+ "durable",
35
+ "receiptDigest",
36
+ "requestDigest",
37
+ "resultDigest",
38
+ "tenantId",
39
+ ]);
40
+
41
+ function canonical(value) {
42
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
43
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
44
+ return `{${Object.keys(value)
45
+ .sort()
46
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
47
+ .join(",")}}`;
48
+ }
49
+
50
+ function hash(domain, value) {
51
+ return `sha256:${createHash("sha256")
52
+ .update(domain)
53
+ .update("\0")
54
+ .update(canonical(value))
55
+ .digest("hex")}`;
56
+ }
57
+
58
+ function exact(value, keys, label) {
59
+ if (
60
+ !value ||
61
+ typeof value !== "object" ||
62
+ Array.isArray(value) ||
63
+ utilTypes.isProxy(value) ||
64
+ Reflect.ownKeys(value).length !== keys.size ||
65
+ Reflect.ownKeys(value).some(
66
+ (key) => typeof key !== "string" || !keys.has(key),
67
+ )
68
+ ) {
69
+ throw new TypeError(`${label} is invalid`);
70
+ }
71
+ for (const key of Reflect.ownKeys(value)) {
72
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
73
+ if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) {
74
+ throw new TypeError(`${label}.${String(key)} is invalid`);
75
+ }
76
+ }
77
+ return value;
78
+ }
79
+
80
+ function identifier(value, label) {
81
+ if (typeof value !== "string" || !SAFE_ID.test(value)) {
82
+ throw new TypeError(`${label} is invalid`);
83
+ }
84
+ return value;
85
+ }
86
+
87
+ function boundedText(value, label, maximum = 4096) {
88
+ if (
89
+ typeof value !== "string" ||
90
+ value.trim() === "" ||
91
+ value.length > maximum
92
+ ) {
93
+ throw new TypeError(`${label} is invalid or unbounded`);
94
+ }
95
+ return value.trim();
96
+ }
97
+
98
+ function capture(owner, method, label) {
99
+ if (!owner || typeof owner !== "object" || utilTypes.isProxy(owner)) {
100
+ throw new TypeError(`${label}.${method}() is required`);
101
+ }
102
+ const operation = owner[method];
103
+ if (typeof operation !== "function" || utilTypes.isProxy(operation)) {
104
+ throw new TypeError(`${label}.${method}() is required`);
105
+ }
106
+ return Object.freeze((...args) => Reflect.apply(operation, owner, args));
107
+ }
108
+
109
+ function corpusFor(skills) {
110
+ if (
111
+ !Array.isArray(skills) ||
112
+ utilTypes.isProxy(skills) ||
113
+ skills.length < 1 ||
114
+ skills.length > MAX_SKILLS
115
+ ) {
116
+ throw new TypeError("Skill vector corpus is invalid or unbounded");
117
+ }
118
+ let bytes = 0;
119
+ const digests = new Set();
120
+ const corpus = skills.map((skill, index) => {
121
+ if (!skill || typeof skill !== "object" || utilTypes.isProxy(skill)) {
122
+ throw new TypeError(`Skill vector corpus[${index}] is invalid`);
123
+ }
124
+ const digest = skill.executionIdentity?.contentDigest;
125
+ if (!DIGEST.test(digest ?? "") || digests.has(digest)) {
126
+ throw new TypeError(
127
+ "Skill vector corpus has a missing or duplicate digest",
128
+ );
129
+ }
130
+ digests.add(digest);
131
+ const entry = {
132
+ digest,
133
+ id: boundedText(skill.id, `skills[${index}].id`, 256),
134
+ displayName: boundedText(
135
+ skill.displayName || skill.id,
136
+ `skills[${index}].displayName`,
137
+ 512,
138
+ ),
139
+ description: boundedText(
140
+ skill.description || "(no description)",
141
+ `skills[${index}].description`,
142
+ 16_384,
143
+ ),
144
+ category: boundedText(
145
+ skill.category || "uncategorized",
146
+ `skills[${index}].category`,
147
+ 128,
148
+ ),
149
+ tags: Array.isArray(skill.tags)
150
+ ? skill.tags.map((tag, tagIndex) =>
151
+ boundedText(tag, `skills[${index}].tags[${tagIndex}]`, 128),
152
+ )
153
+ : [],
154
+ };
155
+ if (
156
+ entry.tags.length > 64 ||
157
+ new Set(entry.tags).size !== entry.tags.length
158
+ ) {
159
+ throw new TypeError("Skill vector corpus tags are invalid or unbounded");
160
+ }
161
+ bytes += Buffer.byteLength(canonical(entry), "utf8");
162
+ if (bytes > MAX_TEXT_BYTES) {
163
+ throw new TypeError("Skill vector corpus is invalid or unbounded");
164
+ }
165
+ return Object.freeze({ ...entry, tags: Object.freeze(entry.tags) });
166
+ });
167
+ corpus.sort((left, right) => left.digest.localeCompare(right.digest));
168
+ return Object.freeze(corpus);
169
+ }
170
+
171
+ export function digestSkillVectorResult(value) {
172
+ return hash(SKILL_VECTOR_RESULT_SCHEMA, {
173
+ schema: value.schema,
174
+ tenantId: value.tenantId,
175
+ requestDigest: value.requestDigest,
176
+ corpusDigest: value.corpusDigest,
177
+ modelId: value.modelId,
178
+ modelRevision: value.modelRevision,
179
+ indexDigest: value.indexDigest,
180
+ scores: value.scores,
181
+ });
182
+ }
183
+
184
+ export function createSkillVectorAuthority({
185
+ tenantId: tenantIdInput,
186
+ provider,
187
+ verifier,
188
+ } = {}) {
189
+ const tenantId = identifier(tenantIdInput, "tenantId");
190
+ const scoreProvider = capture(provider, "score", "Skill vector provider");
191
+ const verifyResult = capture(verifier, "verify", "Skill vector verifier");
192
+ const authority = Object.freeze({
193
+ tenantId,
194
+ async score({ query: queryInput, skills } = {}) {
195
+ const query = boundedText(queryInput, "Skill vector query");
196
+ const corpus = corpusFor(skills);
197
+ const corpusDigest = hash(
198
+ "chainlesschain.skill-vector-corpus/v1",
199
+ corpus,
200
+ );
201
+ const requestCore = {
202
+ schema: SKILL_VECTOR_REQUEST_SCHEMA,
203
+ tenantId,
204
+ query,
205
+ corpusDigest,
206
+ corpus,
207
+ };
208
+ const request = Object.freeze({
209
+ ...requestCore,
210
+ requestDigest: hash(SKILL_VECTOR_REQUEST_SCHEMA, requestCore),
211
+ });
212
+ const result = exact(
213
+ await scoreProvider(request),
214
+ RESULT_KEYS,
215
+ "Skill vector result",
216
+ );
217
+ if (
218
+ result.schema !== SKILL_VECTOR_RESULT_SCHEMA ||
219
+ result.tenantId !== tenantId ||
220
+ result.requestDigest !== request.requestDigest ||
221
+ result.corpusDigest !== corpusDigest ||
222
+ !SAFE_ID.test(result.modelId ?? "") ||
223
+ !SAFE_ID.test(result.modelRevision ?? "") ||
224
+ !DIGEST.test(result.indexDigest ?? "") ||
225
+ !DIGEST.test(result.resultDigest ?? "") ||
226
+ !Array.isArray(result.scores) ||
227
+ utilTypes.isProxy(result.scores) ||
228
+ result.scores.length !== corpus.length
229
+ ) {
230
+ throw new Error("Skill vector result is not authoritative");
231
+ }
232
+ const expected = new Set(corpus.map(({ digest }) => digest));
233
+ const scores = new Map();
234
+ for (const [index, input] of result.scores.entries()) {
235
+ const entry = exact(input, SCORE_KEYS, `Skill vector scores[${index}]`);
236
+ if (
237
+ !expected.has(entry.digest) ||
238
+ scores.has(entry.digest) ||
239
+ typeof entry.score !== "number" ||
240
+ !Number.isFinite(entry.score) ||
241
+ entry.score < 0 ||
242
+ entry.score > 1
243
+ ) {
244
+ throw new Error("Skill vector scores are invalid or incomplete");
245
+ }
246
+ scores.set(entry.digest, entry.score);
247
+ }
248
+ if (scores.size !== expected.size) {
249
+ throw new Error("Skill vector scores are invalid or incomplete");
250
+ }
251
+ exact(result.attestation, ATTESTATION_KEYS, "Skill vector attestation");
252
+ if (
253
+ result.attestation.schema !== SKILL_VECTOR_ATTESTATION_SCHEMA ||
254
+ !SAFE_ID.test(result.attestation.algorithm ?? "") ||
255
+ !SAFE_ID.test(result.attestation.keyId ?? "") ||
256
+ typeof result.attestation.value !== "string" ||
257
+ result.attestation.value.length < 16 ||
258
+ result.attestation.value.length > 4096
259
+ ) {
260
+ throw new Error("Skill vector attestation is invalid");
261
+ }
262
+ if (result.resultDigest !== digestSkillVectorResult(result)) {
263
+ throw new Error("Skill vector result integrity is invalid");
264
+ }
265
+ const verification = exact(
266
+ await verifyResult({
267
+ tenantId,
268
+ requestDigest: request.requestDigest,
269
+ resultDigest: result.resultDigest,
270
+ attestation: result.attestation,
271
+ }),
272
+ VERIFICATION_KEYS,
273
+ "Skill vector verification",
274
+ );
275
+ if (
276
+ verification.authenticated !== true ||
277
+ verification.durable !== true ||
278
+ verification.tenantId !== tenantId ||
279
+ verification.requestDigest !== request.requestDigest ||
280
+ verification.resultDigest !== result.resultDigest ||
281
+ !DIGEST.test(verification.receiptDigest ?? "")
282
+ ) {
283
+ throw new Error("Skill vector result is not independently verified");
284
+ }
285
+ return Object.freeze({
286
+ scores: Object.freeze(Object.fromEntries(scores)),
287
+ evidence: Object.freeze({
288
+ schema: SKILL_VECTOR_AUTHORITY_SCHEMA,
289
+ status: "verified",
290
+ tenantId,
291
+ requestDigest: request.requestDigest,
292
+ corpusDigest,
293
+ skillCount: corpus.length,
294
+ modelId: result.modelId,
295
+ modelRevision: result.modelRevision,
296
+ indexDigest: result.indexDigest,
297
+ resultDigest: result.resultDigest,
298
+ receiptDigest: verification.receiptDigest,
299
+ }),
300
+ });
301
+ },
302
+ });
303
+ AUTHORITIES.add(authority);
304
+ return authority;
305
+ }
306
+
307
+ export function captureSkillVectorAuthority(value) {
308
+ if (!AUTHORITIES.has(value)) {
309
+ throw new TypeError("a branded Skill vector authority is required");
310
+ }
311
+ return value;
312
+ }
313
+
314
+ export function unavailableSkillVectorEvidence(
315
+ code = "CC_SKILL_VECTOR_AUTHORITY_UNCONFIGURED",
316
+ ) {
317
+ if (!/^CC_SKILL_VECTOR_[A-Z0-9_]{1,96}$/u.test(code)) {
318
+ throw new TypeError("Skill vector unavailable code is invalid");
319
+ }
320
+ return Object.freeze({
321
+ schema: SKILL_VECTOR_AUTHORITY_SCHEMA,
322
+ status: "unavailable",
323
+ code,
324
+ });
325
+ }
@@ -0,0 +1,386 @@
1
+ import { createHash } from "node:crypto";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { types as utilTypes } from "node:util";
5
+
6
+ import { executionBroker } from "./process-execution-broker/index.js";
7
+ import { createSkillVectorAuthority } from "./skill-vector-authority.js";
8
+
9
+ export const SKILL_VECTOR_PROCESS_REQUEST_SCHEMA =
10
+ "chainlesschain.skill-vector-process-request/v1";
11
+
12
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
13
+ const SAFE_ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
14
+ const WORKER_KEYS = new Set([
15
+ "arguments",
16
+ "cwd",
17
+ "entryDigest",
18
+ "entryPath",
19
+ "environment",
20
+ "executableDigest",
21
+ "executablePath",
22
+ "identity",
23
+ ]);
24
+ const DEFAULT_TIMEOUT_MS = 10_000;
25
+ const DEFAULT_MAX_INPUT_BYTES = 12 * 1024 * 1024;
26
+ const DEFAULT_MAX_OUTPUT_BYTES = 4 * 1024 * 1024;
27
+ const MAX_STDERR_BYTES = 64 * 1024;
28
+ const MAX_EXECUTABLE_BYTES = 512 * 1024 * 1024;
29
+ const MAX_ENTRY_BYTES = 16 * 1024 * 1024;
30
+ const PROCESS_DEPS = Object.freeze({
31
+ spawn: (...args) => executionBroker.spawn(...args),
32
+ });
33
+
34
+ function plainRecord(value, label, allowedKeys = null) {
35
+ if (
36
+ !value ||
37
+ typeof value !== "object" ||
38
+ Array.isArray(value) ||
39
+ utilTypes.isProxy(value) ||
40
+ ![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
41
+ (allowedKeys &&
42
+ Reflect.ownKeys(value).some(
43
+ (key) => typeof key !== "string" || !allowedKeys.has(key),
44
+ ))
45
+ ) {
46
+ throw new TypeError(`${label} is invalid`);
47
+ }
48
+ return value;
49
+ }
50
+
51
+ function identifier(value, label) {
52
+ if (typeof value !== "string" || !SAFE_ID.test(value)) {
53
+ throw new TypeError(`${label} is invalid`);
54
+ }
55
+ return value;
56
+ }
57
+
58
+ function pinnedDigest(value, label) {
59
+ if (typeof value !== "string" || !DIGEST.test(value)) {
60
+ throw new TypeError(`${label} must be sha256-bound`);
61
+ }
62
+ return value;
63
+ }
64
+
65
+ function absolutePath(value, label) {
66
+ if (
67
+ typeof value !== "string" ||
68
+ value.includes("\0") ||
69
+ !path.isAbsolute(value) ||
70
+ path.normalize(value) !== value
71
+ ) {
72
+ throw new TypeError(`${label} must be a normalized absolute path`);
73
+ }
74
+ return value;
75
+ }
76
+
77
+ function boundedInteger(value, fallback, label, maximum) {
78
+ const normalized = value === undefined ? fallback : value;
79
+ if (
80
+ !Number.isSafeInteger(normalized) ||
81
+ normalized < 1 ||
82
+ normalized > maximum
83
+ ) {
84
+ throw new TypeError(`${label} is invalid or unbounded`);
85
+ }
86
+ return normalized;
87
+ }
88
+
89
+ function normalizeArguments(value, label) {
90
+ if (value === undefined) return Object.freeze([]);
91
+ if (!Array.isArray(value) || utilTypes.isProxy(value) || value.length > 64) {
92
+ throw new TypeError(`${label} is invalid or unbounded`);
93
+ }
94
+ let bytes = 0;
95
+ const result = value.map((argument, index) => {
96
+ if (
97
+ typeof argument !== "string" ||
98
+ argument.includes("\0") ||
99
+ Buffer.byteLength(argument, "utf8") > 4096
100
+ ) {
101
+ throw new TypeError(`${label}[${index}] is invalid or unbounded`);
102
+ }
103
+ bytes += Buffer.byteLength(argument, "utf8");
104
+ return argument;
105
+ });
106
+ if (bytes > 32 * 1024) {
107
+ throw new TypeError(`${label} is invalid or unbounded`);
108
+ }
109
+ return Object.freeze(result);
110
+ }
111
+
112
+ function normalizeEnvironment(value, label) {
113
+ if (value === undefined) return Object.freeze({});
114
+ plainRecord(value, label);
115
+ const entries = Object.entries(value);
116
+ if (entries.length > 64) {
117
+ throw new TypeError(`${label} is invalid or unbounded`);
118
+ }
119
+ let bytes = 0;
120
+ const result = Object.create(null);
121
+ const normalizedKeys = new Set();
122
+ for (const [key, entry] of entries.sort(([left], [right]) =>
123
+ left.localeCompare(right),
124
+ )) {
125
+ const normalizedKey =
126
+ process.platform === "win32" ? key.toLowerCase() : key;
127
+ if (
128
+ !/^[A-Za-z_][A-Za-z0-9_]{0,127}$/u.test(key) ||
129
+ normalizedKeys.has(normalizedKey) ||
130
+ typeof entry !== "string" ||
131
+ entry.includes("\0") ||
132
+ Buffer.byteLength(entry, "utf8") > 16 * 1024
133
+ ) {
134
+ throw new TypeError(`${label}.${key} is invalid or unbounded`);
135
+ }
136
+ bytes += Buffer.byteLength(key, "utf8") + Buffer.byteLength(entry, "utf8");
137
+ normalizedKeys.add(normalizedKey);
138
+ result[key] = entry;
139
+ }
140
+ if (bytes > 32 * 1024) {
141
+ throw new TypeError(`${label} is invalid or unbounded`);
142
+ }
143
+ return Object.freeze(result);
144
+ }
145
+
146
+ function normalizeWorker(value, label) {
147
+ plainRecord(value, label, WORKER_KEYS);
148
+ return Object.freeze({
149
+ identity: identifier(value.identity, `${label}.identity`),
150
+ executablePath: absolutePath(
151
+ value.executablePath,
152
+ `${label}.executablePath`,
153
+ ),
154
+ executableDigest: pinnedDigest(
155
+ value.executableDigest,
156
+ `${label}.executableDigest`,
157
+ ),
158
+ entryPath: absolutePath(value.entryPath, `${label}.entryPath`),
159
+ entryDigest: pinnedDigest(value.entryDigest, `${label}.entryDigest`),
160
+ arguments: normalizeArguments(value.arguments, `${label}.arguments`),
161
+ cwd: absolutePath(value.cwd, `${label}.cwd`),
162
+ environment: normalizeEnvironment(
163
+ value.environment,
164
+ `${label}.environment`,
165
+ ),
166
+ });
167
+ }
168
+
169
+ function fileDigest(filePath) {
170
+ return `sha256:${createHash("sha256").update(fs.readFileSync(filePath)).digest("hex")}`;
171
+ }
172
+
173
+ function samePath(left, right) {
174
+ return process.platform === "win32"
175
+ ? left.toLowerCase() === right.toLowerCase()
176
+ : left === right;
177
+ }
178
+
179
+ function assertPinnedFile(filePath, expectedDigest, label, maximumBytes) {
180
+ const stat = fs.lstatSync(filePath);
181
+ if (
182
+ !stat.isFile() ||
183
+ stat.isSymbolicLink() ||
184
+ stat.size < 1 ||
185
+ stat.size > maximumBytes
186
+ ) {
187
+ throw new Error(`${label} is not a regular pinned file`);
188
+ }
189
+ const realPath = fs.realpathSync.native(filePath);
190
+ if (!samePath(realPath, filePath)) {
191
+ throw new Error(`${label} does not resolve to its pinned path`);
192
+ }
193
+ if (fileDigest(filePath) !== expectedDigest) {
194
+ throw new Error(`${label} digest changed`);
195
+ }
196
+ }
197
+
198
+ function assertWorkerIdentity(worker, label) {
199
+ assertPinnedFile(
200
+ worker.executablePath,
201
+ worker.executableDigest,
202
+ `${label} executable`,
203
+ MAX_EXECUTABLE_BYTES,
204
+ );
205
+ assertPinnedFile(
206
+ worker.entryPath,
207
+ worker.entryDigest,
208
+ `${label} entry`,
209
+ MAX_ENTRY_BYTES,
210
+ );
211
+ const cwd = fs.realpathSync.native(worker.cwd);
212
+ if (!samePath(cwd, worker.cwd) || !fs.statSync(cwd).isDirectory()) {
213
+ throw new Error(`${label} cwd does not resolve to its pinned directory`);
214
+ }
215
+ }
216
+
217
+ function processFailure(code) {
218
+ const error = new Error(`Skill vector process failed closed (${code})`);
219
+ error.code = code;
220
+ return error;
221
+ }
222
+
223
+ async function invokeWorker(
224
+ worker,
225
+ role,
226
+ payload,
227
+ { timeoutMs, maxInputBytes, maxOutputBytes },
228
+ ) {
229
+ assertWorkerIdentity(worker, role);
230
+ const input = Buffer.from(
231
+ `${JSON.stringify({
232
+ schema: SKILL_VECTOR_PROCESS_REQUEST_SCHEMA,
233
+ role,
234
+ payload,
235
+ })}\n`,
236
+ "utf8",
237
+ );
238
+ if (input.length > maxInputBytes) {
239
+ throw processFailure("CC_SKILL_VECTOR_PROCESS_INPUT_LIMIT");
240
+ }
241
+
242
+ const output = await new Promise((resolve, reject) => {
243
+ let settled = false;
244
+ let pendingFailure = null;
245
+ let timer = null;
246
+ let stdoutBytes = 0;
247
+ let stderrBytes = 0;
248
+ const stdout = [];
249
+ const child = PROCESS_DEPS.spawn(
250
+ worker.executablePath,
251
+ [worker.entryPath, ...worker.arguments],
252
+ {
253
+ cwd: worker.cwd,
254
+ env: { ...worker.environment },
255
+ shell: false,
256
+ windowsHide: true,
257
+ stdio: ["pipe", "pipe", "pipe"],
258
+ origin: "skill-vector-process-authority",
259
+ scope: "evolution",
260
+ policy: "allow",
261
+ auditRedactArgIndexes: worker.arguments.map((_, index) => index + 1),
262
+ },
263
+ );
264
+ const terminate = (error) => {
265
+ if (settled || pendingFailure) return;
266
+ pendingFailure = error;
267
+ if (child.exitCode === null) child.kill("SIGKILL");
268
+ };
269
+ timer = setTimeout(() => {
270
+ terminate(processFailure("CC_SKILL_VECTOR_PROCESS_TIMEOUT"));
271
+ }, timeoutMs);
272
+ timer.unref?.();
273
+ child.once("error", () => {
274
+ terminate(processFailure("CC_SKILL_VECTOR_PROCESS_SPAWN_FAILED"));
275
+ });
276
+ child.stdout.on("data", (chunk) => {
277
+ if (pendingFailure) return;
278
+ stdoutBytes += chunk.length;
279
+ if (stdoutBytes > maxOutputBytes) {
280
+ terminate(processFailure("CC_SKILL_VECTOR_PROCESS_OUTPUT_LIMIT"));
281
+ return;
282
+ }
283
+ stdout.push(chunk);
284
+ });
285
+ child.stderr.on("data", (chunk) => {
286
+ if (pendingFailure) return;
287
+ stderrBytes += chunk.length;
288
+ if (stderrBytes > MAX_STDERR_BYTES) {
289
+ terminate(processFailure("CC_SKILL_VECTOR_PROCESS_STDERR_LIMIT"));
290
+ }
291
+ });
292
+ child.once("close", (code, signal) => {
293
+ if (settled) return;
294
+ settled = true;
295
+ clearTimeout(timer);
296
+ if (pendingFailure) {
297
+ reject(pendingFailure);
298
+ return;
299
+ }
300
+ if (code !== 0 || signal !== null) {
301
+ reject(processFailure("CC_SKILL_VECTOR_PROCESS_EXITED"));
302
+ return;
303
+ }
304
+ resolve(Buffer.concat(stdout).toString("utf8"));
305
+ });
306
+ child.stdin.once("error", () => {
307
+ terminate(processFailure("CC_SKILL_VECTOR_PROCESS_STDIN_FAILED"));
308
+ });
309
+ child.stdin.end(input);
310
+ });
311
+
312
+ assertWorkerIdentity(worker, role);
313
+ const text = output.trim();
314
+ if (text === "" || Buffer.byteLength(text, "utf8") > maxOutputBytes) {
315
+ throw processFailure("CC_SKILL_VECTOR_PROCESS_EMPTY_OUTPUT");
316
+ }
317
+ try {
318
+ const parsed = JSON.parse(text);
319
+ plainRecord(parsed, `${role} process result`);
320
+ return parsed;
321
+ } catch (error) {
322
+ if (error?.code?.startsWith?.("CC_SKILL_VECTOR_")) throw error;
323
+ throw processFailure("CC_SKILL_VECTOR_PROCESS_INVALID_JSON");
324
+ }
325
+ }
326
+
327
+ /**
328
+ * Creates the existing branded vector authority over two independently pinned
329
+ * JSON worker processes. The host supplies all executable and entry digests;
330
+ * no PATH lookup, shell, inherited environment, local key or permissive
331
+ * verifier fallback is used.
332
+ */
333
+ export function createSkillVectorProcessAuthority({
334
+ tenantId,
335
+ provider: providerInput,
336
+ verifier: verifierInput,
337
+ timeoutMs: timeoutInput,
338
+ maxInputBytes: maxInputInput,
339
+ maxOutputBytes: maxOutputInput,
340
+ } = {}) {
341
+ const provider = normalizeWorker(providerInput, "provider");
342
+ const verifier = normalizeWorker(verifierInput, "verifier");
343
+ if (
344
+ provider.identity === verifier.identity ||
345
+ provider.entryDigest === verifier.entryDigest
346
+ ) {
347
+ throw new TypeError(
348
+ "Skill vector provider and verifier must be independent",
349
+ );
350
+ }
351
+ const limits = Object.freeze({
352
+ timeoutMs: boundedInteger(
353
+ timeoutInput,
354
+ DEFAULT_TIMEOUT_MS,
355
+ "timeoutMs",
356
+ 60_000,
357
+ ),
358
+ maxInputBytes: boundedInteger(
359
+ maxInputInput,
360
+ DEFAULT_MAX_INPUT_BYTES,
361
+ "maxInputBytes",
362
+ 16 * 1024 * 1024,
363
+ ),
364
+ maxOutputBytes: boundedInteger(
365
+ maxOutputInput,
366
+ DEFAULT_MAX_OUTPUT_BYTES,
367
+ "maxOutputBytes",
368
+ 8 * 1024 * 1024,
369
+ ),
370
+ });
371
+ assertWorkerIdentity(provider, "provider");
372
+ assertWorkerIdentity(verifier, "verifier");
373
+ return createSkillVectorAuthority({
374
+ tenantId,
375
+ provider: Object.freeze({
376
+ score: Object.freeze((request) =>
377
+ invokeWorker(provider, "provider", request, limits),
378
+ ),
379
+ }),
380
+ verifier: Object.freeze({
381
+ verify: Object.freeze((request) =>
382
+ invokeWorker(verifier, "verifier", request, limits),
383
+ ),
384
+ }),
385
+ });
386
+ }