chainlesschain 0.166.43 → 0.166.45

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 (202) hide show
  1. package/README.md +75 -14
  2. package/package.json +3 -3
  3. package/src/assets/web-panel/.build-hash +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-BIl-Z62M.js → AIOps-CrMhYNeH.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-BgPi_Te6.js → ActionButton-DLY5blZ3.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-CaNIzlAG.js → Analytics-C0NhKQB0.js} +2 -2
  7. package/src/assets/web-panel/assets/{AppLayout-D9GSx2hl.js → AppLayout-DLyepgMq.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-Kq7kotzv.js → Artifacts-Depk01Sa.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-e1RTJLco.js → Audit-jKe6NQ3J.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-BfyNT0BW.js → BackgroundAgents-CG4GKT9s.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-BEAq7i6S.js → Backup-DYWCkzwM.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-BHuP82DF.js → BaseInput-xm5vodmJ.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-BLPgCQsB.js → Chat-B20_PNd3.js} +5 -5
  14. package/src/assets/web-panel/assets/ChatBubbleRenderer-D4d-eh0F.js +1 -0
  15. package/src/assets/web-panel/assets/{Checkbox-DDJrOqEh.js → Checkbox-CfgwkV_r.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-CxyKcM6S.js → Codegen-DbnoWI44.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-BYFh9rE1.js → Col-CfzzhgGw.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-D8JPppoh.js → Community-BU7mGM8p.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-B5VGSqZe.js → Compact-DpYim0an.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-C7KiFcUK.js → Compliance-BNJcO6ra.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-D-F2fgA_.js → Cowork-CecZ-pWj.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-B6TmPqRO.js → Cron-BG_C1fe3.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-BeGcBXhk.js → Crosschain-BAeILQLL.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-9QklLcmQ.js → DID-CYqOEkXi.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-DIadmsuS.js → Dashboard-BYU8wmL1.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-0I5gks3i.js → Dropdown-DYlJeTTa.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-BdTAjT2q.js → EmailListRenderer-C0M6py3K.js} +1 -1
  28. package/src/assets/web-panel/assets/EvolutionSettings-_QnjPFZJ.js +1 -0
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-DQUQWwUY.js → FamilyGuardDashboard-Du90iDch.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-Drgi--Zn.js → Federation-DkFp_hzB.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-BOf-9P8n.js → FormItemContext-BGgtGTfG.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-CBBnIDaW.js → GenericCardRenderer-BIDsSCei.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-BKimGd5P.js → Git--d3Te93J.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-DoXCXppu.js → Governance-CZwD0vmO.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-DzOhGhOE.js → Inference-DiDcSFEW.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-DawgmU58.js → KnowledgeGraph-Bi0hSfzg.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-Co3EJL2Y.js → Logs-C8NHSc0K.js} +2 -2
  38. package/src/assets/web-panel/assets/{MarkdownRenderer-VUfiDRZN.js → MarkdownRenderer-DfDuADqF.js} +1 -1
  39. package/src/assets/web-panel/assets/{Marketplace-BqpMHnMW.js → Marketplace-D6kD0bNf.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-C7ZSokcR.js → McpTools-mTSamCr5.js} +2 -2
  41. package/src/assets/web-panel/assets/{Memory-DuJrpeDx.js → Memory-YQBXfLjU.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-CaM744NU.js → MobileBridge-D2awuupp.js} +1 -1
  43. package/src/assets/web-panel/assets/MobileProjects-Bl7lZc_-.js +1 -0
  44. package/src/assets/web-panel/assets/{Mtc-5oUB7lPh.js → Mtc-CBqjLK2Q.js} +5 -5
  45. package/src/assets/web-panel/assets/{MtcAudit-D9DNF6DB.js → MtcAudit-C4poRInZ.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-CfMpFQSr.js → Multisig-C_J0zXYZ.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-CuhPZQ7q.js → NLProgramming-Ci43sWOU.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-NtSeMoyM.js → Notes-DN7A-GFZ.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-CB4e7V83.js → NotificationSettings-D5jNm71V.js} +1 -1
  50. package/src/assets/web-panel/assets/OrderTableRenderer-C9UsPOG8.js +1 -0
  51. package/src/assets/web-panel/assets/{Organization-K_0bjm7y.js → Organization-BapYMJrP.js} +2 -2
  52. package/src/assets/web-panel/assets/{Overflow-D2vwxiPv.js → Overflow-BwxwjhFw.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-WQMHBu8q.js → P2P-TObXXOu3.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-CTZVBMZZ.js → PdhVaultBrowser-UwJvMbFO.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-DcLy9Nfp.js → Permissions-Damnxv-O.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-zc-cm-02.js → PersonalDataHub-d_7jlBb-.js} +4 -4
  57. package/src/assets/web-panel/assets/{Pipeline-CCnI8peM.js → Pipeline-DA87VjLw.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-DO1Xor8L.js → Privacy-DzO_UvWn.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-CZqC-jyt.js → ProjectInit-CwqECDhs.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-DqJtyavX.js → ProjectSettings-CT5YdIl6.js} +2 -2
  61. package/src/assets/web-panel/assets/{Projects-Dx14NAO3.js → Projects-D3KdZPCv.js} +1 -1
  62. package/src/assets/web-panel/assets/{Providers-DH13a6ro.js → Providers-BjBIS8kk.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-C9bwzVfA.js → QrScannerModal-mMFqiKkI.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-Cbt-oIPf.js → QuickAsk-BwGi9ZU1.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-BYIimGcY.js → Recommend-BY65SR5s.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-C8OWTG1H.js → RemoteSession-BGsVH_XU.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-DpUGT_jD.js → Reputation-DpPbxSgI.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-DZ5Izi2A.js → Row-B5YBYoVz.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-CAn94No1.js → RssFeed-DvM5jaoh.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-BqNaxcgj.js → Search-6RX39EPO.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-Ck6vFTWn.js → Security-Beal-7cM.js} +4 -4
  72. package/src/assets/web-panel/assets/{Services-Y3RdvvDj.js → Services-D6rjVLe-.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-Cx9Iqcp7.js → Skeleton-Dur7R7vz.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-Oiqz7wLM.js → Skills-D1QkGwMk.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-DaKJQADm.js → Sla-3ObrX8Es.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-BWoOpPW4.js → SpeechSettings-DG_KAiH1.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-CgFle8GX.js → SyncSettings-BaHq0SJ2.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-C1tQNvWx.js → Tasks-BDpAkBAB.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-CvvycaWi.js → Templates-tYdoRd-c.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-D1FwaD12.js → Tenant-yGS5zIQ1.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-oorFjObO.js → Terminal-B3QbmVFa.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-BjMs48Sj.js → TimelineRenderer-B_7Pr5dS.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-BkRb95xG.js → Tokens-DPvpDa53.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-B94RYYAF.js → Trigger-DcSAD0GZ.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-DnBVpOWt.js → Trust-BBzEq-uy.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-DouHO6Up.js → UkeySign-Dssav7-5.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-DDgRerWV.js → VideoEditing-CPOZf4yi.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-CQN9Un7X.js → Wallet-BzBVRXEq.js} +3 -3
  89. package/src/assets/web-panel/assets/{WebAuthn-DyHl2G3J.js → WebAuthn-DdSGaCCh.js} +2 -2
  90. package/src/assets/web-panel/assets/{WorkflowEditor-BQlN77Ey.js → WorkflowEditor-CKjBFoSs.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-0jOqe7ZD.js → chat-B9aMGLg0.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-kp5TAaKx.js → colors-GFCMctSV.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-DqF6Rml7.js → compact-item-BqSDFAYJ.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-lDyLBjy5.js → createContext-BwUm3Ffp.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-LxtRBsCm.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-CkiF91kH.js → hasIn-DN1kMJOT.js} +1 -1
  97. package/src/assets/web-panel/assets/index-36hxBH-o.js +1 -0
  98. package/src/assets/web-panel/assets/{index-BvFFY-2V.js → index-7W1e9Vi4.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DQGk8bV8.js → index-B4MfxM5W.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-kenTha3h.js → index-B4dI_csl.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-B6V9l2P-.js → index-B7Yu5wwV.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Bq2s5obn.js → index-B9Pe-EyB.js} +3 -3
  103. package/src/assets/web-panel/assets/{index-aHKeys8c.js → index-BBMW8bQO.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BPwtIqRo.js → index-BCnbC2z7.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-ByggSxTQ.js → index-BDL2MwxN.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BPcjLn2w.js → index-BHUxz4dy.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Bu14YcwM.js → index-BL_0ndQc.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DrVVi5jX.js → index-BPGlcDvs.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DzU_SfdF.js → index-BeycSy7n.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DnI__Fwu.js → index-BpiR6uzH.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CI-H0ljO.js → index-BwssFWI1.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-DPHmcQWh.js → index-By9GbJhu.js} +1 -1
  113. package/src/assets/web-panel/assets/index-C0b78zWZ.js +1 -0
  114. package/src/assets/web-panel/assets/{index-DX40v3aL.js → index-CEMl-Qte.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BRu6Pe98.js → index-CH2wK5dx.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-8Hxbv1SG.js → index-CRikhGgx.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DgGNW2ep.js → index-Ci0zIpSX.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-BUqE17wu.js → index-Cli0VREv.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BAtpuJQ7.js → index-CmEHzOsw.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DK47iA2d.js → index-Cwih67e8.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-mkwJZMBT.js → index-D8jcp9Rj.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DSDM-VNz.js → index-DAK28GY8.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CNPCAYHk.js → index-DI90Wo_P.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CLchRTsS.js → index-DO-IKERp.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BKFL4DfP.js → index-DaFr7XB1.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DduPk1RS.js → index-DbDhKroq.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-X1l5-ive.js → index-DnJt9DaX.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-INxX1TMz.js → index-DvvJWwT8.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DHnFhMOL.js → index-PJt1Zrx2.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DHVNtkrR.js → index-PKwZkQDC.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DZU13W4o.js → index-THsr_UUJ.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-C-CS_-jC.js → index-bwb4cg_D.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BSAeSPQe.js → index-rCTtYCGu.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BnU8hi3c.js → index-tMF_deZb.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DTA_B9gU.js → index-y7cfh9rP.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-CYYQ0SI1.js → initDefaultProps-B6e5CZ5p.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion--Tyo36te.js → motion-riMM1KfJ.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-D2BjgQv7.js → move-C1NSDMjc.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-dyIu5RU_.js → mtc-parser-Bibuny9B.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-CDEAhC5H.js → omit-Cmf6FoRn.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-DLKDlIQs.js → pickAttrs-BSsYBUCY.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-BveC8fe2.js → placementArrow-gSB7-GAS.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-51urgYrW.js → responsiveObserve-qaqttvKa.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-CCHbhZg-.js → slide-RX2gxl3k.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-W4mtUXRP.js → statusUtils-DEJmkhqw.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-D4Drrz2a.js → styleChecker-CIWmJ78O.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-BBCd4kCM.js → useFlexGapSupport-D-UPSQBE.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-4Khxvw5Y.js → useFs-9QFtqADc.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-7c72tleZ.js → usePersonalDataHub-DM6kyift.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-DzZ7Y0LN.js → vnode-C-q6FNSJ.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-C5jhaET3.js → zoom-D4WJY2m8.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/command-help-index.json +1 -1
  154. package/src/commands/agent.js +19 -2
  155. package/src/commands/ask.js +13 -8
  156. package/src/commands/chat.js +8 -5
  157. package/src/commands/cowork.js +18 -9
  158. package/src/commands/eval.js +100 -45
  159. package/src/commands/evolution-deployment.js +58 -0
  160. package/src/commands/hub.js +13 -7
  161. package/src/commands/setup.js +31 -1
  162. package/src/constants.js +2 -2
  163. package/src/data/changelog.json +188 -762
  164. package/src/gateways/ws/personal-data-hub-protocol.js +12 -5
  165. package/src/lazy-dispatch.js +42 -6
  166. package/src/lib/agent-router.js +25 -23
  167. package/src/lib/chat-intent-service.js +3 -13
  168. package/src/lib/context-memory-kernel/provider-context.js +19 -3
  169. package/src/lib/cowork-adapter.js +9 -4
  170. package/src/lib/doctor-checkup.js +42 -0
  171. package/src/lib/eval/evidence.js +203 -0
  172. package/src/lib/eval/runner.js +16 -2
  173. package/src/lib/eval/trend.js +4 -3
  174. package/src/lib/evolution/evolution-deployment-config.js +217 -10
  175. package/src/lib/evolution/evolution-deployment-descriptor-revocations.js +131 -0
  176. package/src/lib/evolution/evolution-deployment-loader.js +23 -2
  177. package/src/lib/evolution/evolution-deployment-profile.js +281 -37
  178. package/src/lib/evolution/evolution-deployment-root-rotation.js +154 -0
  179. package/src/lib/evolution/evolution-file-identity.js +42 -0
  180. package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +242 -0
  181. package/src/lib/evolution/evolution-ledger-manifest-chain.js +74 -18
  182. package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +135 -20
  183. package/src/lib/evolution/evolution-ledger.js +353 -209
  184. package/src/lib/evolution/governed-hub-llm.js +18 -12
  185. package/src/lib/evolution/governed-hub-skill.js +4 -17
  186. package/src/lib/evolution/governed-model-turn.js +7 -8
  187. package/src/lib/llm-providers.js +1 -0
  188. package/src/lib/orchestrator.js +14 -8
  189. package/src/lib/personal-data-hub-wiring.js +7 -1
  190. package/src/lib/sub-agent-context.js +5 -1
  191. package/src/lib/task-model-selector.js +1 -1
  192. package/src/repl/agent-repl.js +1 -1
  193. package/src/repl/chat-repl.js +8 -4
  194. package/src/runtime/agent-core.js +36 -10
  195. package/src/runtime/headless-runner.js +16 -0
  196. package/src/assets/web-panel/assets/ChatBubbleRenderer-DWXPJh-J.js +0 -1
  197. package/src/assets/web-panel/assets/EvolutionSettings-C7_tq643.js +0 -1
  198. package/src/assets/web-panel/assets/MobileProjects-Bd78jDwm.js +0 -1
  199. package/src/assets/web-panel/assets/OrderTableRenderer-Bu8C6Qlj.js +0 -1
  200. package/src/assets/web-panel/assets/devWarning-IfrMTwCK.js +0 -1
  201. package/src/assets/web-panel/assets/index-C7nsIbMa.js +0 -1
  202. package/src/assets/web-panel/assets/index-DFXFLdKN.js +0 -1
@@ -1,9 +1,14 @@
1
1
  import {
2
+ assertEvolutionDeploymentActiveTrustRoot,
3
+ assertEvolutionDeploymentDescriptorNotRevoked,
4
+ assertEvolutionDeploymentRevisionFloor,
2
5
  readEvolutionDeploymentProfile,
3
6
  setEvolutionDeploymentProfileEnabled,
4
- writeEvolutionDeploymentProfile,
7
+ updateEvolutionDeploymentProfile,
5
8
  } from "./evolution-deployment-profile.js";
6
9
  import { verifyEvolutionDeployment } from "./evolution-deployment-loader.js";
10
+ import { verifyEvolutionDeploymentRootRotationSync } from "./evolution-deployment-root-rotation.js";
11
+ import { verifyEvolutionDeploymentDescriptorRevocationsSync } from "./evolution-deployment-descriptor-revocations.js";
7
12
 
8
13
  function environmentSelection(env) {
9
14
  const descriptorPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_DESCRIPTOR;
@@ -12,6 +17,102 @@ function environmentSelection(env) {
12
17
  return { descriptorPath, trustRootPath };
13
18
  }
14
19
 
20
+ /**
21
+ * Project verified deployment prerequisites without importing the host module.
22
+ * `ready` describes deployment admission only, never a successful model probe:
23
+ * the command must still load and validate its composition at execution time.
24
+ */
25
+ export function assessEvolutionDeploymentReadiness(
26
+ status,
27
+ { requiredCommands = ["ask", "agent"] } = {},
28
+ ) {
29
+ if (
30
+ !Array.isArray(requiredCommands) ||
31
+ requiredCommands.length === 0 ||
32
+ requiredCommands.some(
33
+ (command) =>
34
+ typeof command !== "string" || !/^[a-z][a-z-]*$/.test(command),
35
+ )
36
+ ) {
37
+ throw new TypeError("deployment readiness requires explicit command names");
38
+ }
39
+ const commands = Object.freeze([...new Set(requiredCommands)]);
40
+ const allowed = Array.isArray(status?.commands) ? status.commands : [];
41
+ const missingCommands = Object.freeze(
42
+ commands.filter((command) => !allowed.includes(command)),
43
+ );
44
+ const result = (state, code, detail, remediation) => {
45
+ const ready = state === "admitted";
46
+ return Object.freeze({
47
+ scope: "deployment-admission",
48
+ state,
49
+ code,
50
+ ready,
51
+ requiredCommands: commands,
52
+ missingCommands,
53
+ runtimeVerification: "not_checked",
54
+ taskReady: ready ? null : false,
55
+ detail,
56
+ remediation,
57
+ });
58
+ };
59
+ if (
60
+ status?.error ||
61
+ (status?.effectiveEnabled === true && status?.verified !== true)
62
+ ) {
63
+ return result(
64
+ "invalid",
65
+ "EVOLUTION_DEPLOYMENT_NOT_VERIFIED",
66
+ `configured Evolution deployment is not verified${status?.error ? `: ${status.error}` : ""}`,
67
+ "repair the signed descriptor or trust root, then run cc evolution deployment status --json",
68
+ );
69
+ }
70
+ if (status?.effectiveEnabled !== true) {
71
+ const disabled =
72
+ status?.profileEnabled === false && Boolean(status?.descriptorPath);
73
+ return result(
74
+ disabled ? "disabled" : "not_configured",
75
+ disabled
76
+ ? "EVOLUTION_DEPLOYMENT_DISABLED"
77
+ : "EVOLUTION_DEPLOYMENT_NOT_CONFIGURED",
78
+ disabled
79
+ ? "signed Evolution deployment is disabled"
80
+ : "no enabled signed Evolution deployment",
81
+ disabled
82
+ ? "review the saved signed deployment, then run cc evolution deployment enable"
83
+ : "configure a signed descriptor and trust root with cc evolution deployment configure --descriptor <path> --trust-root <path>",
84
+ );
85
+ }
86
+ if (missingCommands.length > 0) {
87
+ return result(
88
+ "command_not_allowed",
89
+ "EVOLUTION_DEPLOYMENT_COMMAND_NOT_ALLOWED",
90
+ `signed Evolution deployment does not admit commands: ${missingCommands.join(", ")}`,
91
+ `request a signed deployment that admits ${missingCommands.join(", ")}; do not edit the signed descriptor in place`,
92
+ );
93
+ }
94
+ return result(
95
+ "admitted",
96
+ "EVOLUTION_DEPLOYMENT_ADMITTED",
97
+ `signed Evolution deployment admits ${commands.join(", ")}; runtime composition and model execution are not checked`,
98
+ null,
99
+ );
100
+ }
101
+
102
+ function withDeploymentReadiness(status) {
103
+ return Object.freeze({
104
+ ...status,
105
+ readiness: Object.freeze({
106
+ ask: assessEvolutionDeploymentReadiness(status, {
107
+ requiredCommands: ["ask"],
108
+ }),
109
+ agent: assessEvolutionDeploymentReadiness(status, {
110
+ requiredCommands: ["agent"],
111
+ }),
112
+ }),
113
+ });
114
+ }
115
+
15
116
  export async function getEvolutionDeploymentStatus(options = {}) {
16
117
  const env = options.env || process.env;
17
118
  const saved = await readEvolutionDeploymentProfile(options);
@@ -28,6 +129,7 @@ export async function getEvolutionDeploymentStatus(options = {}) {
28
129
  effectiveEnabled: source !== "none",
29
130
  profileEnabled: saved.profile?.enabled === true,
30
131
  profilePath: saved.filePath,
132
+ activeTrustRootDigest: saved.profile?.activeTrustRootDigest || null,
31
133
  descriptorPath:
32
134
  selected?.descriptorPath || saved.profile?.descriptorPath || null,
33
135
  trustRootPath:
@@ -36,20 +138,38 @@ export async function getEvolutionDeploymentStatus(options = {}) {
36
138
  error: saved.error,
37
139
  autoPromotion: "hold",
38
140
  };
39
- if (!selected || saved.error) return Object.freeze(base);
141
+ if (!selected || saved.error) return withDeploymentReadiness(base);
40
142
  try {
41
143
  const verified = await verifyEvolutionDeployment(selected, options);
42
- return Object.freeze({
144
+ if (source === "profile")
145
+ assertEvolutionDeploymentActiveTrustRoot(
146
+ saved.profile,
147
+ verified.descriptor,
148
+ );
149
+ if (source === "profile")
150
+ assertEvolutionDeploymentDescriptorNotRevoked(
151
+ saved.profile,
152
+ verified.descriptor,
153
+ );
154
+ if (source === "profile")
155
+ assertEvolutionDeploymentRevisionFloor(
156
+ saved.profile,
157
+ verified.descriptor,
158
+ );
159
+ return withDeploymentReadiness({
43
160
  ...base,
44
161
  verified: true,
45
162
  error: null,
46
163
  revision: verified.descriptor.revision,
164
+ revisionFloor:
165
+ saved.profile?.revisionFloors?.[verified.descriptor.trustRootDigest] ||
166
+ null,
47
167
  modulePath: verified.modulePath,
48
168
  moduleDigest: verified.descriptor.moduleDigest,
49
169
  commands: verified.descriptor.commands,
50
170
  });
51
171
  } catch (error) {
52
- return Object.freeze({
172
+ return withDeploymentReadiness({
53
173
  ...base,
54
174
  error: error instanceof Error ? error.message : String(error),
55
175
  });
@@ -57,21 +177,77 @@ export async function getEvolutionDeploymentStatus(options = {}) {
57
177
  }
58
178
 
59
179
  export async function configureEvolutionDeployment(
60
- { descriptorPath, trustRootPath, enabled = true },
180
+ {
181
+ descriptorPath,
182
+ trustRootPath,
183
+ rootRotationPath = null,
184
+ revocationPath = null,
185
+ enabled = true,
186
+ },
61
187
  options = {},
62
188
  ) {
63
189
  const verified = await verifyEvolutionDeployment(
64
190
  { descriptorPath, trustRootPath },
65
191
  options,
66
192
  );
67
- await writeEvolutionDeploymentProfile(
68
- {
193
+ updateEvolutionDeploymentProfile((current) => {
194
+ if (
195
+ current?.activeTrustRootDigest &&
196
+ current.activeTrustRootDigest !== verified.descriptor.trustRootDigest
197
+ ) {
198
+ if (typeof rootRotationPath !== "string" || !rootRotationPath) {
199
+ const error = new Error(
200
+ "evolution deployment trust root rotation requires a certificate signed by the active root",
201
+ );
202
+ error.code = "EVOLUTION_DEPLOYMENT_ROOT_ROTATION_REQUIRED";
203
+ throw error;
204
+ }
205
+ verifyEvolutionDeploymentRootRotationSync({
206
+ rotationPath: rootRotationPath,
207
+ fromTrustRootPath: current.trustRootPath,
208
+ expectedFromTrustRootDigest: current.activeTrustRootDigest,
209
+ expectedToTrustRootDigest: verified.descriptor.trustRootDigest,
210
+ destinationRevision: verified.descriptor.revision,
211
+ });
212
+ }
213
+ assertEvolutionDeploymentRevisionFloor(current, verified.descriptor);
214
+ const receivedRevocations = revocationPath
215
+ ? verifyEvolutionDeploymentDescriptorRevocationsSync({
216
+ revocationPath,
217
+ trustRootPath: verified.trustRootPath,
218
+ expectedTrustRootDigest: verified.descriptor.trustRootDigest,
219
+ }).revokedDescriptorRevisions
220
+ : [];
221
+ const priorRevocations =
222
+ current?.revokedDescriptorRevisions?.[
223
+ verified.descriptor.trustRootDigest
224
+ ] || [];
225
+ const revokedDescriptorRevisions = {
226
+ ...(current?.revokedDescriptorRevisions || {}),
227
+ [verified.descriptor.trustRootDigest]: [
228
+ ...new Set([...priorRevocations, ...receivedRevocations]),
229
+ ].sort((left, right) => left - right),
230
+ };
231
+ assertEvolutionDeploymentDescriptorNotRevoked(
232
+ { revokedDescriptorRevisions },
233
+ verified.descriptor,
234
+ );
235
+ const revisionFloors = {
236
+ ...(current?.revisionFloors || {}),
237
+ [verified.descriptor.trustRootDigest]: Math.max(
238
+ current?.revisionFloors?.[verified.descriptor.trustRootDigest] || 0,
239
+ verified.descriptor.revision,
240
+ ),
241
+ };
242
+ return {
69
243
  enabled: enabled === true,
70
244
  descriptorPath: verified.descriptorPath,
71
245
  trustRootPath: verified.trustRootPath,
72
- },
73
- options,
74
- );
246
+ revisionFloors,
247
+ activeTrustRootDigest: verified.descriptor.trustRootDigest,
248
+ revokedDescriptorRevisions,
249
+ };
250
+ }, options);
75
251
  return getEvolutionDeploymentStatus(options);
76
252
  }
77
253
 
@@ -79,3 +255,34 @@ export async function setEvolutionDeploymentEnabled(enabled, options = {}) {
79
255
  await setEvolutionDeploymentProfileEnabled(enabled, options);
80
256
  return getEvolutionDeploymentStatus(options);
81
257
  }
258
+
259
+ export function revokeEvolutionDeploymentDescriptorRevisions(
260
+ { revocationPath },
261
+ options = {},
262
+ ) {
263
+ updateEvolutionDeploymentProfile((current) => {
264
+ if (!current?.activeTrustRootDigest)
265
+ throw new Error("evolution deployment profile is not configured");
266
+ const record = verifyEvolutionDeploymentDescriptorRevocationsSync({
267
+ revocationPath,
268
+ trustRootPath: current.trustRootPath,
269
+ expectedTrustRootDigest: current.activeTrustRootDigest,
270
+ });
271
+ const prior =
272
+ current.revokedDescriptorRevisions?.[current.activeTrustRootDigest] || [];
273
+ return {
274
+ ...current,
275
+ // Disabling is conservative: the current descriptor may be one of the
276
+ // newly revoked revisions, and it must not remain executable while the
277
+ // caller is recovering or selecting a replacement.
278
+ enabled: false,
279
+ revokedDescriptorRevisions: {
280
+ ...(current.revokedDescriptorRevisions || {}),
281
+ [current.activeTrustRootDigest]: [
282
+ ...new Set([...prior, ...record.revokedDescriptorRevisions]),
283
+ ].sort((left, right) => left - right),
284
+ },
285
+ };
286
+ }, options);
287
+ return getEvolutionDeploymentStatus(options);
288
+ }
@@ -0,0 +1,131 @@
1
+ import { createHash, createPublicKey, verify } from "node:crypto";
2
+ import { readFileSync } from "node:fs";
3
+ import { isAbsolute } from "node:path";
4
+
5
+ export const EVOLUTION_DEPLOYMENT_DESCRIPTOR_REVOCATIONS_SCHEMA =
6
+ "chainlesschain.evolution-deployment-descriptor-revocations/v1";
7
+
8
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
9
+ const MAX_BYTES = 64 * 1024;
10
+ const MAX_REVOKED_REVISIONS = 1024;
11
+
12
+ function canonical(value) {
13
+ if (value === null || typeof value !== "object") return JSON.stringify(value);
14
+ if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
15
+ return `{${Object.keys(value)
16
+ .sort()
17
+ .map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
18
+ .join(",")}}`;
19
+ }
20
+
21
+ function digest(bytes) {
22
+ return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
23
+ }
24
+
25
+ function normalize(value) {
26
+ const expected = [
27
+ "revision",
28
+ "revokedDescriptorRevisions",
29
+ "schema",
30
+ "signature",
31
+ "trustRootDigest",
32
+ ];
33
+ if (!value || typeof value !== "object" || Array.isArray(value))
34
+ throw new TypeError("evolution deployment revocations must be an object");
35
+ if (canonical(Object.keys(value).sort()) !== canonical(expected))
36
+ throw new TypeError("evolution deployment revocations fields are invalid");
37
+ if (value.schema !== EVOLUTION_DEPLOYMENT_DESCRIPTOR_REVOCATIONS_SCHEMA)
38
+ throw new TypeError("evolution deployment revocations schema is invalid");
39
+ if (!DIGEST.test(value.trustRootDigest || ""))
40
+ throw new TypeError("evolution deployment revocations trust root is invalid");
41
+ if (!Number.isSafeInteger(value.revision) || value.revision < 1)
42
+ throw new TypeError("evolution deployment revocations revision is invalid");
43
+ if (
44
+ !Array.isArray(value.revokedDescriptorRevisions) ||
45
+ value.revokedDescriptorRevisions.length > MAX_REVOKED_REVISIONS ||
46
+ value.revokedDescriptorRevisions.some(
47
+ (revision) => !Number.isSafeInteger(revision) || revision < 1,
48
+ ) ||
49
+ new Set(value.revokedDescriptorRevisions).size !==
50
+ value.revokedDescriptorRevisions.length
51
+ ) {
52
+ throw new TypeError("evolution deployment revoked revisions are invalid");
53
+ }
54
+ if (
55
+ typeof value.signature !== "string" ||
56
+ value.signature.length === 0 ||
57
+ !/^[A-Za-z0-9+/]+={0,2}$/u.test(value.signature)
58
+ ) {
59
+ throw new TypeError("evolution deployment revocations signature is invalid");
60
+ }
61
+ return Object.freeze({
62
+ ...value,
63
+ revokedDescriptorRevisions: Object.freeze(
64
+ [...value.revokedDescriptorRevisions].sort((left, right) => left - right),
65
+ ),
66
+ });
67
+ }
68
+
69
+ export function serializeEvolutionDeploymentDescriptorRevocationsPayload(value) {
70
+ const revocations = normalize({ ...value, signature: "AA==" });
71
+ return canonical({
72
+ schema: revocations.schema,
73
+ revision: revocations.revision,
74
+ trustRootDigest: revocations.trustRootDigest,
75
+ revokedDescriptorRevisions: revocations.revokedDescriptorRevisions,
76
+ });
77
+ }
78
+
79
+ export function verifyEvolutionDeploymentDescriptorRevocationsSync({
80
+ revocationPath,
81
+ trustRootPath,
82
+ expectedTrustRootDigest,
83
+ }) {
84
+ if (
85
+ typeof revocationPath !== "string" ||
86
+ !isAbsolute(revocationPath) ||
87
+ typeof trustRootPath !== "string" ||
88
+ !isAbsolute(trustRootPath) ||
89
+ !DIGEST.test(expectedTrustRootDigest || "")
90
+ ) {
91
+ throw new Error("evolution deployment revocation inputs are invalid");
92
+ }
93
+ let record;
94
+ let trustRootBytes;
95
+ try {
96
+ const bytes = readFileSync(revocationPath);
97
+ if (bytes.byteLength === 0 || bytes.byteLength > MAX_BYTES)
98
+ throw new Error("evolution deployment revocations size is invalid");
99
+ record = normalize(JSON.parse(bytes.toString("utf8")));
100
+ trustRootBytes = readFileSync(trustRootPath);
101
+ } catch (error) {
102
+ throw new Error(
103
+ "evolution deployment revocations could not be read",
104
+ error instanceof Error ? { cause: error } : undefined,
105
+ );
106
+ }
107
+ if (digest(trustRootBytes) !== expectedTrustRootDigest)
108
+ throw new Error("evolution deployment revocation trust root changed");
109
+ if (record.trustRootDigest !== expectedTrustRootDigest)
110
+ throw new Error("evolution deployment revocation trust root does not match");
111
+ let publicKey;
112
+ try {
113
+ publicKey = createPublicKey(trustRootBytes);
114
+ } catch {
115
+ throw new Error("evolution deployment revocation trust root is invalid");
116
+ }
117
+ if (
118
+ !verify(
119
+ null,
120
+ Buffer.from(
121
+ serializeEvolutionDeploymentDescriptorRevocationsPayload(record),
122
+ "utf8",
123
+ ),
124
+ publicKey,
125
+ Buffer.from(record.signature, "base64"),
126
+ )
127
+ ) {
128
+ throw new Error("evolution deployment revocation signature rejected");
129
+ }
130
+ return record;
131
+ }
@@ -2,7 +2,12 @@ import { createHash, createPublicKey, verify } from "node:crypto";
2
2
  import { readFile, realpath } from "node:fs/promises";
3
3
  import { isAbsolute } from "node:path";
4
4
  import { types as utilTypes } from "node:util";
5
- import { readEvolutionDeploymentProfile } from "./evolution-deployment-profile.js";
5
+ import {
6
+ assertEvolutionDeploymentActiveTrustRoot,
7
+ assertEvolutionDeploymentDescriptorNotRevoked,
8
+ assertEvolutionDeploymentRevisionFloor,
9
+ readEvolutionDeploymentProfile,
10
+ } from "./evolution-deployment-profile.js";
6
11
 
7
12
  export const EVOLUTION_DEPLOYMENT_DESCRIPTOR_SCHEMA =
8
13
  "chainlesschain.evolution-deployment-descriptor/v1";
@@ -486,8 +491,9 @@ export async function loadEvolutionDeploymentCommandDependencies(
486
491
  let descriptorPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_DESCRIPTOR;
487
492
  let trustRootPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_TRUST_ROOT;
488
493
  let fromSavedProfile = false;
494
+ let saved = null;
489
495
  if (!descriptorPath && !trustRootPath) {
490
- const saved = await readEvolutionDeploymentProfile({ env });
496
+ saved = await readEvolutionDeploymentProfile({ env });
491
497
  if (!saved.error && saved.profile?.enabled) {
492
498
  descriptorPath = saved.profile.descriptorPath;
493
499
  trustRootPath = saved.profile.trustRootPath;
@@ -505,6 +511,21 @@ export async function loadEvolutionDeploymentCommandDependencies(
505
511
  { descriptorPath, trustRootPath },
506
512
  { read, resolveRealPath, includeModuleBytes: true },
507
513
  );
514
+ if (fromSavedProfile)
515
+ assertEvolutionDeploymentActiveTrustRoot(
516
+ saved.profile,
517
+ verified.descriptor,
518
+ );
519
+ if (fromSavedProfile)
520
+ assertEvolutionDeploymentDescriptorNotRevoked(
521
+ saved.profile,
522
+ verified.descriptor,
523
+ );
524
+ if (fromSavedProfile)
525
+ assertEvolutionDeploymentRevisionFloor(
526
+ saved.profile,
527
+ verified.descriptor,
528
+ );
508
529
  } catch (error) {
509
530
  // A saved profile may become stale after files are moved or rotated. Keep
510
531
  // governed capabilities fail-closed while allowing `deployment status`,