chainlesschain 0.166.115 → 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 (207) hide show
  1. package/README.md +43 -5
  2. package/package.json +4 -4
  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-BsoSoDNb.js → AIOps-BGySwMIP.js} +1 -1
  7. package/src/assets/web-panel/assets/{ActionButton-Dcx7Gm5t.js → ActionButton-Chn7fBLr.js} +1 -1
  8. package/src/assets/web-panel/assets/{Analytics-S1hsBIz3.js → Analytics-ORH7UkGa.js} +3 -3
  9. package/src/assets/web-panel/assets/{AppLayout-B2j067qM.js → AppLayout-8xV4jWjP.js} +5 -5
  10. package/src/assets/web-panel/assets/{Artifacts-D5iGV9ic.js → Artifacts-26SBK-x-.js} +1 -1
  11. package/src/assets/web-panel/assets/{Audit-C8ChVvXu.js → Audit-CtXpqbXg.js} +1 -1
  12. package/src/assets/web-panel/assets/{BackgroundAgents-Cg97AAJS.js → BackgroundAgents-C5zLvQis.js} +1 -1
  13. package/src/assets/web-panel/assets/{Backup-CyxU9IUg.js → Backup-C93xY4vO.js} +1 -1
  14. package/src/assets/web-panel/assets/{BaseInput-CKlWjA8I.js → BaseInput-DpVCHfAn.js} +1 -1
  15. package/src/assets/web-panel/assets/{Chat-C-EqZza6.js → Chat-DM0LblR2.js} +5 -5
  16. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BRFiXKPX.js → ChatBubbleRenderer-unlQUF1T.js} +1 -1
  17. package/src/assets/web-panel/assets/{Checkbox-kkI13tSJ.js → Checkbox-BsAt3cKR.js} +1 -1
  18. package/src/assets/web-panel/assets/{Codegen-NlqEDwHK.js → Codegen-E_kp4KFd.js} +1 -1
  19. package/src/assets/web-panel/assets/{Col-CfepEu79.js → Col-6msR3T6I.js} +1 -1
  20. package/src/assets/web-panel/assets/{Community-BRo0qLXM.js → Community-PyX9c5D-.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compact-BMu8TP0E.js → Compact-7G1bVDSH.js} +1 -1
  22. package/src/assets/web-panel/assets/{Compliance-B7Q3Moef.js → Compliance-DcHN7GlD.js} +1 -1
  23. package/src/assets/web-panel/assets/{Cowork-BVwt7Xmc.js → Cowork-WUIHJYDx.js} +3 -3
  24. package/src/assets/web-panel/assets/{Cron-CgBv20Qy.js → Cron-CWgCbptg.js} +2 -2
  25. package/src/assets/web-panel/assets/{Crosschain-CwcSBJk2.js → Crosschain-BzKZ6roD.js} +1 -1
  26. package/src/assets/web-panel/assets/{DID-d20rCiIm.js → DID-r7zxeItn.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dashboard-PpZaUYpS.js → Dashboard-D3pBiN2H.js} +2 -2
  28. package/src/assets/web-panel/assets/{Dropdown-DjsLdX_Z.js → Dropdown-C4otRJlZ.js} +1 -1
  29. package/src/assets/web-panel/assets/{EmailListRenderer-CaPkrtxn.js → EmailListRenderer-CzDTC8lm.js} +1 -1
  30. package/src/assets/web-panel/assets/{EvolutionSettings-DDY8cQnE.js → EvolutionSettings-DGkXiIs-.js} +1 -1
  31. package/src/assets/web-panel/assets/{FamilyGuardDashboard-VQavMjyj.js → FamilyGuardDashboard-BKdEyuiR.js} +1 -1
  32. package/src/assets/web-panel/assets/{Federation-D0GvKQgI.js → Federation-dsI-xcpf.js} +1 -1
  33. package/src/assets/web-panel/assets/{FormItemContext-Dl_TWHmb.js → FormItemContext-CEEb1fMR.js} +1 -1
  34. package/src/assets/web-panel/assets/{GenericCardRenderer-Bny2uagG.js → GenericCardRenderer-D_mfO3Ts.js} +1 -1
  35. package/src/assets/web-panel/assets/{Git-B01KXq47.js → Git-CBwr2ZI3.js} +2 -2
  36. package/src/assets/web-panel/assets/{Governance-F4c4Vwo1.js → Governance-D-Wy2Jjr.js} +1 -1
  37. package/src/assets/web-panel/assets/{Inference-_025Q-8K.js → Inference-B4Yk_IRx.js} +1 -1
  38. package/src/assets/web-panel/assets/{KnowledgeGraph-DwbTmQb1.js → KnowledgeGraph-DoI7bi6m.js} +1 -1
  39. package/src/assets/web-panel/assets/{Logs-CnNo0hCm.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-Dkz5bv7F.js → Marketplace-CsIEByzK.js} +1 -1
  42. package/src/assets/web-panel/assets/{McpTools-CBtRwDW_.js → McpTools-_DRzjcIn.js} +3 -3
  43. package/src/assets/web-panel/assets/{Memory-Y9jnyTb7.js → Memory-zvLpyi__.js} +2 -2
  44. package/src/assets/web-panel/assets/{MobileBridge-Br1urkOz.js → MobileBridge-DXd1ik2Z.js} +1 -1
  45. package/src/assets/web-panel/assets/{MobileProjects-DnsyuerX.js → MobileProjects-DKh2q-Y9.js} +1 -1
  46. package/src/assets/web-panel/assets/{Mtc-he3ZzieF.js → Mtc-Ct-fhtIx.js} +4 -4
  47. package/src/assets/web-panel/assets/{MtcAudit-BadphAuN.js → MtcAudit-J4zY3Oqk.js} +2 -2
  48. package/src/assets/web-panel/assets/{Multisig-3_pVLymK.js → Multisig-B2HJMCKe.js} +3 -3
  49. package/src/assets/web-panel/assets/{NLProgramming-DmtmHfsI.js → NLProgramming-CwcSmU4q.js} +1 -1
  50. package/src/assets/web-panel/assets/{Notes-CE4L2O55.js → Notes-Da53L6wb.js} +4 -4
  51. package/src/assets/web-panel/assets/{NotificationSettings-B7QmfJn9.js → NotificationSettings-BxhufdrA.js} +1 -1
  52. package/src/assets/web-panel/assets/{OrderTableRenderer-O0wRSyJ0.js → OrderTableRenderer-BoFwohAi.js} +1 -1
  53. package/src/assets/web-panel/assets/{Organization-BrlMSsyT.js → Organization-MIsMrUes.js} +4 -4
  54. package/src/assets/web-panel/assets/{Overflow-CY4ULPrZ.js → Overflow-Dy2P4v3q.js} +1 -1
  55. package/src/assets/web-panel/assets/{P2P-kIANZYKd.js → P2P-CD9Sxn2y.js} +2 -2
  56. package/src/assets/web-panel/assets/{PdhVaultBrowser-DEgB4rvF.js → PdhVaultBrowser-BvBWgfG0.js} +5 -5
  57. package/src/assets/web-panel/assets/{Permissions-CWxywRp5.js → Permissions-CwOlDRis.js} +4 -4
  58. package/src/assets/web-panel/assets/{PersonalDataHub-DAg7iCbr.js → PersonalDataHub-CZYaxEpv.js} +4 -4
  59. package/src/assets/web-panel/assets/{Pipeline-Brc6ONnR.js → Pipeline-kLU7PUbB.js} +1 -1
  60. package/src/assets/web-panel/assets/{Privacy-CcinYTL8.js → Privacy-BVRycSiI.js} +1 -1
  61. package/src/assets/web-panel/assets/{ProjectInit-Bz8XEsom.js → ProjectInit-DP3pr7uJ.js} +2 -2
  62. package/src/assets/web-panel/assets/{ProjectSettings-CsOMlSTZ.js → ProjectSettings-CACaDYjs.js} +2 -2
  63. package/src/assets/web-panel/assets/Projects-CB1k4zTC.js +1 -0
  64. package/src/assets/web-panel/assets/{Providers-CeunOQiH.js → Providers-D7Y9WHRE.js} +1 -1
  65. package/src/assets/web-panel/assets/{QrScannerModal-CN2a2_Fb.js → QrScannerModal-CeP8xzs1.js} +1 -1
  66. package/src/assets/web-panel/assets/{QuickAsk-CVeLif3e.js → QuickAsk-iJVFrhZ2.js} +1 -1
  67. package/src/assets/web-panel/assets/{Recommend-1k9WOEGM.js → Recommend-DmTpnagw.js} +1 -1
  68. package/src/assets/web-panel/assets/{RemoteSession-Q8UCqIMw.js → RemoteSession-C6ek8Uni.js} +2 -2
  69. package/src/assets/web-panel/assets/{Reputation-CkrCgXKM.js → Reputation-CPfwc9de.js} +1 -1
  70. package/src/assets/web-panel/assets/{Row-JFdvuTzi.js → Row-C1wwtSMJ.js} +1 -1
  71. package/src/assets/web-panel/assets/{RssFeed-C74JHCmk.js → RssFeed-BiDJsqaH.js} +3 -3
  72. package/src/assets/web-panel/assets/{Search-DrJiVO1T.js → Search-BF6Aon95.js} +1 -1
  73. package/src/assets/web-panel/assets/{Security-BJzNlSJq.js → Security-Bps0XnV4.js} +3 -3
  74. package/src/assets/web-panel/assets/{Services-D4TLMnJm.js → Services-uf92smGR.js} +2 -2
  75. package/src/assets/web-panel/assets/{Skeleton-cswTDqhh.js → Skeleton-DQd4eVWW.js} +1 -1
  76. package/src/assets/web-panel/assets/{Skills-Bv0rM1BS.js → Skills-DgamiYa5.js} +1 -1
  77. package/src/assets/web-panel/assets/{Sla-D9rE7hNh.js → Sla-CF1IVIrm.js} +1 -1
  78. package/src/assets/web-panel/assets/SpeechSettings-Bzxmjbpc.js +1 -0
  79. package/src/assets/web-panel/assets/{SyncSettings-BwnMG8kq.js → SyncSettings-B8zKauiq.js} +2 -2
  80. package/src/assets/web-panel/assets/{Tasks-wJvU24cB.js → Tasks-DPKV_xSt.js} +1 -1
  81. package/src/assets/web-panel/assets/{Templates-CZbRU3tN.js → Templates-BikeSZIF.js} +1 -1
  82. package/src/assets/web-panel/assets/{Tenant-_jbpFJPZ.js → Tenant-CEaUaDkJ.js} +1 -1
  83. package/src/assets/web-panel/assets/{Terminal-BzNm5WKZ.js → Terminal-ZPgOSQ_q.js} +3 -3
  84. package/src/assets/web-panel/assets/{TimelineRenderer-bmybWjuS.js → TimelineRenderer-DmyB4Udk.js} +1 -1
  85. package/src/assets/web-panel/assets/{Tokens-o1WDcqVQ.js → Tokens-g85Pm5TO.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trigger-BB1D6sIB.js → Trigger-D202hx9a.js} +1 -1
  87. package/src/assets/web-panel/assets/{Trust-CLxdCfy2.js → Trust-DzvQYVFy.js} +1 -1
  88. package/src/assets/web-panel/assets/{UkeySign-B9LS6vS0.js → UkeySign-KRzwddVg.js} +1 -1
  89. package/src/assets/web-panel/assets/{VideoEditing-Bg0-wxjz.js → VideoEditing-IRBXLO2z.js} +1 -1
  90. package/src/assets/web-panel/assets/{Wallet-Bw0G2F6P.js → Wallet-DSf5KPgQ.js} +4 -4
  91. package/src/assets/web-panel/assets/{WebAuthn-irEiNY9b.js → WebAuthn-DNPxLTCc.js} +5 -5
  92. package/src/assets/web-panel/assets/{WorkflowEditor-Bh08FbJs.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-De-FPjVT.js → chat-q3XXUtv2.js} +1 -1
  95. package/src/assets/web-panel/assets/{colors-ygdyvinU.js → colors-CF54SNei.js} +1 -1
  96. package/src/assets/web-panel/assets/{compact-item-BQ9jH9KV.js → compact-item-BaRkvZuT.js} +1 -1
  97. package/src/assets/web-panel/assets/{createContext-BFuVSyox.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-i19GtR1P.js → hasIn-DlC--S8R.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DS1IwwGL.js → index-B0Ptc7yu.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-B1IsP_JO.js → index-B0V9rgdu.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-CWfgeaG4.js → index-BEiUlFKb.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DTY20pWu.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-IXkif6J_.js → index-BU5DJqk7.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-BVhtukYX.js → index-BY-Tf3OM.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-BKlU5VZy.js → index-BZrE0Go8.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Bw5pTpnI.js → index-BizdX2X5.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BGMxK155.js → index-C87Yr3h1.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DVnFgasM.js → index-C9Wypz9e.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-C61w3omz.js → index-CAoG_E-q.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-l5-J0jHx.js → index-CAxSyMrF.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-28DjsABm.js → index-CC5HjNM6.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BPUCvc8i.js → index-CNZQEZ9g.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CpdXhhMY.js → index-CPvIhha6.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DAboGZTw.js → index-CR_wqMGy.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DL7ewjD2.js → index-CSClXoB3.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Bhf-MuUh.js → index-CZ8azVgB.js} +3 -3
  120. package/src/assets/web-panel/assets/{index-BaaydJcC.js → index-Ccc5z8eJ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-B2LieObB.js → index-CeiKbM3a.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-We2nK3ju.js → index-Cl6av3X7.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-m8waSAyv.js → index-CtGfeD7E.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-cDJsyAkI.js → index-Ctid12Gq.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DlwxUZQL.js → index-D0H-N0uG.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BBYiCI1d.js → index-D0vIgprF.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-_9tUBcLm.js → index-D4wUDFRg.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-4HoFz1MA.js → index-DJFipyK7.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-Cq9k4-Ws.js → index-DX2REKNp.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DuuOX5u3.js → index-Dc3gD0cw.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DgjLaB7k.js → index-DiQzer2R.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CMNjaSir.js → index-DntKLOs9.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-vXtH3o6O.js → index-Dplhl6gh.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BLMtCKAY.js → index-Dq8q_PWB.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-CXrk8OYO.js → index-IVQdOBNN.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CBVcGaxk.js → index-Kerduyao.js} +1 -1
  137. package/src/assets/web-panel/assets/{index-BKblSCL9.js → index-W6cLGjpW.js} +1 -1
  138. package/src/assets/web-panel/assets/{index-CgoSgmjK.js → index-qZDNFll9.js} +1 -1
  139. package/src/assets/web-panel/assets/{initDefaultProps-B_EZHeqN.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-BrVb_Gy1.js → motion-BlCLpVDp.js} +1 -1
  143. package/src/assets/web-panel/assets/{move-CKxVRL_J.js → move-B80G7fLU.js} +1 -1
  144. package/src/assets/web-panel/assets/{mtc-parser-C80rvQ1J.js → mtc-parser-Djw08NJh.js} +1 -1
  145. package/src/assets/web-panel/assets/{omit-De5vD7BR.js → omit-Bg_G1eUr.js} +1 -1
  146. package/src/assets/web-panel/assets/{pickAttrs-BTyEDjth.js → pickAttrs-Df9zYUg2.js} +1 -1
  147. package/src/assets/web-panel/assets/{placementArrow-BWR94AjR.js → placementArrow-DjCDLhJ4.js} +1 -1
  148. package/src/assets/web-panel/assets/{responsiveObserve-1g-Vnibk.js → responsiveObserve--Naz7NgY.js} +1 -1
  149. package/src/assets/web-panel/assets/{slide-Dmg6dYuF.js → slide-CHn3ald-.js} +1 -1
  150. package/src/assets/web-panel/assets/{statusUtils-Ddj6rSab.js → statusUtils-BiGwoIK_.js} +1 -1
  151. package/src/assets/web-panel/assets/{styleChecker-DyP1mPDf.js → styleChecker-Zf2dQx1j.js} +1 -1
  152. package/src/assets/web-panel/assets/{useFlexGapSupport-D3d_0YuY.js → useFlexGapSupport-sLES8nyD.js} +1 -1
  153. package/src/assets/web-panel/assets/{useFs-M3vq-gE2.js → useFs-DV1Hl4qu.js} +1 -1
  154. package/src/assets/web-panel/assets/{usePersonalDataHub-GtP2TgtK.js → usePersonalDataHub-CZXr2Qxg.js} +1 -1
  155. package/src/assets/web-panel/assets/{vnode-BurE2ATQ.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-Ch-ViiDe.js → zoom-B8A6xKMF.js} +1 -1
  158. package/src/assets/web-panel/index.html +1 -1
  159. package/src/commands/compact.js +7 -2
  160. package/src/data/changelog.json +27 -1
  161. package/src/harness/jsonl-session-store.js +80 -74
  162. package/src/harness/prompt-compressor.js +57 -3
  163. package/src/lib/artifact-store.js +129 -20
  164. package/src/lib/bounded-artifact-file-read.js +128 -46
  165. package/src/lib/context-memory-kernel/context-image-transport.js +248 -0
  166. package/src/lib/context-memory-kernel/jsonl-session-context-port.js +4 -1
  167. package/src/lib/context-memory-kernel/live-compaction.js +40 -10
  168. package/src/lib/context-memory-kernel/message-adapter.js +80 -10
  169. package/src/lib/context-memory-kernel/message-bundle-store.js +1140 -0
  170. package/src/lib/context-memory-kernel/provider-context.js +23 -8
  171. package/src/lib/evolution/agent-evolution-ingress.js +103 -19
  172. package/src/lib/evolution/agent-evolution-runtime-composition.js +65 -27
  173. package/src/lib/evolution/agent-model-projection.js +90 -18
  174. package/src/lib/evolution/evidence-json-text.js +341 -42
  175. package/src/lib/evolution/evolution-artifact-ports.js +1005 -83
  176. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +59 -15
  177. package/src/lib/evolution/evolution-evidence-projector.js +153 -16
  178. package/src/lib/evolution/evolution-evidence-storage-layout.js +115 -0
  179. package/src/lib/evolution/evolution-file-witness.js +7 -3
  180. package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +6 -2
  181. package/src/lib/evolution/evolution-ledger-file-manifest-head-store.js +6 -2
  182. package/src/lib/evolution/evolution-ledger.js +226 -55
  183. package/src/lib/evolution/evolution-private-storage.js +20 -0
  184. package/src/lib/evolution/evolution-run-ledger-adapter.js +298 -11
  185. package/src/lib/evolution/evolution-windows-directory-durability.js +215 -32
  186. package/src/lib/evolution/local-ui-evolution-runtime.js +3 -38
  187. package/src/lib/evolution/local-ui-signing-authority.js +69 -0
  188. package/src/lib/image-token-estimate.js +59 -0
  189. package/src/lib/ollama-provider-fetch.js +33 -0
  190. package/src/lib/provider-stream.js +14 -13
  191. package/src/lib/read-file-loop-guard.js +7 -4
  192. package/src/lib/session-history-origins.js +94 -35
  193. package/src/lib/session-message-provenance.js +26 -2
  194. package/src/lib/session-runtime-retention.js +10 -1
  195. package/src/lib/session-transcript-history.js +5 -1
  196. package/src/lib/session-transcript-migration.js +67 -12
  197. package/src/lib/storage-failure-cause-codes.js +449 -0
  198. package/src/lib/tool-result-preview.js +276 -0
  199. package/src/runtime/agent-core.js +111 -92
  200. package/src/runtime/headless-stream.js +121 -27
  201. package/src/assets/web-panel/assets/MarkdownRenderer-D8_iZief.js +0 -1
  202. package/src/assets/web-panel/assets/Projects-BeSOM6wi.js +0 -1
  203. package/src/assets/web-panel/assets/SpeechSettings-Bfhvin8B.js +0 -1
  204. package/src/assets/web-panel/assets/devWarning-c2I2Rn4_.js +0 -1
  205. package/src/assets/web-panel/assets/index-CTs4dYcV.js +0 -1
  206. package/src/assets/web-panel/assets/index-DeuvaW15.js +0 -1
  207. package/src/assets/web-panel/assets/markdown-CsiA8-E5.js +0 -50
@@ -1,10 +1,14 @@
1
- import { canonicalDigest } from "@chainlesschain/context-memory-kernel";
1
+ import {
2
+ canonicalDigest,
3
+ canonicalJson,
4
+ } from "@chainlesschain/context-memory-kernel";
2
5
  import {
3
6
  contextItemsToMessages,
4
7
  messagesToContextItems,
5
8
  } from "./context-memory-kernel/message-adapter.js";
6
9
  import {
7
10
  decodeVerifiedPersistedMessage,
11
+ decodeVerifiedRawPersistedMessage,
8
12
  encodePersistedMessage,
9
13
  getDurableSystemMessageProvenance,
10
14
  DURABLE_SYSTEM_MESSAGE_KINDS,
@@ -31,8 +35,28 @@ const historyBearing = (entry) =>
31
35
  derivedSystemKinds.has(
32
36
  getDurableSystemMessageProvenance(entry.message)?.kind,
33
37
  );
38
+ // Compare conversation identity without dropping system messages, their private
39
+ // provenance, or unknown metadata. Raw receipt fields remain available below
40
+ // for authenticating historical ContextItem source digests.
41
+ const conversationMessages = (messages) =>
42
+ messages.map((message) =>
43
+ decodeVerifiedPersistedMessage(encodePersistedMessage(message)),
44
+ );
34
45
  const fingerprint = (messages) =>
35
- canonicalDigest(messages.map(encodePersistedMessage));
46
+ canonicalDigest(conversationMessages(messages).map(encodePersistedMessage));
47
+ const sameContextItemContent = (left, right) => {
48
+ if (typeof left?.content === "string" || typeof right?.content === "string") {
49
+ return (
50
+ typeof left?.content === "string" &&
51
+ typeof right?.content === "string" &&
52
+ left.content === right.content
53
+ );
54
+ }
55
+ if (left?.contentRef === undefined || right?.contentRef === undefined) {
56
+ return false;
57
+ }
58
+ return canonicalJson(left.contentRef) === canonicalJson(right.contentRef);
59
+ };
36
60
 
37
61
  /**
38
62
  * Origins belong to positions in the current display history, never to equal
@@ -75,12 +99,12 @@ export function createSessionHistoryOrigins() {
75
99
  appendPersisted(message, ordinal) {
76
100
  if (!context) return;
77
101
  append(
78
- decodeVerifiedPersistedMessage(message),
102
+ decodeVerifiedRawPersistedMessage(message),
79
103
  displayable(message) ? { first: ordinal, last: ordinal } : null,
80
104
  );
81
105
  },
82
106
  appendMappedPersisted(message, origin) {
83
- append(decodeVerifiedPersistedMessage(message), origin);
107
+ append(decodeVerifiedRawPersistedMessage(message), origin);
84
108
  },
85
109
  branchPrefix(messages, head, count) {
86
110
  if (!context) return null;
@@ -114,7 +138,7 @@ export function createSessionHistoryOrigins() {
114
138
  let ordinal = 0;
115
139
  replace(
116
140
  messages.map((message) => ({
117
- message: decodeVerifiedPersistedMessage(message),
141
+ message: decodeVerifiedRawPersistedMessage(message),
118
142
  origin: displayable(message)
119
143
  ? { first: ordinal, last: ordinal++ }
120
144
  : null,
@@ -126,21 +150,41 @@ export function createSessionHistoryOrigins() {
126
150
  let entries = null;
127
151
  try {
128
152
  if (context) {
129
- const originals = messagesToContextItems(
130
- context.map((entry) => entry.message),
131
- { sessionId: canonical.sessionId },
132
- );
133
- const byDigest = new Map(
134
- originals.map((item) => [item.digest, item]),
135
- );
136
- const bySequence = new Map(
137
- originals.map((item) => [item.sourceRef.eventSequence, item]),
138
- );
153
+ const rawMessages = context.map((entry) => entry.message);
154
+ // Old compactions hashed raw receipt-bearing bundles; new ones hash
155
+ // conversation projections. Derive exactly these two representations
156
+ // from the same bounded verified context, never from output claims.
157
+ const representations = [rawMessages];
158
+ if (
159
+ rawMessages.some(
160
+ (message) =>
161
+ message.role === "user" &&
162
+ (Object.hasOwn(message, "clientMessageId") ||
163
+ Object.hasOwn(message, "inputDigest")),
164
+ )
165
+ ) {
166
+ representations.push(conversationMessages(rawMessages));
167
+ }
168
+ const sources = representations.map((messages) => {
169
+ const items = messagesToContextItems(messages, {
170
+ sessionId: canonical.sessionId,
171
+ allowExternalization: true,
172
+ });
173
+ return {
174
+ items,
175
+ byDigest: new Map(items.map((item) => [item.digest, item])),
176
+ bySequence: new Map(
177
+ items.map((item) => [item.sourceRef.eventSequence, item]),
178
+ ),
179
+ };
180
+ });
139
181
  const itemEntries = (item) =>
140
182
  context.slice(
141
183
  item.sourceRef.eventSequence,
142
184
  item.sourceRef.eventSequence +
143
- contextItemsToMessages([item]).length,
185
+ contextItemsToMessages([item], {
186
+ sessionId: canonical.sessionId,
187
+ }).length,
144
188
  );
145
189
  entries = [...canonical.outputItems]
146
190
  .sort(
@@ -150,13 +194,19 @@ export function createSessionHistoryOrigins() {
150
194
  left.itemId.localeCompare(right.itemId, "en"),
151
195
  )
152
196
  .flatMap((item) => {
153
- const messages = contextItemsToMessages([item]);
154
- const source = bySequence.get(item.sourceRef.eventSequence);
155
- if (
156
- item.sourceRef.store === "cli-jsonl-session" &&
157
- source?.sourceRef.digest === item.sourceRef.digest &&
158
- source.content === item.content
159
- ) {
197
+ const messages = contextItemsToMessages([item], {
198
+ sessionId: canonical.sessionId,
199
+ });
200
+ const source = sources
201
+ .map(({ bySequence }) =>
202
+ bySequence.get(item.sourceRef.eventSequence),
203
+ )
204
+ .find(
205
+ (candidate) =>
206
+ candidate?.sourceRef.digest === item.sourceRef.digest &&
207
+ sameContextItemContent(candidate, item),
208
+ );
209
+ if (item.sourceRef.store === "cli-jsonl-session" && source) {
160
210
  return itemEntries(source);
161
211
  }
162
212
  let origin = null;
@@ -165,18 +215,26 @@ export function createSessionHistoryOrigins() {
165
215
  item.provenance?.parentDigests?.length > 0
166
216
  ) {
167
217
  const digests = item.provenance.parentDigests;
168
- if (
169
- digests.length <= originals.length &&
170
- new Set(digests).size === digests.length
171
- ) {
172
- const parents = digests.map((digest) => byDigest.get(digest));
173
- if (parents.every(Boolean))
174
- origin = span(parents.flatMap(itemEntries));
218
+ if (new Set(digests).size === digests.length) {
219
+ // A summary must name one complete representation. Mixing
220
+ // raw and projected aliases cannot manufacture extra parents.
221
+ for (const { items, byDigest } of sources) {
222
+ if (digests.length > items.length) continue;
223
+ const parents = digests.map((digest) =>
224
+ byDigest.get(digest),
225
+ );
226
+ if (parents.every(Boolean)) {
227
+ origin = span(parents.flatMap(itemEntries));
228
+ break;
229
+ }
230
+ }
175
231
  }
176
232
  }
177
233
  return messages.map((message) => ({ message, origin }));
178
234
  });
179
- const persisted = data.messages.map(decodeVerifiedPersistedMessage);
235
+ const persisted = data.messages.map(
236
+ decodeVerifiedRawPersistedMessage,
237
+ );
180
238
  if (
181
239
  fingerprint(entries.map((entry) => entry.message)) !==
182
240
  fingerprint(persisted)
@@ -189,7 +247,7 @@ export function createSessionHistoryOrigins() {
189
247
  replace(
190
248
  entries ||
191
249
  data.messages.map((message) => ({
192
- message: decodeVerifiedPersistedMessage(message),
250
+ message: decodeVerifiedRawPersistedMessage(message),
193
251
  origin: null,
194
252
  })),
195
253
  );
@@ -213,13 +271,14 @@ export function createSessionHistoryOrigins() {
213
271
  start: certificate.start,
214
272
  end: certificate.end,
215
273
  });
274
+ const persisted = data.messages.map(decodeVerifiedRawPersistedMessage);
216
275
  if (
217
276
  fingerprint(projected.map((entry) => entry.message)) !==
218
- fingerprint(data.messages.map(decodeVerifiedPersistedMessage))
277
+ fingerprint(persisted)
219
278
  )
220
279
  return false;
221
- const entries = projected.map(({ message, sourceIndexes }) => ({
222
- message,
280
+ const entries = projected.map(({ sourceIndexes }, index) => ({
281
+ message: persisted[index],
223
282
  origin: span(sourceIndexes.map((index) => context[index])),
224
283
  }));
225
284
  replace(entries);
@@ -214,6 +214,18 @@ function cloneWithoutWireTag(snapshot) {
214
214
  return clean;
215
215
  }
216
216
 
217
+ // Input acceptance belongs to the authenticated event, not the provider's
218
+ // conversation message. Keep encodePersistedMessage unchanged so receipt
219
+ // lookup/deduplication still verifies the original event and digest. Apply this
220
+ // only after the full JSON-safe clone, including for historical checkpoints.
221
+ function conversationMessage(clean) {
222
+ if (clean?.role === "user") {
223
+ delete clean.clientMessageId;
224
+ delete clean.inputDigest;
225
+ }
226
+ return clean;
227
+ }
228
+
217
229
  function canonicalTag(kind) {
218
230
  if (!DURABLE_KINDS.has(kind)) {
219
231
  throw new TypeError(`Unsupported durable system message kind: ${kind}`);
@@ -314,7 +326,7 @@ export function encodePersistedMessage(message) {
314
326
  * Decode provenance only after the caller has verified the JSONL hash chain
315
327
  * and its independent head/count anchor while holding the session lock.
316
328
  */
317
- export function decodeVerifiedPersistedMessage(message) {
329
+ export function decodeVerifiedRawPersistedMessage(message) {
318
330
  if (!message || typeof message !== "object") return message;
319
331
  if (!isObjectMessage(message)) return null;
320
332
  const snapshot = plainDataSnapshot(message);
@@ -332,6 +344,12 @@ export function decodeVerifiedPersistedMessage(message) {
332
344
  return clean;
333
345
  }
334
346
 
347
+ /** Verified message replay has a conversation projection distinct from the
348
+ * exact historical payload used to authenticate migration and lineage. */
349
+ export function decodeVerifiedPersistedMessage(message) {
350
+ return conversationMessage(decodeVerifiedRawPersistedMessage(message));
351
+ }
352
+
335
353
  /** Strip an untrusted wire field without granting runtime replay authority. */
336
354
  export function sanitizePersistedMessage(message) {
337
355
  if (!message || typeof message !== "object") return message;
@@ -340,6 +358,12 @@ export function sanitizePersistedMessage(message) {
340
358
  return snapshot ? cloneWithoutWireTag(snapshot) : null;
341
359
  }
342
360
 
361
+ /** Conversation replay excludes receipt metadata; generic data sanitation and
362
+ * historical migration digests retain their original representation. */
363
+ export function sanitizeConversationMessage(message) {
364
+ return conversationMessage(sanitizePersistedMessage(message));
365
+ }
366
+
343
367
  /** Deep-sanitize an untrusted persisted message array without granting replay. */
344
368
  export function sanitizePersistedMessages(messages, options = {}) {
345
369
  const strict = options?.strict === true;
@@ -442,7 +466,7 @@ export function projectCanonicalResumeMessages(messages, options = {}) {
442
466
  }
443
467
  if (isRuntimeOnlySessionMessage(raw)) continue;
444
468
  if (role !== "system") {
445
- projected.push(clean);
469
+ projected.push(conversationMessage(clean));
446
470
  } else if (runtimeTag) {
447
471
  projected.push(attachRuntimeTag(clean, canonicalTag(runtimeTag.kind)));
448
472
  }
@@ -1,6 +1,10 @@
1
1
  /** Bounded live-state retention for long-running agent conversations. */
2
2
 
3
3
  import { createHash } from "node:crypto";
4
+ import {
5
+ isRuntimeOnlySessionMessage,
6
+ markRuntimeOnlySessionMessage,
7
+ } from "./session-message-provenance.js";
4
8
 
5
9
  export const SESSION_RUNTIME_RETENTION_LIMITS = Object.freeze({
6
10
  recentResults: 32,
@@ -136,7 +140,12 @@ export function releaseOldLiveSessionResults(messages, configured = {}) {
136
140
  originalChars: content.length,
137
141
  retainedChars: projection.content.length,
138
142
  });
139
- return { ...message, content: projection.content };
143
+ const retained = { ...message, content: projection.content };
144
+ // This is a trusted host clone. Preserve only authority already attached
145
+ // to its source; matching background-result text grants no authority.
146
+ return isRuntimeOnlySessionMessage(message)
147
+ ? markRuntimeOnlySessionMessage(retained)
148
+ : retained;
140
149
  });
141
150
  return {
142
151
  messages: output,
@@ -77,7 +77,11 @@ function isContextCompaction(data) {
77
77
  }));
78
78
  return (
79
79
  canonicalDigest(
80
- content(contextItemsToMessages(canonical.outputItems)),
80
+ content(
81
+ contextItemsToMessages(canonical.outputItems, {
82
+ sessionId: canonical.sessionId,
83
+ }),
84
+ ),
81
85
  ) === canonicalDigest(content(data.messages))
82
86
  );
83
87
  } catch {
@@ -2,6 +2,7 @@ import { createHash } from "node:crypto";
2
2
 
3
3
  import {
4
4
  appendEvent,
5
+ appendAuthorityEventWithVerifiedProjection,
5
6
  findLatestEvent,
6
7
  listSessionAuthoritySummaries,
7
8
  readVerifiedMessages,
@@ -12,7 +13,10 @@ import {
12
13
  getSession as getDatabaseSession,
13
14
  listSessions as listDatabaseSessions,
14
15
  } from "./session-manager.js";
15
- import { sanitizePersistedMessages } from "./session-message-provenance.js";
16
+ import {
17
+ sanitizeConversationMessage,
18
+ sanitizePersistedMessages,
19
+ } from "./session-message-provenance.js";
16
20
 
17
21
  export const SESSION_STORE_MIGRATION_EVENT = "session_store_migrated";
18
22
  export const SESSION_STORE_MIGRATION_SCHEMA =
@@ -71,6 +75,7 @@ export function ensureCanonicalSessionTranscript(
71
75
  ) {
72
76
  const deps = {
73
77
  appendEvent,
78
+ appendAuthorityEventWithVerifiedProjection,
74
79
  findLatestEvent,
75
80
  readVerifiedMessages,
76
81
  sessionHasPersistedEvidence,
@@ -113,14 +118,67 @@ export function ensureCanonicalSessionTranscript(
113
118
  });
114
119
  }
115
120
 
121
+ const migration = {
122
+ schema: SESSION_STORE_MIGRATION_SCHEMA,
123
+ source,
124
+ messagesDigest: digest,
125
+ messageCount: importedMessages.length,
126
+ };
127
+ const conflict = () =>
128
+ migrationError(
129
+ "CC_SESSION_MIGRATION_CONFLICT",
130
+ `canonical transcript already contains different messages: ${id}`,
131
+ { sessionId: id },
132
+ );
116
133
  const currentMessages = deps.readVerifiedMessages(id);
134
+ let recoveredImport = false;
117
135
  if (currentMessages.length > 0) {
118
- if (messagesDigest(currentMessages) !== digest) {
119
- throw migrationError(
120
- "CC_SESSION_MIGRATION_CONFLICT",
121
- `canonical transcript already contains different messages: ${id}`,
122
- { sessionId: id },
136
+ const snapshot = deps.findLatestEvent(id, "compact");
137
+ if (snapshot?.data?.reason === "physical-store-import") {
138
+ // Conversation replay omits input receipt metadata. Recover an interrupted
139
+ // import only from the exact raw snapshot, never normalized equality alone.
140
+ // Recheck both evidence and live replay under the marker's writer lock.
141
+ deps.appendAuthorityEventWithVerifiedProjection(
142
+ id,
143
+ SESSION_STORE_MIGRATION_EVENT,
144
+ migration,
145
+ {
146
+ createProjection: () => {
147
+ let latest = null;
148
+ let completed = false;
149
+ return {
150
+ accept(event) {
151
+ if (event.type === "compact") latest = event.data;
152
+ if (event.type === SESSION_STORE_MIGRATION_EVENT)
153
+ completed = true;
154
+ },
155
+ finish: () => ({ latest, completed }),
156
+ };
157
+ },
158
+ validateProjection({ latest, completed }, authority) {
159
+ if (
160
+ completed ||
161
+ latest?.reason !== "physical-store-import" ||
162
+ !Array.isArray(latest.messages) ||
163
+ messagesDigest(latest.messages) !== digest ||
164
+ // Old snapshots did not record a source label. Their exact raw
165
+ // source bytes remain the only available import identity proof.
166
+ (Object.hasOwn(latest, "migration") &&
167
+ (latest.migration?.schema !== migration.schema ||
168
+ latest.migration.source !== source ||
169
+ latest.migration.messagesDigest !== digest)) ||
170
+ messagesDigest(authority.readMessages()) !==
171
+ messagesDigest(
172
+ importedMessages.map(sanitizeConversationMessage),
173
+ )
174
+ )
175
+ throw conflict();
176
+ },
177
+ },
123
178
  );
179
+ recoveredImport = true;
180
+ } else if (messagesDigest(currentMessages) !== digest) {
181
+ throw conflict();
124
182
  }
125
183
  } else if (importedMessages.length > 0) {
126
184
  deps.appendEvent(id, "compact", {
@@ -128,15 +186,12 @@ export function ensureCanonicalSessionTranscript(
128
186
  originalMessages: importedMessages.length,
129
187
  compressedMessages: importedMessages.length,
130
188
  reason: "physical-store-import",
189
+ migration,
131
190
  });
132
191
  }
133
192
 
134
- deps.appendEvent(id, SESSION_STORE_MIGRATION_EVENT, {
135
- schema: SESSION_STORE_MIGRATION_SCHEMA,
136
- source,
137
- messagesDigest: digest,
138
- messageCount: importedMessages.length,
139
- });
193
+ if (!recoveredImport)
194
+ deps.appendEvent(id, SESSION_STORE_MIGRATION_EVENT, migration);
140
195
  return Object.freeze({
141
196
  sessionId: id,
142
197
  migrated: true,