chainlesschain 0.166.34 → 0.166.37

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 (188) hide show
  1. package/package.json +2 -2
  2. package/src/assets/web-panel/assets/{AIOps-D8PJmSrh.js → AIOps-B_Nt1Qe4.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-DG6DqHA3.js → ActionButton-CHQbie4X.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-DiLleeWs.js → Analytics-Bm9364Lw.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-DxYkhlHK.js → AppLayout-DTwlIh2v.js} +4 -4
  6. package/src/assets/web-panel/assets/{Artifacts-BAW3Kdsi.js → Artifacts-OibP0qB4.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-DBr4uY6E.js → Audit-B8Fwavkg.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-Dw0r-bHX.js → BackgroundAgents-p1Vb2K2B.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-AyhwYsio.js → Backup-BI3QT-wI.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-Cj8qJotr.js → BaseInput-BW_VRWWu.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DcvimQ0u.js → Chat-CUEhDQfq.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer--joJ1e2f.js → ChatBubbleRenderer-C5UVXdVE.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-C2mlU77l.js → Checkbox-URYsaaxv.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-CAfc3YaV.js → Codegen-DJAwC80a.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-CIxoxtJI.js → Col-DfRKFzc9.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-DvufZoRg.js → Community-GOkGHuly.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-55JTa99J.js → Compact-CIMs13NC.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-BllWog6P.js → Compliance-BE-TQIxV.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-ThsFGc5p.js → Cowork-CYmbJiWw.js} +4 -4
  20. package/src/assets/web-panel/assets/{Cron-CZjl5Ig2.js → Cron-Be3OIWyM.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-DIAKAoQT.js → Crosschain-2xB2HS2D.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-ayygwEil.js → DID-B_lJO2yF.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-C3Xjm2UO.js → Dashboard-DnVWqUER.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-C1S3zf-j.js → Dropdown-C7ZJvHVa.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-DRvriU-H.js → EmailListRenderer-DLevT-0F.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-iSX2bmsD.js → FamilyGuardDashboard-BwhQ5BRU.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-Dk0Stkv-.js → Federation-BkGI-Xkq.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-DasXSGff.js → FormItemContext-BgIIbMd7.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-Dv9XGlxI.js → GenericCardRenderer-qL-qN8Nb.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-B5PgXL3Z.js → Git-BTzgrC4U.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-B78x11e_.js → Governance-p28vdCN4.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-b7CX1RqW.js → Inference-Cqephrur.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph--MgBzMVp.js → KnowledgeGraph-C3v5Q4Zp.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-CYCiGmVc.js → Logs-T6f0w32w.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-yrl10SWw.js → MarkdownRenderer-Dj5XPm3S.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-CsbwQ0eM.js → Marketplace-ClDsvHDH.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-0GBWHVra.js → McpTools-C4P-_snx.js} +3 -3
  38. package/src/assets/web-panel/assets/{Memory-fAywmAYr.js → Memory-BZZfG6y6.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BeNEyy3s.js → MobileBridge-DpIv_BLs.js} +1 -1
  40. package/src/assets/web-panel/assets/MobileProjects-Buz3NIQg.js +1 -0
  41. package/src/assets/web-panel/assets/{Mtc-CqRhJB70.js → Mtc-HS2PJB79.js} +4 -4
  42. package/src/assets/web-panel/assets/{MtcAudit-BEyGZflc.js → MtcAudit-UmBrcU27.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-luz3EBT2.js → Multisig-C00sXiZf.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-Dkbvp8IX.js → NLProgramming-Dj1ng_ph.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-Cf9I2K8j.js → Notes-C4LEVKlk.js} +4 -4
  46. package/src/assets/web-panel/assets/{NotificationSettings-BTfuzynL.js → NotificationSettings-BWXwnekv.js} +1 -1
  47. package/src/assets/web-panel/assets/OrderTableRenderer-CZHfK8Nn.js +1 -0
  48. package/src/assets/web-panel/assets/{Organization-BbG3-vDy.js → Organization-CFEtFPrV.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-CMtFKEIQ.js → Overflow-DSz4MJK1.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-6SAEb_lU.js → P2P-DyTEytwG.js} +2 -2
  51. package/src/assets/web-panel/assets/PdhVaultBrowser-B5QNGLVx.js +7 -0
  52. package/src/assets/web-panel/assets/{Permissions-ClZxZKZl.js → Permissions-wEC_X7x4.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-BYkyoZDT.js → PersonalDataHub-If5GZlGZ.js} +3 -3
  54. package/src/assets/web-panel/assets/{Pipeline-B28ZgADI.js → Pipeline-LB4gqqmX.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-BxtZywbB.js → Privacy-QVLhoxcN.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-DPqoRnxK.js → ProjectInit-FaAbTYTo.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-QjKvMkau.js → ProjectSettings-DhMeNA21.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-Cp0Z8ZG0.js → Projects-5L4lkWAZ.js} +1 -1
  59. package/src/assets/web-panel/assets/{Providers-CrS-rbyb.js → Providers-DhZFp8fO.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-xTrhbVAU.js → QrScannerModal-BZuJ7_xi.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-DFOqJoq-.js → QuickAsk-TXddPYYb.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-DXlKqu2-.js → Recommend-DDuXIKYt.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-BLLaZH8K.js → RemoteSession-CDrTXImv.js} +3 -3
  64. package/src/assets/web-panel/assets/{Reputation-CUgAdJ11.js → Reputation-B2xKaKzt.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-DzOO3wP-.js → Row-DzAjWAOX.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-B6GrRvh8.js → RssFeed-CKH38BLF.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-Cj3zKLb3.js → Search-CuPqJYoQ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-LnktzidI.js → Security-DmAd2hxz.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-BQ6sIc2K.js → Services-Bt3nljnY.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-CCSV3Jbw.js → Skeleton-CP7RH093.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CpoQ4SNk.js → Skills-DKNeMBTx.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-DbAbgRPq.js → Sla-CbpM8Nrd.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-C4cJ_hoD.js → SpeechSettings-DTk-vTzF.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-BKFzjN9Z.js → SyncSettings-DKiplwmc.js} +2 -2
  75. package/src/assets/web-panel/assets/Tasks-z-lOm8fx.js +1 -0
  76. package/src/assets/web-panel/assets/{Templates-DTEQfFAQ.js → Templates-Rb-Q0DGX.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-wToJWKXB.js → Tenant-C2sqDUnR.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-1s3c7kmF.js → Terminal-DcyzskEE.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-BcfsYW3u.js → TimelineRenderer-lg0Eam7N.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-Byez6FY0.js → Tokens-D9USIMIA.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-Cq8mZO88.js → Trigger-BQpaQJ5k.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-DUrMmEwR.js → Trust-C-Mik04s.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-CVHwXrVU.js → UkeySign-DrnZ_o56.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-CDKbTRUS.js → VideoEditing-BDOsoZi0.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-BqnEBIOy.js → Wallet-Ct_bleI7.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-CeTMpj7_.js → WebAuthn-B6b6FDao.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-F6OgjV3C.js → WorkflowEditor-ZUJMaIHr.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-CMHUCwq3.js → chat-BII20OJy.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-DzVM_fpJ.js → colors-DEsJRV3n.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-Hhmg51yT.js → compact-item-DoDYAzN9.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-SwHt7x3Q.js → createContext-o_nofnVW.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-0tgDCszN.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-HGNKkn9A.js → hasIn-CAsABTHC.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-Cc-d6f0F.js → index-B0ApxOMw.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-E-bI8HpV.js → index-B4SfcwZA.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BJqNTF1S.js → index-B9Z75LfA.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DgoefbLs.js → index-B9hYHPhs.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CDtzUt75.js → index-BDRh3v44.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-B_HgLPC5.js → index-BcYbQoY7.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-C1QJxiOL.js → index-Bmwo5wQG.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-ChLHLBkF.js → index-Bn2ZPUXO.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-D5dcWBqg.js → index-BnbnmRqg.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-Bq9MMKno.js → index-Bqyg3PME.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-Ba2Kszdy.js → index-BrIIJ2s-.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BDt4wSl6.js → index-BxT8yTwS.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-COOcGOyK.js → index-Bycj011d.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DQT5thlV.js → index-BzMA6Ra3.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-F7Grz3-G.js → index-C1YDdyQ1.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-jrRtmiUh.js → index-CE2J04dA.js} +1 -1
  110. package/src/assets/web-panel/assets/index-CFF8XEFE.js +1 -0
  111. package/src/assets/web-panel/assets/{index-BDE-WiE5.js → index-CQE-WMEU.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-B6YQN5_R.js → index-CVQSl1uY.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-BlHB5eax.js → index-CeJSTcXw.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-C-YkiVyL.js → index-CeWJqXNX.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BRikmONJ.js → index-Cf3sFEoE.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-MDdTkUpA.js → index-D5Fd4tdL.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-CMG_2fK2.js → index-DDQzBK3l.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Co4RcBua.js → index-DQmX_-hk.js} +1 -1
  119. package/src/assets/web-panel/assets/{index--iOqM_AI.js → index-DRAA2McB.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-pwLuJGFh.js → index-DU2Rpx1m.js} +1 -1
  121. package/src/assets/web-panel/assets/index-DVUEISry.js +1 -0
  122. package/src/assets/web-panel/assets/{index-AQcDW8bB.js → index-DWZNYecl.js} +3 -3
  123. package/src/assets/web-panel/assets/{index-oz0Xxs8D.js → index-D_CMB_wC.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-aKV4Py_2.js → index-Dbb34cAr.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BstLYy9q.js → index-DciLb_Ww.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DyZUrnje.js → index-Dgt1mKby.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-sYkFp9A4.js → index-Dhnau6uw.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BDhCx17_.js → index-DrsAF-Ar.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Dcg7nQDe.js → index-DsoFTdA2.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-CWkWh48N.js → index-TSwbtCYG.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Cnm4zroJ.js → index-kIyLNyoF.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BmPYmoY3.js → index-tCeNfxv4.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-C_2QM45F.js → initDefaultProps-CNjeeoKE.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-DkxY04tR.js → motion-CBT8IZDm.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-D0CJlA7D.js → move-h1MOxjqv.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-DjP38YUD.js → mtc-parser-C_3pqNmn.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-C9CJDaGT.js → omit-CMUnPFDk.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-D5Wq2fa8.js → pickAttrs-p8_c1xq0.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-DJ6Dixs7.js → placementArrow-D6O67r23.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-DMmM0Dee.js → responsiveObserve-DquhepAK.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DipmpYA-.js → slide-CZ-m6gmS.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-DSqw6_nU.js → statusUtils-k9ejZFtd.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-t828MYjI.js → styleChecker-NX6_137R.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-COsSNzDQ.js → useFlexGapSupport-bCqR70lP.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-Bq5IEzv_.js → useFs-2l0vSqyY.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-CUKM0HdW.js → usePersonalDataHub-1yccm4O7.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-l-JwAt2M.js → vnode-CxQzajDo.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-D7xkW-gD.js → zoom-CrTKwFyb.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/hub.js +21 -6
  151. package/src/commands/llm.js +4 -3
  152. package/src/commands/stream.js +28 -7
  153. package/src/commands/ui.js +10 -2
  154. package/src/data/changelog.json +39 -0
  155. package/src/gateways/ws/chat-intent-protocol.js +4 -1
  156. package/src/gateways/ws/llm-chat-protocol.js +29 -3
  157. package/src/gateways/ws/message-dispatcher.js +3 -1
  158. package/src/gateways/ws/personal-data-hub-protocol.js +24 -10
  159. package/src/gateways/ws/session-core-protocol.js +23 -6
  160. package/src/gateways/ws/session-protocol.js +1 -0
  161. package/src/lib/__tests__/provider-stream.test.js +6 -8
  162. package/src/lib/chat-core.js +67 -9
  163. package/src/lib/chat-intent-service.js +138 -39
  164. package/src/lib/evolution/evolution-artifact-ports.js +40 -3
  165. package/src/lib/evolution/evolution-deployment-loader.js +7 -1
  166. package/src/lib/evolution/evolution-file-identity.js +50 -0
  167. package/src/lib/evolution/evolution-file-witness.js +206 -91
  168. package/src/lib/evolution/evolution-ledger-file-backend.js +4 -0
  169. package/src/lib/evolution/evolution-ledger.js +37 -5
  170. package/src/lib/evolution/evolution-witness-segments.js +330 -0
  171. package/src/lib/evolution/governed-hub-llm.js +56 -0
  172. package/src/lib/evolution/governed-hub-resolver.js +65 -0
  173. package/src/lib/evolution/governed-hub-skill.js +36 -0
  174. package/src/lib/evolution/governed-model-turn.js +88 -0
  175. package/src/lib/evolution/progressive-canary-external-watchdog.js +6 -4
  176. package/src/lib/evolution/skill-candidate-registry.js +45 -11
  177. package/src/lib/evolution/skill-release-registry.js +46 -12
  178. package/src/lib/llm-connection-probe.js +21 -4
  179. package/src/lib/personal-data-hub-wiring.js +49 -0
  180. package/src/lib/provider-stream.js +94 -45
  181. package/src/lib/ws-chat-handler.js +19 -2
  182. package/src/assets/web-panel/assets/MobileProjects-Zt1cpErd.js +0 -1
  183. package/src/assets/web-panel/assets/OrderTableRenderer-DBmCtl2H.js +0 -1
  184. package/src/assets/web-panel/assets/PdhVaultBrowser-CWG2OLvh.js +0 -7
  185. package/src/assets/web-panel/assets/Tasks-Cf4bl7NS.js +0 -1
  186. package/src/assets/web-panel/assets/devWarning-5q_Y0E88.js +0 -1
  187. package/src/assets/web-panel/assets/index-dl9TJMh5.js +0 -1
  188. package/src/assets/web-panel/assets/index-x0DDgUaT.js +0 -1
@@ -0,0 +1,330 @@
1
+ import path from "node:path";
2
+ import { ensurePrivateDirectory } from "../secure-fs.js";
3
+
4
+ export const EVOLUTION_SEGMENTED_WITNESS_SCHEMA =
5
+ "chainlesschain.evolution-file-witness-store/v2";
6
+ const SEGMENT_SCHEMA = "chainlesschain.evolution-file-witness-segment/v1";
7
+ export const EVOLUTION_WITNESS_SEGMENT_RECORDS = 256;
8
+ const MAX_RECORDS = 262_144;
9
+ const MAX_SEGMENTS = MAX_RECORDS / EVOLUTION_WITNESS_SEGMENT_RECORDS;
10
+ const MAX_CACHE_BYTES = 16 * 1024 * 1024;
11
+ const DIGEST = /^sha256:[a-f0-9]{64}$/u;
12
+ const HEAD_KEYS = new Set([
13
+ "schema",
14
+ "current",
15
+ "segments",
16
+ "history",
17
+ "discardedAnchors",
18
+ ]);
19
+ const SEGMENT_KEYS = new Set(["schema", "history", "discardedAnchors"]);
20
+
21
+ function exact(value, keys, label) {
22
+ if (
23
+ !value ||
24
+ typeof value !== "object" ||
25
+ Array.isArray(value) ||
26
+ Object.keys(value).length !== keys.size ||
27
+ Object.keys(value).some((key) => !keys.has(key))
28
+ ) {
29
+ throw new Error(`${label} fields are invalid`);
30
+ }
31
+ }
32
+
33
+ function matchesDiscard(entry, snapshot) {
34
+ return (
35
+ snapshot &&
36
+ (entry.anchorDigest === snapshot.anchorDigest ||
37
+ entry.headDigest === snapshot.headDigest ||
38
+ entry.segmentDigest === snapshot.segmentDigest)
39
+ );
40
+ }
41
+
42
+ /** Internal storage adapter. Record signatures and trust policy stay with the witness. */
43
+ export function createEvolutionWitnessSegments({
44
+ filePath,
45
+ fsImpl,
46
+ readBytes,
47
+ writeBytes,
48
+ confirmDurable,
49
+ validateStore,
50
+ legacySchema,
51
+ canonical,
52
+ hash,
53
+ encodeRecord,
54
+ maximumHistoryBytes,
55
+ }) {
56
+ const segmentDirectory = `${filePath}.segments-v2`;
57
+ const secureOptions = { deps: { fs: fsImpl }, failIfUnavailable: true };
58
+ const metadata = new WeakMap();
59
+ const cache = new Map();
60
+ let cacheBytes = 0;
61
+
62
+ const segmentPath = (digest) => {
63
+ if (!DIGEST.test(digest || ""))
64
+ throw new Error("witness segment digest is invalid");
65
+ return path.join(segmentDirectory, `${digest.slice(7)}.json`);
66
+ };
67
+
68
+ const assertDirectory = () => {
69
+ ensurePrivateDirectory(segmentDirectory, secureOptions);
70
+ const observed = fsImpl.lstatSync(segmentDirectory);
71
+ if (!observed.isDirectory() || observed.isSymbolicLink()) {
72
+ throw new Error("witness segment directory is invalid");
73
+ }
74
+ };
75
+
76
+ const validateSegment = (segment, previous, trustEpoch) => {
77
+ exact(segment, SEGMENT_KEYS, "witness segment");
78
+ if (
79
+ segment.schema !== SEGMENT_SCHEMA ||
80
+ !Array.isArray(segment.history) ||
81
+ segment.history.length !== EVOLUTION_WITNESS_SEGMENT_RECORDS
82
+ ) {
83
+ throw new Error("witness segment length or schema is invalid");
84
+ }
85
+ validateStore(
86
+ {
87
+ schema: legacySchema,
88
+ current: segment.history.at(-1),
89
+ history: segment.history,
90
+ discardedAnchors: segment.discardedAnchors,
91
+ },
92
+ trustEpoch,
93
+ previous,
94
+ );
95
+ return segment;
96
+ };
97
+
98
+ const observe = (records, discardedAnchors, observations) => {
99
+ for (const query of observations.discards) {
100
+ if (
101
+ discardedAnchors.some((entry) => matchesDiscard(entry, query.snapshot))
102
+ ) {
103
+ query.matched = true;
104
+ }
105
+ }
106
+ for (const query of observations.records) {
107
+ const firstGeneration = records[0].generation;
108
+ const index = query.checkpoint.generation - firstGeneration;
109
+ if (Number.isSafeInteger(index) && index >= 0 && index < records.length) {
110
+ const record = records[index];
111
+ if (record.witnessDigest === query.checkpoint.witnessDigest)
112
+ query.record = record;
113
+ }
114
+ }
115
+ };
116
+
117
+ const remember = (digest, segment, trustEpoch) => {
118
+ if (trustEpoch === null) return;
119
+ // A cached decision belongs only to bytes rehashed on this read and a
120
+ // current verifier epoch. Copy through a small encoding so no parser
121
+ // substring can retain a whole source segment.
122
+ const encoded = canonical({
123
+ first: segment.history[0],
124
+ last: segment.history.at(-1),
125
+ discardedAnchors: segment.discardedAnchors,
126
+ });
127
+ const bytes = 6 * encoded.length;
128
+ const existing = cache.get(digest);
129
+ if (existing) cacheBytes -= existing.bytes;
130
+ cache.delete(digest);
131
+ if (cache.size >= MAX_SEGMENTS || cacheBytes + bytes > MAX_CACHE_BYTES)
132
+ return;
133
+ cache.set(digest, { ...JSON.parse(encoded), trustEpoch, bytes });
134
+ cacheBytes += bytes;
135
+ };
136
+
137
+ const load = (head, trustEpoch, options = {}) => {
138
+ exact(head, HEAD_KEYS, "segmented witness store");
139
+ if (
140
+ head.schema !== EVOLUTION_SEGMENTED_WITNESS_SCHEMA ||
141
+ !Array.isArray(head.segments) ||
142
+ head.segments.length < 1 ||
143
+ head.segments.length >= MAX_SEGMENTS ||
144
+ !Array.isArray(head.history) ||
145
+ head.history.length < 1 ||
146
+ head.history.length > EVOLUTION_WITNESS_SEGMENT_RECORDS ||
147
+ head.segments.length * EVOLUTION_WITNESS_SEGMENT_RECORDS +
148
+ head.history.length >
149
+ MAX_RECORDS
150
+ ) {
151
+ throw new Error("segmented witness store capacity or schema is invalid");
152
+ }
153
+ assertDirectory();
154
+ const seen = new Set();
155
+ const observations = {
156
+ discards: (options.discards || [])
157
+ .filter(Boolean)
158
+ .map((snapshot) => ({ snapshot, matched: false })),
159
+ records: (options.records || []).map((checkpoint) => ({
160
+ checkpoint,
161
+ record: null,
162
+ })),
163
+ };
164
+ let previous = null;
165
+ let storedBytes = options.headBytes;
166
+ if (
167
+ !Number.isSafeInteger(storedBytes) ||
168
+ storedBytes < 1 ||
169
+ storedBytes > maximumHistoryBytes
170
+ ) {
171
+ throw new Error("witness history exceeds its configured maximum size");
172
+ }
173
+ for (const digest of head.segments) {
174
+ if (seen.has(digest)) throw new Error("witness segment is repeated");
175
+ seen.add(digest);
176
+ const bytes = readBytes(
177
+ segmentPath(digest),
178
+ maximumHistoryBytes - storedBytes,
179
+ );
180
+ storedBytes += bytes.length;
181
+ if (hash(bytes) !== digest)
182
+ throw new Error("witness segment bytes changed");
183
+ const cached = cache.get(digest);
184
+ const canReuse =
185
+ cached && trustEpoch !== null && cached.trustEpoch === trustEpoch;
186
+ const needsRecord = observations.records.some(
187
+ ({ checkpoint }) =>
188
+ canReuse &&
189
+ checkpoint.generation >= cached.first.generation &&
190
+ checkpoint.generation <= cached.last.generation,
191
+ );
192
+ if (canReuse) {
193
+ if (
194
+ (!previous && cached.first.generation !== 0) ||
195
+ (previous &&
196
+ (cached.first.generation !== previous.generation + 1 ||
197
+ cached.first.previousWitnessDigest !== previous.witnessDigest))
198
+ ) {
199
+ throw new Error("witness segment history is not contiguous");
200
+ }
201
+ for (const query of observations.discards) {
202
+ if (
203
+ cached.discardedAnchors.some((entry) =>
204
+ matchesDiscard(entry, query.snapshot),
205
+ )
206
+ ) {
207
+ query.matched = true;
208
+ }
209
+ }
210
+ if (needsRecord) {
211
+ const parsed = JSON.parse(
212
+ new TextDecoder("utf-8", { fatal: true }).decode(bytes),
213
+ );
214
+ observe(parsed.history, parsed.discardedAnchors, observations);
215
+ }
216
+ previous = cached.last;
217
+ continue;
218
+ }
219
+ const parsed = JSON.parse(
220
+ new TextDecoder("utf-8", { fatal: true }).decode(bytes),
221
+ );
222
+ const segment = validateSegment(parsed, previous, trustEpoch);
223
+ observe(segment.history, segment.discardedAnchors, observations);
224
+ remember(digest, segment, trustEpoch);
225
+ previous = segment.history.at(-1);
226
+ }
227
+ const store = validateStore(
228
+ {
229
+ schema: legacySchema,
230
+ current: head.current,
231
+ history: head.history,
232
+ discardedAnchors: head.discardedAnchors,
233
+ },
234
+ trustEpoch,
235
+ previous,
236
+ );
237
+ observe(store.history, store.discardedAnchors, observations);
238
+ metadata.set(store, {
239
+ segments: [...head.segments],
240
+ observations,
241
+ tailPreviousDiscardDigest: previous.discardAccumulatorDigest,
242
+ segmentBytes: storedBytes - options.headBytes,
243
+ });
244
+ return store;
245
+ };
246
+
247
+ const publish = (store) => {
248
+ const existing = metadata.get(store);
249
+ const segments = [...(existing?.segments || [])];
250
+ if (
251
+ segments.length * EVOLUTION_WITNESS_SEGMENT_RECORDS +
252
+ store.history.length >
253
+ MAX_RECORDS
254
+ ) {
255
+ throw new Error("witness history exceeds its configured record capacity");
256
+ }
257
+ assertDirectory();
258
+ let history = store.history;
259
+ let discardedAnchors = store.discardedAnchors;
260
+ let segmentBytes = existing?.segmentBytes ?? 0;
261
+ let accumulator =
262
+ existing?.tailPreviousDiscardDigest ??
263
+ history[0].discardAccumulatorDigest;
264
+ while (history.length > EVOLUTION_WITNESS_SEGMENT_RECORDS) {
265
+ const records = history.slice(0, EVOLUTION_WITNESS_SEGMENT_RECORDS);
266
+ let discardCount = 0;
267
+ // The first record's predecessor may belong to the preceding segment.
268
+ // The caller carries the exact predecessor accumulator when loading.
269
+ for (const record of records) {
270
+ if (record.discardAccumulatorDigest !== accumulator) discardCount++;
271
+ accumulator = record.discardAccumulatorDigest;
272
+ }
273
+ const part = {
274
+ schema: SEGMENT_SCHEMA,
275
+ history: records,
276
+ discardedAnchors: discardedAnchors.slice(0, discardCount),
277
+ };
278
+ const bytes = Buffer.from(`${canonical(part)}\n`, "utf8");
279
+ segmentBytes += bytes.length;
280
+ if (segmentBytes > maximumHistoryBytes) {
281
+ throw new Error("witness history exceeds its configured maximum size");
282
+ }
283
+ const digest = hash(bytes);
284
+ const destination = segmentPath(digest);
285
+ if (fsImpl.existsSync(destination)) {
286
+ if (!readBytes(destination).equals(bytes)) {
287
+ throw new Error(
288
+ "existing witness segment differs from its content address",
289
+ );
290
+ }
291
+ // A previous process may have stopped after rename and before fsync of
292
+ // the directory. Reuse requires that durability boundary again.
293
+ confirmDurable(destination, bytes);
294
+ } else {
295
+ // The witness CAS lock serializes publication. Only complete, fsynced
296
+ // bytes are renamed into this immutable content address before HEAD.
297
+ writeBytes(destination, bytes);
298
+ }
299
+ segments.push(digest);
300
+ history = history.slice(EVOLUTION_WITNESS_SEGMENT_RECORDS);
301
+ discardedAnchors = discardedAnchors.slice(discardCount);
302
+ }
303
+ const encoded = `{"current":${encodeRecord(store.current)},"discardedAnchors":${canonical(discardedAnchors)},"history":[${history.map(encodeRecord).join(",")}],"schema":${JSON.stringify(EVOLUTION_SEGMENTED_WITNESS_SCHEMA)},"segments":${canonical(segments)}}`;
304
+ const headBytes = Buffer.from(`${encoded}\n`, "utf8");
305
+ if (segmentBytes + headBytes.length > maximumHistoryBytes) {
306
+ throw new Error("witness history exceeds its configured maximum size");
307
+ }
308
+ writeBytes(filePath, headBytes);
309
+ return store.current;
310
+ };
311
+
312
+ return {
313
+ load,
314
+ publish,
315
+ handles: (store) =>
316
+ metadata.has(store) ||
317
+ store.history.length > EVOLUTION_WITNESS_SEGMENT_RECORDS,
318
+ isSegmented: (store) => metadata.has(store),
319
+ isDiscarded: (store, snapshot) =>
320
+ metadata
321
+ .get(store)
322
+ ?.observations.discards.find((query) => query.snapshot === snapshot)
323
+ ?.matched === true,
324
+ lookup: (store, checkpoint) =>
325
+ metadata
326
+ .get(store)
327
+ ?.observations.records.find((query) => query.checkpoint === checkpoint)
328
+ ?.record ?? null,
329
+ };
330
+ }
@@ -0,0 +1,56 @@
1
+ import { prepareGovernedModelTurn } from "./governed-model-turn.js";
2
+
3
+ // A scoped wrapper preserves the Hub's independent local/cloud consent check.
4
+ // Never replace llm on the process-wide cached Hub or its analysis engine.
5
+ export function createGovernedHubLlm(llm, factory) {
6
+ if (
7
+ !llm ||
8
+ typeof llm.chat !== "function" ||
9
+ typeof llm.isLocal !== "boolean"
10
+ ) {
11
+ throw new TypeError(
12
+ "A Hub model client with declared locality is required",
13
+ );
14
+ }
15
+ if (typeof factory !== "function")
16
+ throw new TypeError("A Hub evolution factory is required");
17
+ const identity = { name: llm.name, isLocal: llm.isLocal, chat: llm.chat };
18
+ const assertIdentity = () => {
19
+ if (
20
+ llm.name !== identity.name ||
21
+ llm.isLocal !== identity.isLocal ||
22
+ llm.chat !== identity.chat
23
+ ) {
24
+ throw new Error(
25
+ "Hub model identity changed; reopen the analysis invocation",
26
+ );
27
+ }
28
+ };
29
+ const chat = identity.chat.bind(llm);
30
+ return Object.freeze({
31
+ get name() {
32
+ assertIdentity();
33
+ return identity.name;
34
+ },
35
+ get isLocal() {
36
+ assertIdentity();
37
+ return identity.isLocal;
38
+ },
39
+ async chat(messages, options = {}) {
40
+ assertIdentity();
41
+ const turn = await prepareGovernedModelTurn(factory, {
42
+ mode: "hub-analysis",
43
+ messages,
44
+ signal: options.signal,
45
+ });
46
+ assertIdentity();
47
+ const response = await chat(turn.messages, options);
48
+ assertIdentity();
49
+ if (!response || typeof response.text !== "string") {
50
+ throw new Error("Hub model response must contain text");
51
+ }
52
+ await turn.complete(response.text);
53
+ return response;
54
+ },
55
+ });
56
+ }
@@ -0,0 +1,65 @@
1
+ import { prepareGovernedModelTurn } from "./governed-model-turn.js";
2
+ import { createGovernedHubLlm } from "./governed-hub-llm.js";
3
+
4
+ export function createGovernedHubResolver(ports, factory) {
5
+ if (typeof factory !== "function")
6
+ throw new TypeError("A resolver evolution factory is required");
7
+ const {
8
+ resolver,
9
+ llm,
10
+ embeddingStage,
11
+ EntityResolver,
12
+ EmbeddingStage,
13
+ LLMStage,
14
+ } = ports;
15
+ // Rebuild stages for each drain. Neither the shared resolver nor its embedding
16
+ // cache may acquire the authority of an individual WebSocket request.
17
+ const embedding =
18
+ embeddingStage &&
19
+ new EmbeddingStage({
20
+ vault: resolver.vault,
21
+ embedFn: async (profile) => {
22
+ const turn = await prepareGovernedModelTurn(factory, {
23
+ mode: "hub-embedding",
24
+ messages: [{ role: "user", content: profile }],
25
+ });
26
+ // Chat projection prepends host provenance. Embed only the projected
27
+ // profile: per-Run evidence IDs must not change semantic similarity.
28
+ const profileMessage = turn.messages[1];
29
+ if (
30
+ turn.messages.length !== 2 ||
31
+ turn.messages[0].role !== "system" ||
32
+ profileMessage?.role !== "user" ||
33
+ typeof profileMessage.content !== "string"
34
+ )
35
+ throw new Error(
36
+ "Projected embedding input must contain one text message",
37
+ );
38
+ const vector = await embeddingStage._embed(profileMessage.content);
39
+ if (
40
+ (!Array.isArray(vector) && !(vector instanceof Float32Array)) ||
41
+ vector.length === 0 ||
42
+ !Array.from(vector).every(Number.isFinite)
43
+ )
44
+ throw new Error(
45
+ "Embedding response must contain a nonempty finite vector",
46
+ );
47
+ await turn.complete(JSON.stringify(Array.from(vector)));
48
+ return vector;
49
+ },
50
+ });
51
+ const model =
52
+ resolver._llmStage &&
53
+ new LLMStage({
54
+ llm: createGovernedHubLlm(llm, factory),
55
+ acceptNonLocal: false,
56
+ });
57
+ return new EntityResolver({
58
+ vault: resolver.vault,
59
+ candidateLimit: resolver._candidateLimit,
60
+ embeddingHighThreshold: resolver._embeddingHighThreshold,
61
+ embeddingLowThreshold: resolver._embeddingLowThreshold,
62
+ embeddingStage: embedding ? embedding.asStageFn() : null,
63
+ llmStage: model ? model.asStageFn() : null,
64
+ });
65
+ }
@@ -0,0 +1,36 @@
1
+ import { createGovernedHubLlm } from "./governed-hub-llm.js";
2
+
3
+ // Analysis skills treat commentary failures as optional. A governed invocation
4
+ // must still surface a failed model turn after the SDK returns its report.
5
+ export async function runGovernedHubSkill(
6
+ hub,
7
+ factory,
8
+ runSkill,
9
+ name,
10
+ options,
11
+ ) {
12
+ const model = createGovernedHubLlm(hub.llm, factory);
13
+ let failure;
14
+ let failed = false;
15
+ const llm = Object.freeze({
16
+ get name() {
17
+ return model.name;
18
+ },
19
+ get isLocal() {
20
+ return model.isLocal;
21
+ },
22
+ async chat(messages, chatOptions) {
23
+ if (failed) throw failure;
24
+ try {
25
+ return await model.chat(messages, chatOptions);
26
+ } catch (error) {
27
+ failure = error;
28
+ failed = true;
29
+ throw error;
30
+ }
31
+ },
32
+ });
33
+ const result = await runSkill({ vault: hub.vault, llm }, name, options);
34
+ if (failed) throw failure;
35
+ return result;
36
+ }
@@ -0,0 +1,88 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { types } from "node:util";
3
+ import { captureAgentEvolutionRuntimeComposition } from "./agent-evolution-runtime-composition-brand.js";
4
+ import { captureAgentEvolutionIngress } from "./agent-evolution-ingress.js";
5
+
6
+ export function readEvolutionCompositionFactory(dependencies = {}) {
7
+ if (
8
+ !dependencies ||
9
+ typeof dependencies !== "object" ||
10
+ Array.isArray(dependencies) ||
11
+ types.isProxy(dependencies)
12
+ ) {
13
+ throw new TypeError("Model turn dependencies must be a plain object");
14
+ }
15
+ const property = Object.getOwnPropertyDescriptor(
16
+ dependencies,
17
+ "evolutionCompositionFactory",
18
+ );
19
+ if (
20
+ property &&
21
+ (!Object.hasOwn(property, "value") || typeof property.value !== "function")
22
+ ) {
23
+ throw new TypeError(
24
+ "evolutionCompositionFactory must be a function data property",
25
+ );
26
+ }
27
+ return property?.value ?? null;
28
+ }
29
+
30
+ // Only a host-owned factory can supply authority. Client messages supply input,
31
+ // never a run identifier or composition to borrow from another request.
32
+ export async function prepareGovernedModelTurn(
33
+ factory,
34
+ { mode, messages, signal },
35
+ ) {
36
+ signal?.throwIfAborted();
37
+ if (factory === null)
38
+ return {
39
+ governed: false,
40
+ messages,
41
+ complete: async () => {
42
+ signal?.throwIfAborted();
43
+ },
44
+ };
45
+ if (typeof factory !== "function")
46
+ throw new TypeError("Invalid evolution composition factory");
47
+ const runId = `${mode}-${randomUUID()}`;
48
+ const composition = captureAgentEvolutionRuntimeComposition(
49
+ await factory(
50
+ Object.freeze({ mode, runId, taskId: runId, cwd: process.cwd() }),
51
+ ),
52
+ );
53
+ const ingress = captureAgentEvolutionIngress(composition.evolutionIngress);
54
+ if (
55
+ composition.runId !== runId ||
56
+ ingress.runId !== runId ||
57
+ composition.tenantId !== ingress.tenantId
58
+ ) {
59
+ throw new Error(
60
+ "Model evolution composition is not bound to the requested Run",
61
+ );
62
+ }
63
+ signal?.throwIfAborted();
64
+ await ingress.start();
65
+ await ingress.ingestUserPrompt({ messages, source: mode });
66
+ const prepared = await ingress.prepareModelRequest({ messages, tools: [] });
67
+ signal?.throwIfAborted();
68
+ return Object.freeze({
69
+ governed: true,
70
+ messages: prepared.messages,
71
+ async complete(content) {
72
+ signal?.throwIfAborted();
73
+ await ingress.ingestAgentEvent({ type: "response-complete", content });
74
+ signal?.throwIfAborted();
75
+ await ingress.complete();
76
+ },
77
+ });
78
+ }
79
+
80
+ export async function* governModelTokenSource(source, turn, signal) {
81
+ let content = "";
82
+ for await (const delta of source) {
83
+ signal?.throwIfAborted();
84
+ content += delta;
85
+ yield delta;
86
+ }
87
+ await turn.complete(content);
88
+ }
@@ -218,6 +218,7 @@ export function createProgressiveCanaryHeartbeatAuthority({
218
218
  const authority = Object.freeze({
219
219
  planDigest: plan.planDigest,
220
220
  async issue({ sequence, stage, activeStateDigest } = {}) {
221
+ const issuedAt = timestamp(Number(now()), "heartbeat clock");
221
222
  const payload = {
222
223
  schema: PROGRESSIVE_CANARY_HOST_HEARTBEAT_SCHEMA,
223
224
  planDigest: plan.planDigest,
@@ -228,15 +229,16 @@ export function createProgressiveCanaryHeartbeatAuthority({
228
229
  sequence: timestamp(sequence, "heartbeat sequence"),
229
230
  stage: id(stage, "heartbeat stage"),
230
231
  activeStateDigest: digest(activeStateDigest, "activeStateDigest"),
231
- issuedAt: timestamp(Number(now()), "heartbeat clock"),
232
- expiresAt: Number(now()) + plan.leaseDurationMs,
232
+ issuedAt,
233
+ expiresAt: timestamp(
234
+ issuedAt + plan.leaseDurationMs,
235
+ "heartbeat expiry",
236
+ ),
233
237
  authorityId: plan.heartbeatAuthority.id,
234
238
  authorityRevision: plan.heartbeatAuthority.revision,
235
239
  handlerDigest: plan.heartbeatAuthority.handlerDigest,
236
240
  publicKeySpkiDigest: plan.heartbeatAuthority.publicKeySpkiDigest,
237
241
  };
238
- if (payload.expiresAt !== payload.issuedAt + plan.leaseDurationMs)
239
- throw new Error("heartbeat clock changed during issuance");
240
242
  const signature = await attestor(Object.freeze(structuredClone(payload)));
241
243
  const core = { ...payload, signature };
242
244
  return verify(