chainlesschain 0.166.117 → 0.166.118

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 (192) hide show
  1. package/README.md +26 -4
  2. package/package.json +3 -3
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/.build-hash +1 -1
  6. package/src/assets/web-panel/assets/{AIOps-C9tSCImB.js → AIOps-BGySwMIP.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-CXKExmT_.js → ActionButton-Chn7fBLr.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-DE8WBWHo.js → Analytics-ORH7UkGa.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-BdpwNM08.js → AppLayout-8xV4jWjP.js} +4 -4
  10. package/src/assets/web-panel/assets/{Artifacts-94TQpe38.js → Artifacts-26SBK-x-.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-DdDEv5Ej.js → Audit-CtXpqbXg.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-TU9nlV7j.js → BackgroundAgents-C5zLvQis.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-C0GPoUUq.js → Backup-C93xY4vO.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-iyrVn2I6.js → BaseInput-DpVCHfAn.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-Dqo8spwp.js → Chat-DM0LblR2.js} +5 -5
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CDqHSzc4.js → ChatBubbleRenderer-unlQUF1T.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-BF_XJvQi.js → Checkbox-BsAt3cKR.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-5tUWoOa9.js → Codegen-E_kp4KFd.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-BQxSeRvG.js → Col-6msR3T6I.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-B2Ra7w-J.js → Community-PyX9c5D-.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-GjxJwlr0.js → Compact-7G1bVDSH.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-BTUP6RTA.js → Compliance-DcHN7GlD.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-DiwfL16s.js → Cowork-WUIHJYDx.js} +2 -2
  24. package/src/assets/web-panel/assets/{Cron-1ceOo5ux.js → Cron-CWgCbptg.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-aHYxLu0u.js → Crosschain-BzKZ6roD.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-eeTjzOLV.js → DID-r7zxeItn.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-CT3fpkvX.js → Dashboard-D3pBiN2H.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-B3UpOy-N.js → Dropdown-C4otRJlZ.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-Ba2Rvoru.js → EmailListRenderer-CzDTC8lm.js} +1 -1
  30. package/src/assets/web-panel/assets/{EvolutionSettings-CGtn93on.js → EvolutionSettings-DGkXiIs-.js} +1 -1
  31. package/src/assets/web-panel/assets/{FamilyGuardDashboard-C0IUdHQt.js → FamilyGuardDashboard-BKdEyuiR.js} +1 -1
  32. package/src/assets/web-panel/assets/{Federation-1QIDwemn.js → Federation-dsI-xcpf.js} +1 -1
  33. package/src/assets/web-panel/assets/{FormItemContext-NGbSsdje.js → FormItemContext-CEEb1fMR.js} +1 -1
  34. package/src/assets/web-panel/assets/{GenericCardRenderer-DzVZc2Ba.js → GenericCardRenderer-D_mfO3Ts.js} +1 -1
  35. package/src/assets/web-panel/assets/{Git-B_1TDbSr.js → Git-CBwr2ZI3.js} +2 -2
  36. package/src/assets/web-panel/assets/{Governance-BDl_ySyI.js → Governance-D-Wy2Jjr.js} +1 -1
  37. package/src/assets/web-panel/assets/{Inference-CAp-wcCK.js → Inference-B4Yk_IRx.js} +1 -1
  38. package/src/assets/web-panel/assets/{KnowledgeGraph-DRjRcxul.js → KnowledgeGraph-DoI7bi6m.js} +1 -1
  39. package/src/assets/web-panel/assets/{Logs-qSuwMwk7.js → Logs-Ce1IiKAj.js} +2 -2
  40. package/src/assets/web-panel/assets/MarkdownRenderer-GND_8y0V.js +1 -0
  41. package/src/assets/web-panel/assets/{Marketplace-DfiXL6UO.js → Marketplace-CsIEByzK.js} +1 -1
  42. package/src/assets/web-panel/assets/{McpTools-D9rIvFjN.js → McpTools-_DRzjcIn.js} +2 -2
  43. package/src/assets/web-panel/assets/{Memory-D-p7yDzj.js → Memory-zvLpyi__.js} +2 -2
  44. package/src/assets/web-panel/assets/{MobileBridge-D0XT5B6m.js → MobileBridge-DXd1ik2Z.js} +1 -1
  45. package/src/assets/web-panel/assets/{MobileProjects-CL9cHVIk.js → MobileProjects-DKh2q-Y9.js} +1 -1
  46. package/src/assets/web-panel/assets/{Mtc-CME4kDmC.js → Mtc-Ct-fhtIx.js} +2 -2
  47. package/src/assets/web-panel/assets/{MtcAudit-BjGOXFnn.js → MtcAudit-J4zY3Oqk.js} +2 -2
  48. package/src/assets/web-panel/assets/{Multisig-CSzc53e0.js → Multisig-B2HJMCKe.js} +3 -3
  49. package/src/assets/web-panel/assets/{NLProgramming-BYjZnaH8.js → NLProgramming-CwcSmU4q.js} +1 -1
  50. package/src/assets/web-panel/assets/{Notes-BUPOYE0C.js → Notes-Da53L6wb.js} +3 -3
  51. package/src/assets/web-panel/assets/{NotificationSettings-BK8YADru.js → NotificationSettings-BxhufdrA.js} +1 -1
  52. package/src/assets/web-panel/assets/{OrderTableRenderer-B5F8bnWt.js → OrderTableRenderer-BoFwohAi.js} +1 -1
  53. package/src/assets/web-panel/assets/{Organization-B0WNlhMd.js → Organization-MIsMrUes.js} +4 -4
  54. package/src/assets/web-panel/assets/{Overflow-CED6ZO87.js → Overflow-Dy2P4v3q.js} +1 -1
  55. package/src/assets/web-panel/assets/{P2P-CBdc8fkP.js → P2P-CD9Sxn2y.js} +2 -2
  56. package/src/assets/web-panel/assets/{PdhVaultBrowser-DuauYi03.js → PdhVaultBrowser-BvBWgfG0.js} +3 -3
  57. package/src/assets/web-panel/assets/{Permissions-kfgY0ukN.js → Permissions-CwOlDRis.js} +4 -4
  58. package/src/assets/web-panel/assets/{PersonalDataHub-CDY3I1Do.js → PersonalDataHub-CZYaxEpv.js} +3 -3
  59. package/src/assets/web-panel/assets/{Pipeline-B9x0wKSK.js → Pipeline-kLU7PUbB.js} +1 -1
  60. package/src/assets/web-panel/assets/{Privacy-Cqhcr_Qv.js → Privacy-BVRycSiI.js} +1 -1
  61. package/src/assets/web-panel/assets/{ProjectInit-CFhoyo57.js → ProjectInit-DP3pr7uJ.js} +2 -2
  62. package/src/assets/web-panel/assets/{ProjectSettings-DCBjV2Hm.js → ProjectSettings-CACaDYjs.js} +2 -2
  63. package/src/assets/web-panel/assets/{Projects-C51w0LnM.js → Projects-CB1k4zTC.js} +1 -1
  64. package/src/assets/web-panel/assets/{Providers-BuCIWZY1.js → Providers-D7Y9WHRE.js} +1 -1
  65. package/src/assets/web-panel/assets/{QrScannerModal-CEXNL5CB.js → QrScannerModal-CeP8xzs1.js} +1 -1
  66. package/src/assets/web-panel/assets/{QuickAsk-DgK8aLAU.js → QuickAsk-iJVFrhZ2.js} +1 -1
  67. package/src/assets/web-panel/assets/{Recommend-BxEYQRAs.js → Recommend-DmTpnagw.js} +1 -1
  68. package/src/assets/web-panel/assets/{RemoteSession-PRsxNsYU.js → RemoteSession-C6ek8Uni.js} +2 -2
  69. package/src/assets/web-panel/assets/{Reputation-S-tQH70r.js → Reputation-CPfwc9de.js} +1 -1
  70. package/src/assets/web-panel/assets/{Row-U1Ws3CJl.js → Row-C1wwtSMJ.js} +1 -1
  71. package/src/assets/web-panel/assets/{RssFeed-BftCyeii.js → RssFeed-BiDJsqaH.js} +3 -3
  72. package/src/assets/web-panel/assets/{Search-o4gK0cPy.js → Search-BF6Aon95.js} +1 -1
  73. package/src/assets/web-panel/assets/{Security-U2ZRpsbA.js → Security-Bps0XnV4.js} +3 -3
  74. package/src/assets/web-panel/assets/{Services-D0tRjWl_.js → Services-uf92smGR.js} +2 -2
  75. package/src/assets/web-panel/assets/{Skeleton-DzZ8TFsB.js → Skeleton-DQd4eVWW.js} +1 -1
  76. package/src/assets/web-panel/assets/{Skills-B1cC7rju.js → Skills-DgamiYa5.js} +1 -1
  77. package/src/assets/web-panel/assets/{Sla-CtIHOR0J.js → Sla-CF1IVIrm.js} +1 -1
  78. package/src/assets/web-panel/assets/{SpeechSettings-CD8ZlQpW.js → SpeechSettings-Bzxmjbpc.js} +1 -1
  79. package/src/assets/web-panel/assets/{SyncSettings-BilFQWQk.js → SyncSettings-B8zKauiq.js} +2 -2
  80. package/src/assets/web-panel/assets/{Tasks-Bmg2qLXl.js → Tasks-DPKV_xSt.js} +1 -1
  81. package/src/assets/web-panel/assets/{Templates-D6yofyC1.js → Templates-BikeSZIF.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tenant-BzttD-Gp.js → Tenant-CEaUaDkJ.js} +1 -1
  83. package/src/assets/web-panel/assets/{Terminal-DyRXeYuH.js → Terminal-ZPgOSQ_q.js} +3 -3
  84. package/src/assets/web-panel/assets/{TimelineRenderer-Bdmkx-Tr.js → TimelineRenderer-DmyB4Udk.js} +1 -1
  85. package/src/assets/web-panel/assets/{Tokens-10RcVAVJ.js → Tokens-g85Pm5TO.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trigger-CKV-9DdV.js → Trigger-D202hx9a.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trust-BEc-sW1q.js → Trust-DzvQYVFy.js} +1 -1
  88. package/src/assets/web-panel/assets/{UkeySign-BSql8piX.js → UkeySign-KRzwddVg.js} +1 -1
  89. package/src/assets/web-panel/assets/{VideoEditing-C4OH2f4s.js → VideoEditing-IRBXLO2z.js} +1 -1
  90. package/src/assets/web-panel/assets/{Wallet-BSSvWKmv.js → Wallet-DSf5KPgQ.js} +4 -4
  91. package/src/assets/web-panel/assets/{WebAuthn-LxIzXo9d.js → WebAuthn-DNPxLTCc.js} +5 -5
  92. package/src/assets/web-panel/assets/{WorkflowEditor-DWwdfcte.js → WorkflowEditor-C3wAtVcK.js} +1 -1
  93. package/src/assets/web-panel/assets/{addon-fit-CK6X9sAG.js → addon-fit-CbkjSUJl.js} +1 -1
  94. package/src/assets/web-panel/assets/{chat-DWxYYLD5.js → chat-q3XXUtv2.js} +1 -1
  95. package/src/assets/web-panel/assets/{colors-BxEcQqtg.js → colors-CF54SNei.js} +1 -1
  96. package/src/assets/web-panel/assets/{compact-item-DNbezFOJ.js → compact-item-BaRkvZuT.js} +1 -1
  97. package/src/assets/web-panel/assets/{createContext-DaJXc5nx.js → createContext-CDR9hsfs.js} +1 -1
  98. package/src/assets/web-panel/assets/devWarning-1LO-NplX.js +1 -0
  99. package/src/assets/web-panel/assets/{hasIn-BMrw3sg3.js → hasIn-DlC--S8R.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DpSp97J8.js → index-B0Ptc7yu.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-DzZHBzCb.js → index-B0V9rgdu.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DEvdSKT4.js → index-BEiUlFKb.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-pzYLf5qu.js → index-BJO0n1LQ.js} +1 -1
  104. package/src/assets/web-panel/assets/index-BLaJsev4.js +1 -0
  105. package/src/assets/web-panel/assets/index-BLmviChG.js +1 -0
  106. package/src/assets/web-panel/assets/{index-2c0bL3SE.js → index-BU5DJqk7.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Dr18agDl.js → index-BY-Tf3OM.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-T4T84G6X.js → index-BZrE0Go8.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-LRb0QX6S.js → index-BizdX2X5.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B9b6UaZl.js → index-C87Yr3h1.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-BAV07GDK.js → index-C9Wypz9e.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-B_b9_6wQ.js → index-CAoG_E-q.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-NEW5EN2w.js → index-CAxSyMrF.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Dwg38xTG.js → index-CC5HjNM6.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Bs2QyMPQ.js → index-CNZQEZ9g.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-BR4nWOmR.js → index-CPvIhha6.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-hPy_f08G.js → index-CR_wqMGy.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-IX0g0s2t.js → index-CSClXoB3.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-cCqCEa9X.js → index-CZ8azVgB.js} +3 -3
  120. package/src/assets/web-panel/assets/{index-C25ig6EV.js → index-Ccc5z8eJ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-7zzLqfvI.js → index-CeiKbM3a.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CpwgF7vh.js → index-Cl6av3X7.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BNZDGV2q.js → index-CtGfeD7E.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-6W0V5G2t.js → index-Ctid12Gq.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BaByEdBj.js → index-D0H-N0uG.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BCCd8Rj6.js → index-D0vIgprF.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CL-36X3A.js → index-D4wUDFRg.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DL0k35f0.js → index-DJFipyK7.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BcuytRTa.js → index-DX2REKNp.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Cm9DYzhC.js → index-Dc3gD0cw.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Bum_aSyd.js → index-DiQzer2R.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CaxzeSIM.js → index-DntKLOs9.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-cKBpcInt.js → index-Dplhl6gh.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-Ca2hwPMo.js → index-Dq8q_PWB.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DarVV5yG.js → index-IVQdOBNN.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-rFaCnjXi.js → index-Kerduyao.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-VD-dTYQE.js → index-W6cLGjpW.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-CiEdfbB9.js → index-qZDNFll9.js} +1 -1
  139. package/src/assets/web-panel/assets/{initDefaultProps-BWVLgWhF.js → initDefaultProps-Ccz7v71u.js} +1 -1
  140. package/src/assets/web-panel/assets/{markdown-Yo_c6Krv.js → markdown-Bq2x0XsR.js} +1 -1
  141. package/src/assets/web-panel/assets/markdown-DUKxbhE4.js +51 -0
  142. package/src/assets/web-panel/assets/{motion-KJZ1xfDE.js → motion-BlCLpVDp.js} +1 -1
  143. package/src/assets/web-panel/assets/{move-DGqU6H7M.js → move-B80G7fLU.js} +1 -1
  144. package/src/assets/web-panel/assets/{mtc-parser-Dg0xkI5J.js → mtc-parser-Djw08NJh.js} +1 -1
  145. package/src/assets/web-panel/assets/{omit-B6RnMJAQ.js → omit-Bg_G1eUr.js} +1 -1
  146. package/src/assets/web-panel/assets/{pickAttrs-Ctw2i3jb.js → pickAttrs-Df9zYUg2.js} +1 -1
  147. package/src/assets/web-panel/assets/{placementArrow-D3F3x8Jm.js → placementArrow-DjCDLhJ4.js} +1 -1
  148. package/src/assets/web-panel/assets/{responsiveObserve-W6eHE0nM.js → responsiveObserve--Naz7NgY.js} +1 -1
  149. package/src/assets/web-panel/assets/{slide-BlFf8sY5.js → slide-CHn3ald-.js} +1 -1
  150. package/src/assets/web-panel/assets/{statusUtils-Cd6LMwmy.js → statusUtils-BiGwoIK_.js} +1 -1
  151. package/src/assets/web-panel/assets/{styleChecker-Bg5-U4Y1.js → styleChecker-Zf2dQx1j.js} +1 -1
  152. package/src/assets/web-panel/assets/{useFlexGapSupport-DTkLS3tn.js → useFlexGapSupport-sLES8nyD.js} +1 -1
  153. package/src/assets/web-panel/assets/{useFs-CwYGzoBt.js → useFs-DV1Hl4qu.js} +1 -1
  154. package/src/assets/web-panel/assets/{usePersonalDataHub-PCgFQXZP.js → usePersonalDataHub-CZXr2Qxg.js} +1 -1
  155. package/src/assets/web-panel/assets/{vnode-CJM7MkrB.js → vnode-e8Eo3Oyl.js} +1 -1
  156. package/src/assets/web-panel/assets/{xterm-BZcWGsqw.js → xterm-zbskxxGA.js} +1 -1
  157. package/src/assets/web-panel/assets/{zoom-CP0mgaFi.js → zoom-B8A6xKMF.js} +1 -1
  158. package/src/assets/web-panel/index.html +1 -1
  159. package/src/data/changelog.json +15 -2
  160. package/src/harness/jsonl-session-store.js +2 -1
  161. package/src/lib/artifact-store.js +129 -20
  162. package/src/lib/bounded-artifact-file-read.js +128 -46
  163. package/src/lib/evolution/agent-evolution-ingress.js +41 -7
  164. package/src/lib/evolution/agent-evolution-runtime-composition.js +65 -27
  165. package/src/lib/evolution/evidence-json-text.js +65 -3
  166. package/src/lib/evolution/evolution-artifact-ports.js +1005 -83
  167. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +59 -15
  168. package/src/lib/evolution/evolution-evidence-projector.js +35 -3
  169. package/src/lib/evolution/evolution-evidence-storage-layout.js +115 -0
  170. package/src/lib/evolution/evolution-file-witness.js +7 -3
  171. package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +6 -2
  172. package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +6 -2
  173. package/src/lib/evolution/evolution-ledger.js +226 -55
  174. package/src/lib/evolution/evolution-private-storage.js +20 -0
  175. package/src/lib/evolution/evolution-run-ledger-adapter.js +298 -11
  176. package/src/lib/evolution/evolution-windows-directory-durability.js +215 -32
  177. package/src/lib/evolution/local-ui-evolution-runtime.js +3 -38
  178. package/src/lib/evolution/local-ui-signing-authority.js +69 -0
  179. package/src/lib/ollama-provider-fetch.js +33 -0
  180. package/src/lib/provider-stream.js +14 -13
  181. package/src/lib/session-history-origins.js +71 -32
  182. package/src/lib/session-message-provenance.js +26 -2
  183. package/src/lib/session-runtime-retention.js +10 -1
  184. package/src/lib/session-transcript-migration.js +67 -12
  185. package/src/lib/storage-failure-cause-codes.js +449 -0
  186. package/src/runtime/agent-core.js +54 -33
  187. package/src/runtime/headless-stream.js +89 -10
  188. package/src/assets/web-panel/assets/MarkdownRenderer-BgnYTegK.js +0 -1
  189. package/src/assets/web-panel/assets/devWarning-CRyXoGo9.js +0 -1
  190. package/src/assets/web-panel/assets/index-C-W0Ntk_.js +0 -1
  191. package/src/assets/web-panel/assets/index-CCk_qhBx.js +0 -1
  192. package/src/assets/web-panel/assets/markdown-CsiA8-E5.js +0 -50
@@ -2,7 +2,10 @@
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
4
  import { readBoundedDescriptor } from "./evolution/bounded-descriptor-read.js";
5
- import { withEvolutionFileIdentity } from "./evolution/evolution-file-identity.js";
5
+ import {
6
+ withEvolutionDirectoryFileIdentity,
7
+ withEvolutionFileIdentity,
8
+ } from "./evolution/evolution-file-identity.js";
6
9
  import { artifactPhysicalIdentity } from "./evolution/evolution-artifact-identity.js";
7
10
 
8
11
  export const ARTIFACT_BOUNDED_READ_FAILED_CODE =
@@ -67,10 +70,10 @@ function sameStat(left, right) {
67
70
  );
68
71
  }
69
72
 
70
- /** Read one stable window only. Callers retain hash/signature and root checks. */
71
- export function readBoundedArtifactFile(target, expectedSize, maximumBytes) {
73
+ function assertReadArguments(args) {
74
+ const [target, expectedSize, maximumBytes] = args;
72
75
  if (
73
- arguments.length !== 3 ||
76
+ args.length !== 3 ||
74
77
  typeof target !== "string" ||
75
78
  !path.isAbsolute(target) ||
76
79
  path.resolve(target) !== target ||
@@ -83,49 +86,128 @@ export function readBoundedArtifactFile(target, expectedSize, maximumBytes) {
83
86
  throw new TypeError(
84
87
  "bounded artifact read requires a canonical path and finite size bounds",
85
88
  );
89
+ }
90
+
91
+ function readWithIdentity(target, expectedSize, maximumBytes, samePathHandle) {
92
+ const before = fs.lstatSync(target, { bigint: true });
93
+ safeStat(before, expectedSize, maximumBytes, "artifact path");
94
+ if (canonical(fs.realpathSync.native(target)) !== canonical(target))
95
+ fail("artifact path is not physically canonical");
96
+ const fd = fs.openSync(
97
+ target,
98
+ fs.constants.O_RDONLY |
99
+ (fs.constants.O_NOFOLLOW || 0) |
100
+ (fs.constants.O_NONBLOCK || 0),
101
+ );
86
102
  try {
87
- return withEvolutionFileIdentity(DIRECTORY_FS, target, (samePathHandle) => {
88
- const before = fs.lstatSync(target, { bigint: true });
89
- safeStat(before, expectedSize, maximumBytes, "artifact path");
90
- if (canonical(fs.realpathSync.native(target)) !== canonical(target))
91
- fail("artifact path is not physically canonical");
92
- const fd = fs.openSync(
93
- target,
94
- fs.constants.O_RDONLY |
95
- (fs.constants.O_NOFOLLOW || 0) |
96
- (fs.constants.O_NONBLOCK || 0),
97
- );
98
- try {
99
- const opened = fs.fstatSync(fd, { bigint: true });
100
- safeStat(opened, expectedSize, maximumBytes, "artifact descriptor");
101
- if (!samePathHandle(before, opened) || !sameMetadata(before, opened))
102
- fail("artifact path and descriptor identities differ");
103
- const bytes = readBoundedDescriptor(
104
- fs,
105
- fd,
106
- Number(opened.size),
107
- maximumBytes,
108
- );
109
- const closed = fs.fstatSync(fd, { bigint: true });
110
- const after = fs.lstatSync(target, { bigint: true });
111
- safeStat(closed, expectedSize, maximumBytes, "artifact descriptor");
112
- safeStat(after, expectedSize, maximumBytes, "artifact path");
113
- if (!sameStat(opened, closed))
114
- fail("artifact descriptor changed during bounded read");
115
- if (
116
- !sameStat(before, after) ||
117
- !samePathHandle(after, closed) ||
118
- !sameMetadata(after, closed) ||
119
- canonical(fs.realpathSync.native(target)) !== canonical(target)
120
- )
121
- fail("artifact pathname changed during bounded read");
122
- return bytes;
123
- } finally {
124
- fs.closeSync(fd);
125
- }
126
- });
103
+ const opened = fs.fstatSync(fd, { bigint: true });
104
+ safeStat(opened, expectedSize, maximumBytes, "artifact descriptor");
105
+ if (!samePathHandle(before, opened) || !sameMetadata(before, opened))
106
+ fail("artifact path and descriptor identities differ");
107
+ const bytes = readBoundedDescriptor(
108
+ fs,
109
+ fd,
110
+ Number(opened.size),
111
+ maximumBytes,
112
+ );
113
+ const closed = fs.fstatSync(fd, { bigint: true });
114
+ const after = fs.lstatSync(target, { bigint: true });
115
+ safeStat(closed, expectedSize, maximumBytes, "artifact descriptor");
116
+ safeStat(after, expectedSize, maximumBytes, "artifact path");
117
+ if (!sameStat(opened, closed))
118
+ fail("artifact descriptor changed during bounded read");
119
+ if (
120
+ !sameStat(before, after) ||
121
+ !samePathHandle(after, closed) ||
122
+ !sameMetadata(after, closed) ||
123
+ canonical(fs.realpathSync.native(target)) !== canonical(target)
124
+ )
125
+ fail("artifact pathname changed during bounded read");
126
+ return bytes;
127
+ } finally {
128
+ fs.closeSync(fd);
129
+ }
130
+ }
131
+
132
+ function wrapReadFailure(cause) {
133
+ if (cause?.code === ARTIFACT_BOUNDED_READ_FAILED_CODE) throw cause;
134
+ fail("artifact bounded descriptor read failed", cause);
135
+ }
136
+
137
+ /** Read one stable window only. Callers retain hash/signature and root checks. */
138
+ export function readBoundedArtifactFile(target, expectedSize, maximumBytes) {
139
+ assertReadArguments(arguments);
140
+ try {
141
+ return withEvolutionFileIdentity(DIRECTORY_FS, target, (samePathHandle) =>
142
+ readWithIdentity(target, expectedSize, maximumBytes, samePathHandle),
143
+ );
144
+ } catch (cause) {
145
+ wrapReadFailure(cause);
146
+ }
147
+ }
148
+
149
+ /**
150
+ * A synchronous batch shares one authenticated parent handle, never file
151
+ * contents or authority. Each child keeps the complete independent read
152
+ * window above. The parent is reattested before the batch can return.
153
+ */
154
+ export function withBoundedArtifactDirectoryRead(directory, callback) {
155
+ if (
156
+ arguments.length !== 2 ||
157
+ typeof directory !== "string" ||
158
+ !path.isAbsolute(directory) ||
159
+ path.resolve(directory) !== directory ||
160
+ typeof callback !== "function" ||
161
+ callback.constructor?.name === "AsyncFunction"
162
+ )
163
+ throw new TypeError(
164
+ "bounded artifact directory read requires a canonical directory and synchronous callback",
165
+ );
166
+ let callbackFailure = null;
167
+ try {
168
+ return withEvolutionDirectoryFileIdentity(
169
+ DIRECTORY_FS,
170
+ directory,
171
+ (samePathHandle, _sameStableHandle, { parentPath }) => {
172
+ if (canonical(parentPath) !== canonical(directory))
173
+ fail("artifact batch parent is not physically canonical");
174
+ let active = true;
175
+ const read = Object.freeze((...args) => {
176
+ if (!active) fail("artifact batch read window is closed");
177
+ assertReadArguments(args);
178
+ const [target, expectedSize, maximumBytes] = args;
179
+ if (canonical(path.dirname(target)) !== canonical(parentPath))
180
+ fail(
181
+ "artifact batch read must name a direct child of its captured parent",
182
+ );
183
+ try {
184
+ return readWithIdentity(
185
+ target,
186
+ expectedSize,
187
+ maximumBytes,
188
+ samePathHandle,
189
+ );
190
+ } catch (cause) {
191
+ wrapReadFailure(cause);
192
+ }
193
+ });
194
+ try {
195
+ const result = callback(read);
196
+ if (result && typeof result.then === "function")
197
+ throw new TypeError(
198
+ "artifact batch callback must not return a promise",
199
+ );
200
+ return result;
201
+ } catch (cause) {
202
+ callbackFailure = cause;
203
+ throw cause;
204
+ } finally {
205
+ active = false;
206
+ }
207
+ },
208
+ );
127
209
  } catch (cause) {
128
- if (cause?.code === ARTIFACT_BOUNDED_READ_FAILED_CODE) throw cause;
129
- fail("artifact bounded descriptor read failed", cause);
210
+ if (cause === callbackFailure) throw cause;
211
+ wrapReadFailure(cause);
130
212
  }
131
213
  }
@@ -1,6 +1,7 @@
1
1
  import crypto from "node:crypto";
2
2
  import { types } from "node:util";
3
3
  import evolutionRun from "@chainlesschain/session-core/evolution-run";
4
+ import { storageFailureCauseSuffix } from "../storage-failure-cause-codes.js";
4
5
 
5
6
  import { EvolutionEvidenceArtifactAdapter } from "./evolution-evidence-artifact-adapter.js";
6
7
  import {
@@ -8,7 +9,14 @@ import {
8
9
  EVOLUTION_SKILL_DECISION_PROJECTION_RULESET_DIGEST,
9
10
  EVOLUTION_PROJECTION_RULESET_DIGEST,
10
11
  } from "./evolution-evidence-projector.js";
11
- import { EvolutionRunLedgerAdapter } from "./evolution-run-ledger-adapter.js";
12
+ import {
13
+ EvolutionRunLedgerAdapter,
14
+ captureEvolutionRunAppendNext,
15
+ } from "./evolution-run-ledger-adapter.js";
16
+ import {
17
+ evidenceStorageLayoutForRun,
18
+ validateEvidenceStorageLayout,
19
+ } from "./evolution-evidence-storage-layout.js";
12
20
  import { captureEvolutionRunWikiMaintenanceProducer } from "./evolution-run-wiki-maintenance-source.js";
13
21
  import { WIKI_MAINTENANCE_TRIGGER_KIND } from "./wiki-maintenance-trigger-ledger-adapter.js";
14
22
  import { captureEvolutionReleaseTrain } from "./evolution-release-train.js";
@@ -152,6 +160,7 @@ function ingressFailure(cause) {
152
160
  `Agent evolution ingress failed: ${cause?.message || String(cause)}`,
153
161
  { cause },
154
162
  );
163
+ error.message += storageFailureCauseSuffix(cause);
155
164
  error.code = AGENT_EVOLUTION_INGRESS_FAILED_CODE;
156
165
  return error;
157
166
  }
@@ -165,6 +174,7 @@ function guardIngress(operation) {
165
174
  export function createAgentEvolutionIngress({
166
175
  evidenceAdapter,
167
176
  runAdapter,
177
+ evidenceStorageLayout = "legacy",
168
178
  sourceEnvelopeAuthority,
169
179
  openCacheSourceRun = null,
170
180
  wikiMaintenanceProducer = null,
@@ -173,6 +183,7 @@ export function createAgentEvolutionIngress({
173
183
  now = () => new Date(),
174
184
  idGenerator = () => crypto.randomUUID(),
175
185
  } = {}) {
186
+ validateEvidenceStorageLayout(evidenceStorageLayout);
176
187
  if (!(evidenceAdapter instanceof EvolutionEvidenceArtifactAdapter)) {
177
188
  throw new TypeError("an EvolutionEvidenceArtifactAdapter is required");
178
189
  }
@@ -245,10 +256,24 @@ export function createAgentEvolutionIngress({
245
256
  return timestamp(iso, "ingress timestamp");
246
257
  };
247
258
 
259
+ const assertLoadedLayout = (loaded) => {
260
+ if (
261
+ evidenceStorageLayoutForRun(loaded.events, evidenceStorageLayout) !==
262
+ evidenceStorageLayout
263
+ )
264
+ throw new Error("Authenticated Run Evidence storage layout changed");
265
+ };
266
+
248
267
  const appendStarted = () => {
249
268
  const loaded = runAdapter.load();
269
+ assertLoadedLayout(loaded);
250
270
  if (loaded.events.length > 0) return loaded.projection;
251
271
  const occurredAt = currentTimestamp();
272
+ const data = {
273
+ occurredAt,
274
+ runtime: "agent",
275
+ ...(evidenceStorageLayout === "legacy" ? {} : { evidenceStorageLayout }),
276
+ };
252
277
  return runAdapter.appendEvent({
253
278
  schema: EVOLUTION_RUN_EVENT_SCHEMA,
254
279
  tenantId: descriptor.tenantId,
@@ -257,10 +282,10 @@ export function createAgentEvolutionIngress({
257
282
  sequence: 1,
258
283
  type: EVENT_TYPES.RUN_STARTED,
259
284
  subjectId: descriptor.runId,
260
- payloadDigest: digest({ occurredAt, runtime: "agent" }),
285
+ payloadDigest: digest(data),
261
286
  artifactRef: null,
262
287
  keyRef: null,
263
- data: { occurredAt, runtime: "agent" },
288
+ data,
264
289
  }).projection;
265
290
  };
266
291
 
@@ -347,13 +372,14 @@ export function createAgentEvolutionIngress({
347
372
  "Agent evidence persistence returned an unbound result",
348
373
  );
349
374
  }
350
- const current = runAdapter.load();
351
- const appended = runAdapter.appendEvent({
375
+ const appendNext = captureEvolutionRunAppendNext(runAdapter);
376
+ // Custom ports keep their established load-before-append phase.
377
+ const current = appendNext === null ? runAdapter.load() : null;
378
+ const event = {
352
379
  schema: EVOLUTION_RUN_EVENT_SCHEMA,
353
380
  tenantId: descriptor.tenantId,
354
381
  runId: descriptor.runId,
355
382
  eventId,
356
- sequence: current.events.length + 1,
357
383
  type: EVENT_TYPES.RAW_EVENT_REFERENCED,
358
384
  subjectId: persisted.evidenceId,
359
385
  payloadDigest: persisted.manifest.digest,
@@ -371,7 +397,14 @@ export function createAgentEvolutionIngress({
371
397
  candidateSetDigest: skillDecisionRequest.candidateSetDigest,
372
398
  }),
373
399
  },
374
- });
400
+ };
401
+ const appended =
402
+ appendNext !== null
403
+ ? appendNext(event)
404
+ : runAdapter.appendEvent({
405
+ ...event,
406
+ sequence: current.events.length + 1,
407
+ });
375
408
  if (kind === "model-input") {
376
409
  lastModelResponse = null;
377
410
  modelAdmissionPending = true;
@@ -677,6 +710,7 @@ export function createAgentEvolutionIngress({
677
710
  serialize(async () => {
678
711
  if (admissionFailure !== null) throw admissionFailure;
679
712
  const loaded = runAdapter.load();
713
+ assertLoadedLayout(loaded);
680
714
  let projection;
681
715
  if (loaded.projection?.status === "completed") {
682
716
  projection = loaded.projection;
@@ -14,6 +14,11 @@ import {
14
14
  EvolutionEvidenceReader,
15
15
  } from "./evolution-evidence-projector.js";
16
16
  import { EvolutionArtifactPorts } from "./evolution-artifact-ports.js";
17
+ import {
18
+ createTypedEvidenceArtifactPorts,
19
+ evidenceStorageLayoutForRun,
20
+ validateEvidenceStorageLayout,
21
+ } from "./evolution-evidence-storage-layout.js";
17
22
  import {
18
23
  captureEvolutionLedgerFileBackend,
19
24
  createEvolutionLedgerFileBackend,
@@ -172,16 +177,14 @@ function layout(stateRootDir, tenantId, runId, initialize = true, fsImpl = fs) {
172
177
  const result = Object.freeze({
173
178
  rootDir,
174
179
  artifactDir: path.join(scope, "artifacts"),
180
+ evidenceArtifactDir: path.join(scope, "evidence-artifacts"),
175
181
  rawDir: path.join(scope, "raw"),
176
182
  ledgerRootDir: path.join(scope, "ledger-events"),
177
183
  ledgerAuthorityRootDir: path.join(scope, "ledger-authority"),
178
184
  witnessFilePath: path.join(scope, "witness", "checkpoint.json"),
179
185
  });
180
186
  if (initialize) {
181
- ensureDirectoryTreeDurable(
182
- fsImpl,
183
- path.dirname(result.witnessFilePath),
184
- );
187
+ ensureDirectoryTreeDurable(fsImpl, path.dirname(result.witnessFilePath));
185
188
  }
186
189
  return result;
187
190
  }
@@ -224,6 +227,7 @@ export function createAgentEvolutionRuntimeComposition({
224
227
  stateRootDir,
225
228
  authorities: authorityInput,
226
229
  evidenceTtlMs,
230
+ evidenceStorageLayout = "legacy",
227
231
  witnessId: witnessIdInput,
228
232
  clock: clockInput = Date.now,
229
233
  evidenceIdGenerator,
@@ -240,6 +244,7 @@ export function createAgentEvolutionRuntimeComposition({
240
244
  witnessMaximumBytes,
241
245
  ledgerV2: ledgerV2Input = null,
242
246
  } = {}) {
247
+ validateEvidenceStorageLayout(evidenceStorageLayout);
243
248
  const ledgerV2 =
244
249
  ledgerV2Input === null
245
250
  ? null
@@ -445,14 +450,6 @@ export function createAgentEvolutionRuntimeComposition({
445
450
  attestationVerifier: ports.attestationVerifier,
446
451
  now: () => new Date(clock()),
447
452
  });
448
- const evidenceAdapter = new EvolutionEvidenceArtifactAdapter({
449
- tenantId,
450
- audience,
451
- projector,
452
- bundleVerifier,
453
- artifactPorts,
454
- ...(evidenceTtlMs === undefined ? {} : { ttlMs: evidenceTtlMs }),
455
- });
456
453
  const ledgerArtifactResolver =
457
454
  artifactPorts.createEvolutionLedgerArtifactResolver({
458
455
  purpose: "evolution-ledger",
@@ -516,6 +513,46 @@ export function createAgentEvolutionRuntimeComposition({
516
513
  ledgerArtifactResolver,
517
514
  now: clock,
518
515
  });
516
+ const createEvidenceAdapter = (run, runStorage, mainPorts, emptyLayout) => {
517
+ const loaded = run.load();
518
+ const selectedLayout = evidenceStorageLayoutForRun(
519
+ loaded.events,
520
+ emptyLayout,
521
+ );
522
+ return {
523
+ selectedLayout,
524
+ adapter: new EvolutionEvidenceArtifactAdapter({
525
+ tenantId,
526
+ audience,
527
+ projector,
528
+ bundleVerifier,
529
+ ...(selectedLayout === "legacy"
530
+ ? { artifactPorts: mainPorts }
531
+ : {
532
+ typedArtifactPorts: createTypedEvidenceArtifactPorts({
533
+ rootDir: runStorage.evidenceArtifactDir,
534
+ tenantId,
535
+ audience,
536
+ artifactAuthority: {
537
+ envelopeSigner: ports.artifactEnvelopeSigner,
538
+ envelopeVerifier: ports.artifactEnvelopeVerifier,
539
+ currentAuthorityResolver:
540
+ ports.artifactCurrentAuthorityResolver,
541
+ },
542
+ now: clock,
543
+ existingRun: loaded.events.length > 0,
544
+ }),
545
+ }),
546
+ ...(evidenceTtlMs === undefined ? {} : { ttlMs: evidenceTtlMs }),
547
+ }),
548
+ };
549
+ };
550
+ const { adapter: evidenceAdapter, selectedLayout } = createEvidenceAdapter(
551
+ runAdapter,
552
+ storage,
553
+ artifactPorts,
554
+ evidenceStorageLayout,
555
+ );
519
556
  let wikiMaintenance = null;
520
557
  let wikiMaintainer = null;
521
558
  if (wikiConfiguration !== null) {
@@ -707,6 +744,7 @@ export function createAgentEvolutionRuntimeComposition({
707
744
  const evolutionIngress = createAgentEvolutionIngress({
708
745
  evidenceAdapter,
709
746
  runAdapter,
747
+ evidenceStorageLayout: selectedLayout,
710
748
  openCacheSourceRun: (input) => {
711
749
  const sourceRunId = identifier(input, "cache source runId");
712
750
  const sourceStorage = layout(
@@ -758,22 +796,22 @@ export function createAgentEvolutionRuntimeComposition({
758
796
  ...(lockTimeoutMs === undefined ? {} : { lockTimeoutMs }),
759
797
  ...(witnessMaximumBytes === undefined ? {} : { witnessMaximumBytes }),
760
798
  });
799
+ const sourceRunAdapter = new EvolutionRunLedgerAdapter({
800
+ descriptor: { ...runAdapter.descriptor, runId: sourceRunId },
801
+ artifactPorts: sourcePorts,
802
+ ledger: sourceBackend.ledger,
803
+ ledgerArtifactResolver: sourceResolver,
804
+ now: clock,
805
+ });
806
+ const sourceEvidence = createEvidenceAdapter(
807
+ sourceRunAdapter,
808
+ sourceStorage,
809
+ sourcePorts,
810
+ "legacy",
811
+ );
761
812
  return {
762
- runAdapter: new EvolutionRunLedgerAdapter({
763
- descriptor: { ...runAdapter.descriptor, runId: sourceRunId },
764
- artifactPorts: sourcePorts,
765
- ledger: sourceBackend.ledger,
766
- ledgerArtifactResolver: sourceResolver,
767
- now: clock,
768
- }),
769
- evidenceAdapter: new EvolutionEvidenceArtifactAdapter({
770
- tenantId,
771
- audience,
772
- projector,
773
- bundleVerifier,
774
- artifactPorts: sourcePorts,
775
- ...(evidenceTtlMs === undefined ? {} : { ttlMs: evidenceTtlMs }),
776
- }),
813
+ runAdapter: sourceRunAdapter,
814
+ evidenceAdapter: sourceEvidence.adapter,
777
815
  };
778
816
  },
779
817
  sourceEnvelopeAuthority: ports.sourceEnvelope,
@@ -21,6 +21,43 @@ export const AGENT_CODE_TEXT_RESULT_TOOLS = Object.freeze([
21
21
  "search_files",
22
22
  ]);
23
23
 
24
+ export const AGENT_FENCED_CODE_LANGUAGES = Object.freeze([
25
+ "javascript",
26
+ "js",
27
+ "typescript",
28
+ "ts",
29
+ "jsx",
30
+ "tsx",
31
+ "python",
32
+ "py",
33
+ ]);
34
+
35
+ function fencedCodeRanges(text, languages) {
36
+ const ranges = [];
37
+ const fences = /^ {0,3}(`{3,}|~{3,})([^\r\n]*)\r?$/gmu;
38
+ let opening = null;
39
+ for (const match of text.matchAll(fences)) {
40
+ const marker = match[1];
41
+ const info = match[2].trim().toLowerCase();
42
+ if (opening === null) {
43
+ opening = {
44
+ marker,
45
+ supported: languages.includes(info),
46
+ start: match.index + match[0].length,
47
+ };
48
+ } else if (
49
+ marker[0] === opening.marker[0] &&
50
+ marker.length >= opening.marker.length &&
51
+ info === ""
52
+ ) {
53
+ if (opening.supported) ranges.push([opening.start, match.index]);
54
+ opening = null;
55
+ }
56
+ }
57
+ // Unclosed/unknown fences never acquire code semantics.
58
+ return ranges;
59
+ }
60
+
24
61
  /* eslint-disable no-control-regex -- Quoted literals exclude unescaped control bytes. */
25
62
  const JSON_STRING_PREFIX =
26
63
  /^"(?:[^"\\\x00-\x1f]|\\(?:["\\/bfnrt]|u[0-9a-fA-F]{4}))*"/u;
@@ -271,10 +308,35 @@ export function createEvidenceJsonTextBoundary(
271
308
  };
272
309
  };
273
310
 
274
- return (
311
+ return function scanText(
275
312
  text,
276
- { layer = 0, objectOnly = false, codeText = false, visit, plain, equal },
277
- ) => {
313
+ {
314
+ layer = 0,
315
+ objectOnly = false,
316
+ codeText = false,
317
+ fencedCodeLanguages = null,
318
+ visit,
319
+ plain,
320
+ equal,
321
+ },
322
+ ) {
323
+ if (!objectOnly && !codeText && fencedCodeLanguages) {
324
+ const ranges = fencedCodeRanges(text, fencedCodeLanguages);
325
+ if (ranges.length > 0) {
326
+ let output = "";
327
+ let offset = 0;
328
+ const options = { layer, visit, plain, equal };
329
+ for (const [start, end] of ranges) {
330
+ output += scanText(text.slice(offset, start), options);
331
+ output += scanText(text.slice(start, end), {
332
+ ...options,
333
+ codeText: true,
334
+ });
335
+ offset = end;
336
+ }
337
+ return output + scanText(text.slice(offset), options);
338
+ }
339
+ }
278
340
  bytes += Buffer.byteLength(text, "utf8");
279
341
  if (bytes > policy.maxDecodedBytes)
280
342
  reject("Agent model JSON text exceeds its budget");