chainlesschain 0.166.85 → 0.166.87

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 (201) hide show
  1. package/README.md +8 -0
  2. package/package.json +3 -2
  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/assets/{AIOps-Cgo7OFpi.js → AIOps-DdQjhXg9.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-lUMnE2Ln.js → ActionButton-CuwA3hPA.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-CsvKzTot.js → Analytics-DTVXJSAC.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-C2z1h1Pv.js → AppLayout-j06JBfEQ.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-C5Q0ZhNb.js → Artifacts-BFAK8LEW.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-DXnfPKsI.js → Audit-BiGxRpOf.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-DjbGcLm3.js → BackgroundAgents-B6uHaPkZ.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-9bVrKvXE.js → Backup-BNAesB8q.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-bx5ri7BD.js → BaseInput-BOuetfCd.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-CCFmeUMY.js → Chat-cVzo3m_D.js} +4 -4
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-DZ2Ys-CI.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-ei7MQXe9.js → Checkbox-BaCTS-H8.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-CXgBJ9iu.js → Codegen-CBE8NiYh.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-DMkMsizS.js → Col-C9wLiUTN.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-CvpB_UFR.js → Community-jdClBSIp.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-gay5hbFX.js → Compact-BIjauIlM.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-dG8JQyRL.js → Compliance-CZ-AoaNj.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-BA3xfaTW.js → Cowork-BbTKtDS4.js} +4 -4
  23. package/src/assets/web-panel/assets/{Cron-D1_HsxyY.js → Cron-ImKdtwNi.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-DZqoqoy5.js → Crosschain-B54GSHf5.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-Cwnr8hCO.js → DID-BQt5WUzs.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard-CxevypiI.js → Dashboard--gNOffif.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-Bs7-yWgr.js → Dropdown-342A5YJw.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-CcEs2Puo.js → EmailListRenderer-CtIZ3ZHd.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-C9ipBzAQ.js → EvolutionSettings-CyZPoTio.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dt6--mGn.js → FamilyGuardDashboard-B1MCkFEu.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-CD0JN5FF.js → Federation-DZWoERUy.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-POypz3Xv.js → FormItemContext-Onmb0mp3.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-Dv9f-0F5.js → GenericCardRenderer-u1qhNNc7.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BbTh5Atv.js → Git-BEowR1C5.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-C71dgoir.js → Governance-BiYd3AAg.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-DwSHxbJB.js → Inference-CsC4Vjh5.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-Cx1oQYQZ.js → KnowledgeGraph-BXA7ikPM.js} +1 -1
  38. package/src/assets/web-panel/assets/{Logs-BAJWe00o.js → Logs-C9WoplQm.js} +2 -2
  39. package/src/assets/web-panel/assets/{MarkdownRenderer-CD8a7lHT.js → MarkdownRenderer-DecEsXsy.js} +1 -1
  40. package/src/assets/web-panel/assets/{Marketplace-fwuY7P7Y.js → Marketplace-CCoJBfRL.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-Di4693uc.js → McpTools-CzaOWBoA.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-Cz3L-GUB.js → Memory-BPwh7u1-.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-BuXKIkSb.js → MobileBridge-Bk47v6z2.js} +1 -1
  44. package/src/assets/web-panel/assets/MobileProjects-D-CY--Sb.js +1 -0
  45. package/src/assets/web-panel/assets/{Mtc-LnACMFd0.js → Mtc-ExVyAGlW.js} +5 -5
  46. package/src/assets/web-panel/assets/{MtcAudit-BZy7yE0t.js → MtcAudit-Rrw10csE.js} +5 -5
  47. package/src/assets/web-panel/assets/{Multisig-BFG5iVrE.js → Multisig-8TxxwxZZ.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-DgXi04vJ.js → NLProgramming-CNckjtnY.js} +1 -1
  49. package/src/assets/web-panel/assets/Notes-C4j6cZTu.js +7 -0
  50. package/src/assets/web-panel/assets/{NotificationSettings-AixrsHw5.js → NotificationSettings-CchU8rWd.js} +1 -1
  51. package/src/assets/web-panel/assets/OrderTableRenderer-ZJBoyJ16.js +1 -0
  52. package/src/assets/web-panel/assets/{Organization-UNCBC3ux.js → Organization-F0Je7EdZ.js} +2 -2
  53. package/src/assets/web-panel/assets/{Overflow-Drh8oAFT.js → Overflow-B2k-JA3u.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-bc2q0xEB.js → P2P-yui9Xxe6.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-BGwKxcDM.js → PdhVaultBrowser-CegM7hT6.js} +3 -3
  56. package/src/assets/web-panel/assets/{Permissions-DOnUxUzu.js → Permissions-CSFL0uvh.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-B3qPZkrr.js → PersonalDataHub-BrMcd-vr.js} +6 -6
  58. package/src/assets/web-panel/assets/{Pipeline-B6hfa4-i.js → Pipeline-fzrliaVP.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-Bun3c35F.js → Privacy-BrkUjJ_g.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-CCObdzk9.js → ProjectInit-CF_QCsW9.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-C6lKrSXY.js → ProjectSettings-Duwrd8aC.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-DYcta7MZ.js → Projects-B0dLVXzU.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-BtykxKCe.js → Providers-Db8iS1xQ.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-D9CDyroY.js → QrScannerModal-CHbNzEQs.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-CJauCxXx.js → QuickAsk-CIESMfeR.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-BbiYZofR.js → Recommend-BTMbCMtR.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-BymCrgFW.js → RemoteSession-DavyK6J-.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-BWrGpMpF.js → Reputation-BFKtMelA.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-9pOYIhiW.js → Row-BI9AZUvw.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-D3bQJ4qB.js → RssFeed-1nwXt8NY.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-BpKOOFE0.js → Search-Ck8PDYbk.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-DC6C0NSz.js → Security-BgDqpCbq.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-Lkf1046J.js → Services-DF8anXm4.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-eCQ_SsDb.js → Skeleton-CoHyY4ZX.js} +1 -1
  75. package/src/assets/web-panel/assets/Skills-dOaD4Ztl.js +1 -0
  76. package/src/assets/web-panel/assets/{Sla-BQbKy8XJ.js → Sla-XuOawvQY.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-DHsRx-XA.js → SpeechSettings-DFJ7nAiu.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-CC281X_J.js → SyncSettings-B2xYj-Pi.js} +2 -2
  79. package/src/assets/web-panel/assets/Tasks-D_SzNTLi.js +1 -0
  80. package/src/assets/web-panel/assets/{Templates-Cr2vC0tg.js → Templates-BXFmKh7W.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-DeYO5pIG.js → Tenant-CRg2AXbd.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-DBNgbfPr.js → Terminal-DQgxnuep.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-MoxgaF3x.js → TimelineRenderer-BrPQhQVc.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-CT2QfAN7.js → Tokens-RByy4USy.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-DPUnomxs.js → Trigger-pE3y8u73.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-DnufuaTx.js → Trust-DhID9C33.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CJ6iOdPs.js → UkeySign-CPxEPNBH.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-xBWkH8bL.js → VideoEditing-ZD8DUxeQ.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-WYV-4hMR.js → Wallet-Br9JREEd.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-DJ5Mhd9L.js → WebAuthn-Cn-YacJg.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-B__UdOjN.js → WorkflowEditor-BTu0oqMp.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CLlmBVhp.js → chat-CEjws_QF.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-B8zoPQYm.js → colors-Bv2RNebW.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-CvJ-dUsH.js → compact-item-gSc3EofP.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-LAtMm8SC.js → createContext-kyFDaqWC.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-Dcc8pILJ.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-CLYvg42H.js → hasIn-BuMWcjhx.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Cv7vwX3z.js → index--nrQmk8X.js} +1 -1
  99. package/src/assets/web-panel/assets/index-05NB95_V.js +1 -0
  100. package/src/assets/web-panel/assets/{index-BUVrYDNV.js → index-42PTBO7a.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-B6zlMzZz.js → index-BCS5j4SQ.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-oX216HRH.js → index-BSSIJ-rv.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-B02qgCao.js → index-BUOCcXou.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-B_RPWP_5.js → index-Bg5jis0q.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DX99e8Xy.js → index-C-LPpwe9.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DDm9m4vC.js → index-C56Drzol.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DHq2Of6z.js → index-C7Jo20JB.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C_dq-6_3.js → index-C9U9SjcT.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-D0Z13xcZ.js → index-CF3TjDNz.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-B1hHp9_M.js → index-CMS3Mk93.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DfOOACfd.js → index-CNt2X-aK.js} +1 -1
  112. package/src/assets/web-panel/assets/index-Cb6q8wlI.js +1 -0
  113. package/src/assets/web-panel/assets/{index-DYW4Z3y-.js → index-Cj4RA7oA.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-C2KFnUsv.js → index-CkfvP2dN.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BkcQJvsz.js → index-Cm8K8Evn.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-CVDcRQuX.js → index-CvSuM_CB.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BCzyJ1xS.js → index-Czo_hw97.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-Cpda0SAz.js → index-D3m3EXbL.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-iJ6s24bA.js → index-DR561Sqc.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Di9vKira.js → index-DRa4R7vv.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-09YzRb6Z.js → index-DYKSuD02.js} +3 -3
  122. package/src/assets/web-panel/assets/{index-C5v7cEtm.js → index-DYcPWVN9.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BGrQ2uEl.js → index-DbVUA5l3.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-4rr5jFOL.js → index-DbkyTMj-.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-GR3omApz.js → index-Dej4AGOz.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-f1ptYBMr.js → index-EpxWlmip.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-C3uD5H7u.js → index-GpvWtvw3.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-C6PETyel.js → index-NQ0c4hJ1.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CnLXLaEF.js → index-OjZUHz5z.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DpeV-6y4.js → index-U-ytt84A.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DNQUdPam.js → index-_0bfDTDu.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-BM2HqHdT.js → index-jmMAqBAm.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-Bu7-I2L4.js → index-nLemnBZ2.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-CUcE6rIa.js → index-q65c1kp8.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DX0aHEHL.js → index-sJ1F5Txa.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-CxJ4NPVq.js → index-xfS_WO9b.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-QD-koeaw.js → initDefaultProps-B-wqiSu7.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-CTItLW4-.js → motion-BK4_B4MD.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-CGsdTOdN.js → move-BU2TgDDO.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-C1kW_CNU.js → mtc-parser-DA3E4_EX.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-B4PilaYy.js → omit-CaHz1e_q.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-DBGUE12e.js → pickAttrs-NXZ19amf.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-DZxCLjuo.js → placementArrow-BCXI9AHO.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-CZjQiocN.js → responsiveObserve-DdlZ9tLk.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-Btz5hh2_.js → slide-DCZm_Vc4.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-CfuxuLIt.js → statusUtils-CuEULKQr.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-DdO0Obo_.js → styleChecker-Bo_UXG8x.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-CxftJ-Zs.js → useFlexGapSupport-B9PaTcFH.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-pVJChh6K.js → useFs-DwSTGdVR.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-wv7Q0uNE.js → usePersonalDataHub-FswSxnDC.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-DVOVfAqC.js → vnode-EUztvYTj.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-B5tebZuT.js → zoom-D41MAgV-.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/eval.js +118 -18
  156. package/src/commands/memory.js +34 -15
  157. package/src/commands/sandbox.js +9 -0
  158. package/src/data/changelog.json +26 -0
  159. package/src/lib/causal-observability.js +6 -45
  160. package/src/lib/context-memory-kernel/durable-memory-port.js +54 -12
  161. package/src/lib/context-memory-kernel/index.js +1 -0
  162. package/src/lib/context-memory-kernel/memory-query-index.js +278 -0
  163. package/src/lib/context-memory-kernel/memory-service.js +60 -18
  164. package/src/lib/context-memory-kernel/runtime.js +5 -3
  165. package/src/lib/context-memory-kernel/segmented-memory-port.js +955 -0
  166. package/src/lib/eval/outcomes.js +20 -10
  167. package/src/lib/eval/runner.js +49 -5
  168. package/src/lib/eval/tasks.js +8 -3
  169. package/src/lib/eval/verify01-contracts.js +349 -0
  170. package/src/lib/eval/verify01-execution.js +605 -0
  171. package/src/lib/execution-support.js +58 -0
  172. package/src/lib/llm-pricing.js +98 -11
  173. package/src/lib/model-catalog-review.js +116 -0
  174. package/src/lib/model-context-catalog.js +23 -1
  175. package/src/lib/openai-responses.js +39 -0
  176. package/src/lib/packer/pack-update-applier.js +13 -8
  177. package/src/lib/permission-authority.js +146 -10
  178. package/src/lib/process-execution-broker/index.js +8 -0
  179. package/src/lib/process-execution-broker/linux-subreaper-process.js +24 -2
  180. package/src/lib/process-execution-broker/process-ownership-journal.js +168 -7
  181. package/src/lib/process-execution-broker/process-ownership-quarantine.js +56 -1
  182. package/src/lib/process-execution-broker/process-recovery-cgroup.js +272 -0
  183. package/src/lib/sandbox-egress-authority-monitor.js +62 -5
  184. package/src/lib/scoped-permission-store.js +104 -1
  185. package/src/lib/settings-authority-domain.cjs +37 -2
  186. package/src/lib/settings-loader.cjs +67 -34
  187. package/src/lib/settings-permission-authority.cjs +373 -0
  188. package/src/runtime/agent-core.js +88 -407
  189. package/src/runtime/headless-runner.js +8 -3
  190. package/src/runtime/headless-stream.js +10 -3
  191. package/src/runtime/permission-authority-host.js +151 -0
  192. package/src/runtime/provider-stream-state.js +379 -0
  193. package/src/assets/web-panel/assets/ChatBubbleRenderer-ClqsIfTT.js +0 -1
  194. package/src/assets/web-panel/assets/MobileProjects-Bk-lK4Um.js +0 -1
  195. package/src/assets/web-panel/assets/Notes-BAj0Kgg4.js +0 -7
  196. package/src/assets/web-panel/assets/OrderTableRenderer-Dwqk3FlG.js +0 -1
  197. package/src/assets/web-panel/assets/Skills-BvDSQ3-d.js +0 -1
  198. package/src/assets/web-panel/assets/Tasks-CHHSWHom.js +0 -1
  199. package/src/assets/web-panel/assets/devWarning-DgZ4fdGI.js +0 -1
  200. package/src/assets/web-panel/assets/index-jLEdASOV.js +0 -1
  201. package/src/assets/web-panel/assets/index-jesGo4rl.js +0 -1
@@ -0,0 +1,278 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ export const MEMORY_QUERY_INDEX_SCHEMA = "chainlesschain.memory-query-index/v1";
4
+ const CURSOR_SCHEMA = "chainlesschain.memory-list-cursor/v1";
5
+
6
+ export function queryDigest(bytes) {
7
+ return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
8
+ }
9
+
10
+ export function compareMemoryRows(left, right) {
11
+ return (
12
+ right.importance - left.importance ||
13
+ right.updatedAt.localeCompare(left.updatedAt, "en") ||
14
+ left.memoryId.localeCompare(right.memoryId, "en")
15
+ );
16
+ }
17
+
18
+ // No content, evidence, or audit is copied into the derived index. The manifest
19
+ // binds these bytes to the immutable authority shard from which they were made.
20
+ export function encodeQueryIndex(state) {
21
+ const rows = Object.values(state.records)
22
+ .map((record) => ({
23
+ memoryId: record.memoryId,
24
+ category: record.category,
25
+ scope: record.scope,
26
+ scopeId: record.scopeId ?? null,
27
+ state: record.state,
28
+ importance: record.importance,
29
+ updatedAt: record.updatedAt,
30
+ tags: record.tags,
31
+ allowedSinks: record.allowedSinks,
32
+ }))
33
+ .sort(compareMemoryRows);
34
+ return Buffer.from(
35
+ JSON.stringify({
36
+ schema: MEMORY_QUERY_INDEX_SCHEMA,
37
+ shardDigest: state.digest,
38
+ rows,
39
+ }),
40
+ );
41
+ }
42
+
43
+ function scopeKey(scope, scopeId) {
44
+ return JSON.stringify([scope, scopeId ?? null]);
45
+ }
46
+
47
+ export function compileQueryIndex(bytes, descriptor) {
48
+ const value = JSON.parse(bytes.toString("utf8"));
49
+ if (
50
+ value.schema !== MEMORY_QUERY_INDEX_SCHEMA ||
51
+ value.shardDigest !== descriptor.digest ||
52
+ !Array.isArray(value.rows) ||
53
+ value.rows.length !== descriptor.recordCount
54
+ ) {
55
+ throw new Error("query index does not match authority shard");
56
+ }
57
+ const fields = ["category", "scope", "state", "tag", "sink"];
58
+ const postings = Object.fromEntries(
59
+ fields.map((field) => [field, new Map()]),
60
+ );
61
+ const add = (field, key, index) => {
62
+ const map = postings[field];
63
+ if (!map.has(key)) map.set(key, []);
64
+ map.get(key).push(index);
65
+ };
66
+ value.rows.forEach((row, index) => {
67
+ add("category", row.category, index);
68
+ add("scope", scopeKey(row.scope, row.scopeId), index);
69
+ add("state", row.state, index);
70
+ for (const tag of row.tags) add("tag", tag, index);
71
+ for (const sink of row.allowedSinks) add("sink", sink, index);
72
+ });
73
+ return { rows: value.rows, postings };
74
+ }
75
+
76
+ export function normalizeListQuery(options = {}) {
77
+ const result = { includeTombstones: options.includeTombstones === true };
78
+ if (options.category) result.category = String(options.category);
79
+ if (options.sink) result.sink = String(options.sink);
80
+ if (options.scopeAdmissions !== undefined) {
81
+ if (!Array.isArray(options.scopeAdmissions))
82
+ throw new TypeError("scopeAdmissions must be an array");
83
+ result.scopeAdmissions = options.scopeAdmissions.map(
84
+ ({ scope, scopeId }) => ({
85
+ scope,
86
+ scopeId: scopeId ?? null,
87
+ }),
88
+ );
89
+ }
90
+ if (options.tags !== undefined) {
91
+ if (!Array.isArray(options.tags))
92
+ throw new TypeError("tags must be an array");
93
+ result.tags = [...new Set(options.tags.map(String))].sort();
94
+ }
95
+ if (options.states !== undefined) {
96
+ if (!Array.isArray(options.states))
97
+ throw new TypeError("states must be an array");
98
+ result.states = [...new Set(options.states.map(String))].sort();
99
+ }
100
+ return result;
101
+ }
102
+
103
+ export function matchesListQuery(row, query) {
104
+ return (
105
+ (query.includeTombstones || !["deleted", "purged"].includes(row.state)) &&
106
+ (!query.category || row.category === query.category) &&
107
+ (!query.states || query.states.includes(row.state)) &&
108
+ (!query.scopeAdmissions ||
109
+ query.scopeAdmissions.some(
110
+ (scope) =>
111
+ scope.scope === row.scope &&
112
+ (scope.scopeId ?? null) === (row.scopeId ?? null),
113
+ )) &&
114
+ (!query.sink ||
115
+ row.allowedSinks.includes("*") ||
116
+ row.allowedSinks.includes(query.sink)) &&
117
+ (!query.tags?.length || row.tags.some((tag) => query.tags.includes(tag)))
118
+ );
119
+ }
120
+
121
+ // Each posting is already in the public list order. Pick the narrowest posting
122
+ // before applying the remaining predicates; no full-record scan or top-k before
123
+ // permission filtering. Recall uses these gates but retains kernel ranking.
124
+ export function* selectQueryRows(index, query, after = null) {
125
+ const candidates = [];
126
+ const union = (field, keys) => {
127
+ const lists = keys
128
+ .map((key) => index.postings[field].get(key))
129
+ .filter(Boolean);
130
+ return lists.length < 2
131
+ ? lists[0] || []
132
+ : [...new Set(lists.flat())].sort((a, b) => a - b);
133
+ };
134
+ if (query.category)
135
+ candidates.push(index.postings.category.get(query.category) || []);
136
+ if (query.scopeAdmissions)
137
+ candidates.push(
138
+ union(
139
+ "scope",
140
+ query.scopeAdmissions.map((scope) =>
141
+ scopeKey(scope.scope, scope.scopeId),
142
+ ),
143
+ ),
144
+ );
145
+ if (query.states) candidates.push(union("state", query.states));
146
+ if (query.tags?.length) candidates.push(union("tag", query.tags));
147
+ if (query.sink) candidates.push(union("sink", ["*", query.sink]));
148
+ candidates.sort((a, b) => a.length - b.length);
149
+ const positions = candidates[0];
150
+ const length = positions ? positions.length : index.rows.length;
151
+ const rowAt = (offset) => index.rows[positions ? positions[offset] : offset];
152
+ let start = 0;
153
+ if (after) {
154
+ let end = length;
155
+ while (start < end) {
156
+ const middle = Math.floor((start + end) / 2);
157
+ if (compareMemoryRows(rowAt(middle), after) <= 0) start = middle + 1;
158
+ else end = middle;
159
+ }
160
+ }
161
+ for (let offset = start; offset < length; offset++) {
162
+ const row = rowAt(offset);
163
+ if (matchesListQuery(row, query)) yield row;
164
+ }
165
+ }
166
+
167
+ export function* mergeQueryRows(heads) {
168
+ const heap = [];
169
+ const less = (left, right) => compareMemoryRows(left.row, right.row) < 0;
170
+ const push = (head) => {
171
+ let at = heap.length;
172
+ heap.push(head);
173
+ while (at > 0) {
174
+ const parent = Math.floor((at - 1) / 2);
175
+ if (!less(head, heap[parent])) break;
176
+ heap[at] = heap[parent];
177
+ at = parent;
178
+ }
179
+ heap[at] = head;
180
+ };
181
+ for (const head of heads) push(head);
182
+ while (heap.length) {
183
+ const first = heap[0];
184
+ const last = heap.pop();
185
+ if (heap.length) {
186
+ let at = 0;
187
+ while (at * 2 + 1 < heap.length) {
188
+ let child = at * 2 + 1;
189
+ if (child + 1 < heap.length && less(heap[child + 1], heap[child]))
190
+ child++;
191
+ if (!less(heap[child], last)) break;
192
+ heap[at] = heap[child];
193
+ at = child;
194
+ }
195
+ heap[at] = last;
196
+ }
197
+ yield { bucket: first.bucket, row: first.row };
198
+ const next = first.iterator.next();
199
+ if (!next.done) push({ ...first, row: next.value });
200
+ }
201
+ }
202
+
203
+ export function cursorError(reason) {
204
+ return Object.assign(new Error(`Memory list cursor is invalid: ${reason}`), {
205
+ code: "CONTEXT_MEMORY_CURSOR_INVALID",
206
+ });
207
+ }
208
+
209
+ export function listCursorBinding(filePath, generation, query) {
210
+ return queryDigest(
211
+ JSON.stringify({
212
+ filePath,
213
+ generation,
214
+ query,
215
+ order: "importance-desc,updatedAt-desc,memoryId-en-asc/v1",
216
+ }),
217
+ );
218
+ }
219
+
220
+ export function decodeListCursor(cursor, binding) {
221
+ if (cursor == null) return null;
222
+ if (
223
+ typeof cursor !== "string" ||
224
+ cursor.length > 4096 ||
225
+ !/^[\w-]+$/u.test(cursor)
226
+ )
227
+ throw cursorError("encoding");
228
+ let decoded;
229
+ try {
230
+ decoded = JSON.parse(Buffer.from(cursor, "base64url").toString("utf8"));
231
+ } catch {
232
+ throw cursorError("encoding");
233
+ }
234
+ if (
235
+ !decoded ||
236
+ decoded.schema !== CURSOR_SCHEMA ||
237
+ decoded.binding !== binding ||
238
+ !decoded.after ||
239
+ typeof decoded.after.memoryId !== "string" ||
240
+ typeof decoded.after.updatedAt !== "string" ||
241
+ !Number.isFinite(decoded.after.importance) ||
242
+ decoded.digest !==
243
+ queryDigest(
244
+ JSON.stringify({
245
+ schema: decoded.schema,
246
+ binding: decoded.binding,
247
+ after: decoded.after,
248
+ }),
249
+ )
250
+ ) {
251
+ throw cursorError("generation, filters, or checksum changed");
252
+ }
253
+ return decoded.after;
254
+ }
255
+
256
+ export function encodeListCursor(binding, row) {
257
+ const value = {
258
+ schema: CURSOR_SCHEMA,
259
+ binding,
260
+ after: {
261
+ memoryId: row.memoryId,
262
+ updatedAt: row.updatedAt,
263
+ importance: row.importance,
264
+ },
265
+ };
266
+ return Buffer.from(
267
+ JSON.stringify({ ...value, digest: queryDigest(JSON.stringify(value)) }),
268
+ ).toString("base64url");
269
+ }
270
+
271
+ export function pageLimit(value, fallback = 20) {
272
+ const number = value == null ? fallback : Number(value);
273
+ if (!Number.isSafeInteger(number) || number < 1 || number > 10000)
274
+ throw new RangeError(
275
+ "memory page limit must be an integer from 1 to 10000",
276
+ );
277
+ return number;
278
+ }
@@ -50,7 +50,8 @@ function normalizedScope(scope, scopeId) {
50
50
  return { scope: value };
51
51
  }
52
52
  const normalizedId = safeIdentifier(scopeId, "");
53
- if (!normalizedId) throw new TypeError(`scopeId is required for ${value} scope`);
53
+ if (!normalizedId)
54
+ throw new TypeError(`scopeId is required for ${value} scope`);
54
55
  return { scope: value, scopeId: normalizedId };
55
56
  }
56
57
 
@@ -87,7 +88,10 @@ function legacyProposal(entry, now) {
87
88
  {
88
89
  store: "cli-sqlite-memory-entries",
89
90
  id: safeIdentifier(entry?.id, memoryId),
90
- digest: canonicalDigest(entry, "chainlesschain.cli-legacy-memory-row/v1"),
91
+ digest: canonicalDigest(
92
+ entry,
93
+ "chainlesschain.cli-legacy-memory-row/v1",
94
+ ),
91
95
  },
92
96
  ],
93
97
  confidence: 0.7,
@@ -206,7 +210,11 @@ export class CliCanonicalMemoryService {
206
210
  scopeId: "local-user",
207
211
  category: safeIdentifier(options.category, "general"),
208
212
  content,
209
- provenance: { source: "cli-shadow", actor: "local-user", observedAt: now },
213
+ provenance: {
214
+ source: "cli-shadow",
215
+ actor: "local-user",
216
+ observedAt: now,
217
+ },
210
218
  evidenceRefs: [{ store: "cli-command", id: "shadow-memory-add" }],
211
219
  confidence: 0.7,
212
220
  importance: normalizedImportance(options.importance),
@@ -316,7 +324,9 @@ export class CliCanonicalMemoryService {
316
324
  const proposal = legacyProposal(entry, now);
317
325
  const existing = await this.runtime.memoryPort.read(proposal.memoryId);
318
326
  if (existing) {
319
- const projected = createMemoryCandidate(proposal, { clock: this.now });
327
+ const projected = createMemoryCandidate(proposal, {
328
+ clock: this.now,
329
+ });
320
330
  if (existing.digest !== projected.digest) {
321
331
  const error = new Error(
322
332
  `legacy memory ${entry?.id || "unknown"} conflicts with canonical authority`,
@@ -358,7 +368,9 @@ export class CliCanonicalMemoryService {
358
368
  const proposal = legacyScopedProposal(entry, now);
359
369
  const existing = await this.runtime.memoryPort.read(proposal.memoryId);
360
370
  if (existing) {
361
- const projected = createMemoryCandidate(proposal, { clock: this.now });
371
+ const projected = createMemoryCandidate(proposal, {
372
+ clock: this.now,
373
+ });
362
374
  if (existing.digest !== projected.digest) {
363
375
  const error = new Error(
364
376
  `legacy scoped memory ${entry?.id || "unknown"} conflicts with canonical authority`,
@@ -391,14 +403,29 @@ export class CliCanonicalMemoryService {
391
403
  return result;
392
404
  }
393
405
 
394
- async list({ limit = 20, category } = {}) {
395
- const records = await this.runtime.memoryPort.listRecords();
406
+ async list({ limit = 20, category, scopeAdmissions, sink, tags } = {}) {
407
+ const records = await this.runtime.memoryPort.listRecords({
408
+ limit: Math.max(1, Number(limit) || 20),
409
+ category,
410
+ scopeAdmissions,
411
+ sink,
412
+ tags,
413
+ });
396
414
  return records
397
415
  .filter((record) => !category || record.category === category)
398
416
  .slice(0, Math.max(1, Number(limit) || 20))
399
417
  .map((record) => publicEntry(record));
400
418
  }
401
419
 
420
+ async listPage(options = {}) {
421
+ const page = await this.runtime.memoryPort.listPage(options);
422
+ return {
423
+ entries: page.records.map((record) => publicEntry(record)),
424
+ nextCursor: page.nextCursor,
425
+ storeRevision: page.storeRevision,
426
+ };
427
+ }
428
+
402
429
  async add(content, options = {}) {
403
430
  const now = new Date(Number(this.now())).toISOString();
404
431
  const evidenceId = `add-${canonicalDigest(
@@ -533,8 +560,7 @@ export class CliCanonicalMemoryService {
533
560
  .filter(
534
561
  ({ record }) =>
535
562
  (!options.category || record.category === options.category) &&
536
- (tags.length === 0 ||
537
- record.tags.some((tag) => tags.includes(tag))),
563
+ (tags.length === 0 || record.tags.some((tag) => tags.includes(tag))),
538
564
  )
539
565
  .slice(0, limit)
540
566
  .map(({ record, relevance }) => publicScopedEntry(record, relevance));
@@ -558,11 +584,19 @@ export class CliCanonicalMemoryService {
558
584
  }
559
585
 
560
586
  async delete(idOrPrefix) {
561
- const records = await this.runtime.memoryPort.listRecords();
562
- const exact = records.find((record) => record.memoryId === idOrPrefix);
563
- const candidates = exact
564
- ? [exact]
565
- : records.filter((record) => record.memoryId.startsWith(idOrPrefix));
587
+ const exact = await this.runtime.memoryPort.read(idOrPrefix);
588
+ let candidates;
589
+ if (exact && !["deleted", "purged"].includes(exact.state)) {
590
+ candidates = [exact];
591
+ } else {
592
+ const records = await this.runtime.memoryPort.listRecords();
593
+ const listedExact = records.find(
594
+ (record) => record.memoryId === idOrPrefix,
595
+ );
596
+ candidates = listedExact
597
+ ? [listedExact]
598
+ : records.filter((record) => record.memoryId.startsWith(idOrPrefix));
599
+ }
566
600
  if (candidates.length === 0) return null;
567
601
  if (candidates.length > 1) {
568
602
  const error = new Error(`memory prefix is ambiguous: ${idOrPrefix}`);
@@ -601,7 +635,9 @@ export class CliCanonicalMemoryService {
601
635
  const existing = await this.runtime.memoryPort.read(record.memoryId);
602
636
  if (existing) {
603
637
  if (existing.digest !== record.digest) {
604
- const error = new Error(`canonical memory conflict: ${record.memoryId}`);
638
+ const error = new Error(
639
+ `canonical memory conflict: ${record.memoryId}`,
640
+ );
605
641
  error.code = "CONTEXT_MEMORY_IMPORT_CONFLICT";
606
642
  throw error;
607
643
  }
@@ -620,18 +656,24 @@ export class CliCanonicalMemoryService {
620
656
  recordDigest: record.digest,
621
657
  at: new Date(Number(this.now())).toISOString(),
622
658
  };
623
- event.digest = canonicalDigest(event, "chainlesschain.memory-event/v1");
659
+ event.digest = canonicalDigest(
660
+ event,
661
+ "chainlesschain.memory-event/v1",
662
+ );
624
663
  const committed = await this.runtime.memoryPort.commit(
625
664
  { record, event },
626
665
  0,
627
666
  );
628
- if (!committed.ok) throw new Error(`memory import raced: ${record.memoryId}`);
667
+ if (!committed.ok)
668
+ throw new Error(`memory import raced: ${record.memoryId}`);
629
669
  } else {
630
670
  const proposal = legacyProposal(
631
671
  entry,
632
672
  new Date(Number(this.now())).toISOString(),
633
673
  );
634
- const existing = await this.runtime.memoryPort.read(proposal.memoryId);
674
+ const existing = await this.runtime.memoryPort.read(
675
+ proposal.memoryId,
676
+ );
635
677
  if (existing) {
636
678
  result.existing += 1;
637
679
  continue;
@@ -1,5 +1,5 @@
1
1
  import { ContextMemoryKernel } from "@chainlesschain/context-memory-kernel";
2
- import { DurableJsonMemoryPort } from "./durable-memory-port.js";
2
+ import { SegmentedMemoryPort } from "./segmented-memory-port.js";
3
3
  import { JsonlSessionContextPort } from "./jsonl-session-context-port.js";
4
4
  import { CliLegacyMemoryPrivacyPurgePort } from "./privacy-purge-port.js";
5
5
  import {
@@ -8,7 +8,8 @@ import {
8
8
  } from "./authority.js";
9
9
 
10
10
  export function createCliContextMemoryRuntime(options = {}) {
11
- const scopeKey = options.scopeKey ||
11
+ const scopeKey =
12
+ options.scopeKey ||
12
13
  (options.sessionId ? `cli:session:${options.sessionId}` : "cli:memory");
13
14
  const decision = resolveCliContextMemoryCutover({
14
15
  env: options.env,
@@ -20,7 +21,8 @@ export function createCliContextMemoryRuntime(options = {}) {
20
21
  });
21
22
  const memoryPort =
22
23
  options.memoryPort ||
23
- new DurableJsonMemoryPort({
24
+ new SegmentedMemoryPort({
25
+ readOnly: !decision.canonical,
24
26
  ...(options.memoryFilePath ? { filePath: options.memoryFilePath } : {}),
25
27
  });
26
28
  const sessionPort =