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.
- package/README.md +8 -0
- package/package.json +3 -2
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-Cgo7OFpi.js → AIOps-DdQjhXg9.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-lUMnE2Ln.js → ActionButton-CuwA3hPA.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CsvKzTot.js → Analytics-DTVXJSAC.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-C2z1h1Pv.js → AppLayout-j06JBfEQ.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-C5Q0ZhNb.js → Artifacts-BFAK8LEW.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DXnfPKsI.js → Audit-BiGxRpOf.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-DjbGcLm3.js → BackgroundAgents-B6uHaPkZ.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-9bVrKvXE.js → Backup-BNAesB8q.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-bx5ri7BD.js → BaseInput-BOuetfCd.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CCFmeUMY.js → Chat-cVzo3m_D.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DZ2Ys-CI.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-ei7MQXe9.js → Checkbox-BaCTS-H8.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-CXgBJ9iu.js → Codegen-CBE8NiYh.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DMkMsizS.js → Col-C9wLiUTN.js} +1 -1
- package/src/assets/web-panel/assets/{Community-CvpB_UFR.js → Community-jdClBSIp.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-gay5hbFX.js → Compact-BIjauIlM.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-dG8JQyRL.js → Compliance-CZ-AoaNj.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BA3xfaTW.js → Cowork-BbTKtDS4.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-D1_HsxyY.js → Cron-ImKdtwNi.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DZqoqoy5.js → Crosschain-B54GSHf5.js} +1 -1
- package/src/assets/web-panel/assets/{DID-Cwnr8hCO.js → DID-BQt5WUzs.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CxevypiI.js → Dashboard--gNOffif.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Bs7-yWgr.js → Dropdown-342A5YJw.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CcEs2Puo.js → EmailListRenderer-CtIZ3ZHd.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-C9ipBzAQ.js → EvolutionSettings-CyZPoTio.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Dt6--mGn.js → FamilyGuardDashboard-B1MCkFEu.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CD0JN5FF.js → Federation-DZWoERUy.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-POypz3Xv.js → FormItemContext-Onmb0mp3.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-Dv9f-0F5.js → GenericCardRenderer-u1qhNNc7.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BbTh5Atv.js → Git-BEowR1C5.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-C71dgoir.js → Governance-BiYd3AAg.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DwSHxbJB.js → Inference-CsC4Vjh5.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Cx1oQYQZ.js → KnowledgeGraph-BXA7ikPM.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BAJWe00o.js → Logs-C9WoplQm.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-CD8a7lHT.js → MarkdownRenderer-DecEsXsy.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-fwuY7P7Y.js → Marketplace-CCoJBfRL.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-Di4693uc.js → McpTools-CzaOWBoA.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-Cz3L-GUB.js → Memory-BPwh7u1-.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BuXKIkSb.js → MobileBridge-Bk47v6z2.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-D-CY--Sb.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-LnACMFd0.js → Mtc-ExVyAGlW.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BZy7yE0t.js → MtcAudit-Rrw10csE.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-BFG5iVrE.js → Multisig-8TxxwxZZ.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DgXi04vJ.js → NLProgramming-CNckjtnY.js} +1 -1
- package/src/assets/web-panel/assets/Notes-C4j6cZTu.js +7 -0
- package/src/assets/web-panel/assets/{NotificationSettings-AixrsHw5.js → NotificationSettings-CchU8rWd.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-ZJBoyJ16.js +1 -0
- package/src/assets/web-panel/assets/{Organization-UNCBC3ux.js → Organization-F0Je7EdZ.js} +2 -2
- package/src/assets/web-panel/assets/{Overflow-Drh8oAFT.js → Overflow-B2k-JA3u.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-bc2q0xEB.js → P2P-yui9Xxe6.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-BGwKxcDM.js → PdhVaultBrowser-CegM7hT6.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-DOnUxUzu.js → Permissions-CSFL0uvh.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-B3qPZkrr.js → PersonalDataHub-BrMcd-vr.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-B6hfa4-i.js → Pipeline-fzrliaVP.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Bun3c35F.js → Privacy-BrkUjJ_g.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CCObdzk9.js → ProjectInit-CF_QCsW9.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-C6lKrSXY.js → ProjectSettings-Duwrd8aC.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DYcta7MZ.js → Projects-B0dLVXzU.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BtykxKCe.js → Providers-Db8iS1xQ.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-D9CDyroY.js → QrScannerModal-CHbNzEQs.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CJauCxXx.js → QuickAsk-CIESMfeR.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BbiYZofR.js → Recommend-BTMbCMtR.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BymCrgFW.js → RemoteSession-DavyK6J-.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-BWrGpMpF.js → Reputation-BFKtMelA.js} +1 -1
- package/src/assets/web-panel/assets/{Row-9pOYIhiW.js → Row-BI9AZUvw.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-D3bQJ4qB.js → RssFeed-1nwXt8NY.js} +2 -2
- package/src/assets/web-panel/assets/{Search-BpKOOFE0.js → Search-Ck8PDYbk.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DC6C0NSz.js → Security-BgDqpCbq.js} +4 -4
- package/src/assets/web-panel/assets/{Services-Lkf1046J.js → Services-DF8anXm4.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-eCQ_SsDb.js → Skeleton-CoHyY4ZX.js} +1 -1
- package/src/assets/web-panel/assets/Skills-dOaD4Ztl.js +1 -0
- package/src/assets/web-panel/assets/{Sla-BQbKy8XJ.js → Sla-XuOawvQY.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DHsRx-XA.js → SpeechSettings-DFJ7nAiu.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-CC281X_J.js → SyncSettings-B2xYj-Pi.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-D_SzNTLi.js +1 -0
- package/src/assets/web-panel/assets/{Templates-Cr2vC0tg.js → Templates-BXFmKh7W.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-DeYO5pIG.js → Tenant-CRg2AXbd.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DBNgbfPr.js → Terminal-DQgxnuep.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-MoxgaF3x.js → TimelineRenderer-BrPQhQVc.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CT2QfAN7.js → Tokens-RByy4USy.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DPUnomxs.js → Trigger-pE3y8u73.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DnufuaTx.js → Trust-DhID9C33.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CJ6iOdPs.js → UkeySign-CPxEPNBH.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-xBWkH8bL.js → VideoEditing-ZD8DUxeQ.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-WYV-4hMR.js → Wallet-Br9JREEd.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DJ5Mhd9L.js → WebAuthn-Cn-YacJg.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-B__UdOjN.js → WorkflowEditor-BTu0oqMp.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CLlmBVhp.js → chat-CEjws_QF.js} +1 -1
- package/src/assets/web-panel/assets/{colors-B8zoPQYm.js → colors-Bv2RNebW.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CvJ-dUsH.js → compact-item-gSc3EofP.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-LAtMm8SC.js → createContext-kyFDaqWC.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Dcc8pILJ.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CLYvg42H.js → hasIn-BuMWcjhx.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cv7vwX3z.js → index--nrQmk8X.js} +1 -1
- package/src/assets/web-panel/assets/index-05NB95_V.js +1 -0
- package/src/assets/web-panel/assets/{index-BUVrYDNV.js → index-42PTBO7a.js} +1 -1
- package/src/assets/web-panel/assets/{index-B6zlMzZz.js → index-BCS5j4SQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-oX216HRH.js → index-BSSIJ-rv.js} +1 -1
- package/src/assets/web-panel/assets/{index-B02qgCao.js → index-BUOCcXou.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_RPWP_5.js → index-Bg5jis0q.js} +1 -1
- package/src/assets/web-panel/assets/{index-DX99e8Xy.js → index-C-LPpwe9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDm9m4vC.js → index-C56Drzol.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHq2Of6z.js → index-C7Jo20JB.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_dq-6_3.js → index-C9U9SjcT.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0Z13xcZ.js → index-CF3TjDNz.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1hHp9_M.js → index-CMS3Mk93.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfOOACfd.js → index-CNt2X-aK.js} +1 -1
- package/src/assets/web-panel/assets/index-Cb6q8wlI.js +1 -0
- package/src/assets/web-panel/assets/{index-DYW4Z3y-.js → index-Cj4RA7oA.js} +1 -1
- package/src/assets/web-panel/assets/{index-C2KFnUsv.js → index-CkfvP2dN.js} +1 -1
- package/src/assets/web-panel/assets/{index-BkcQJvsz.js → index-Cm8K8Evn.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVDcRQuX.js → index-CvSuM_CB.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCzyJ1xS.js → index-Czo_hw97.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cpda0SAz.js → index-D3m3EXbL.js} +1 -1
- package/src/assets/web-panel/assets/{index-iJ6s24bA.js → index-DR561Sqc.js} +1 -1
- package/src/assets/web-panel/assets/{index-Di9vKira.js → index-DRa4R7vv.js} +1 -1
- package/src/assets/web-panel/assets/{index-09YzRb6Z.js → index-DYKSuD02.js} +3 -3
- package/src/assets/web-panel/assets/{index-C5v7cEtm.js → index-DYcPWVN9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGrQ2uEl.js → index-DbVUA5l3.js} +1 -1
- package/src/assets/web-panel/assets/{index-4rr5jFOL.js → index-DbkyTMj-.js} +1 -1
- package/src/assets/web-panel/assets/{index-GR3omApz.js → index-Dej4AGOz.js} +1 -1
- package/src/assets/web-panel/assets/{index-f1ptYBMr.js → index-EpxWlmip.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3uD5H7u.js → index-GpvWtvw3.js} +1 -1
- package/src/assets/web-panel/assets/{index-C6PETyel.js → index-NQ0c4hJ1.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnLXLaEF.js → index-OjZUHz5z.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpeV-6y4.js → index-U-ytt84A.js} +1 -1
- package/src/assets/web-panel/assets/{index-DNQUdPam.js → index-_0bfDTDu.js} +1 -1
- package/src/assets/web-panel/assets/{index-BM2HqHdT.js → index-jmMAqBAm.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bu7-I2L4.js → index-nLemnBZ2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUcE6rIa.js → index-q65c1kp8.js} +1 -1
- package/src/assets/web-panel/assets/{index-DX0aHEHL.js → index-sJ1F5Txa.js} +1 -1
- package/src/assets/web-panel/assets/{index-CxJ4NPVq.js → index-xfS_WO9b.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-QD-koeaw.js → initDefaultProps-B-wqiSu7.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CTItLW4-.js → motion-BK4_B4MD.js} +1 -1
- package/src/assets/web-panel/assets/{move-CGsdTOdN.js → move-BU2TgDDO.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C1kW_CNU.js → mtc-parser-DA3E4_EX.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B4PilaYy.js → omit-CaHz1e_q.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DBGUE12e.js → pickAttrs-NXZ19amf.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DZxCLjuo.js → placementArrow-BCXI9AHO.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CZjQiocN.js → responsiveObserve-DdlZ9tLk.js} +1 -1
- package/src/assets/web-panel/assets/{slide-Btz5hh2_.js → slide-DCZm_Vc4.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CfuxuLIt.js → statusUtils-CuEULKQr.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DdO0Obo_.js → styleChecker-Bo_UXG8x.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-CxftJ-Zs.js → useFlexGapSupport-B9PaTcFH.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-pVJChh6K.js → useFs-DwSTGdVR.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-wv7Q0uNE.js → usePersonalDataHub-FswSxnDC.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DVOVfAqC.js → vnode-EUztvYTj.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-B5tebZuT.js → zoom-D41MAgV-.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/eval.js +118 -18
- package/src/commands/memory.js +34 -15
- package/src/commands/sandbox.js +9 -0
- package/src/data/changelog.json +26 -0
- package/src/lib/causal-observability.js +6 -45
- package/src/lib/context-memory-kernel/durable-memory-port.js +54 -12
- package/src/lib/context-memory-kernel/index.js +1 -0
- package/src/lib/context-memory-kernel/memory-query-index.js +278 -0
- package/src/lib/context-memory-kernel/memory-service.js +60 -18
- package/src/lib/context-memory-kernel/runtime.js +5 -3
- package/src/lib/context-memory-kernel/segmented-memory-port.js +955 -0
- package/src/lib/eval/outcomes.js +20 -10
- package/src/lib/eval/runner.js +49 -5
- package/src/lib/eval/tasks.js +8 -3
- package/src/lib/eval/verify01-contracts.js +349 -0
- package/src/lib/eval/verify01-execution.js +605 -0
- package/src/lib/execution-support.js +58 -0
- package/src/lib/llm-pricing.js +98 -11
- package/src/lib/model-catalog-review.js +116 -0
- package/src/lib/model-context-catalog.js +23 -1
- package/src/lib/openai-responses.js +39 -0
- package/src/lib/packer/pack-update-applier.js +13 -8
- package/src/lib/permission-authority.js +146 -10
- package/src/lib/process-execution-broker/index.js +8 -0
- package/src/lib/process-execution-broker/linux-subreaper-process.js +24 -2
- package/src/lib/process-execution-broker/process-ownership-journal.js +168 -7
- package/src/lib/process-execution-broker/process-ownership-quarantine.js +56 -1
- package/src/lib/process-execution-broker/process-recovery-cgroup.js +272 -0
- package/src/lib/sandbox-egress-authority-monitor.js +62 -5
- package/src/lib/scoped-permission-store.js +104 -1
- package/src/lib/settings-authority-domain.cjs +37 -2
- package/src/lib/settings-loader.cjs +67 -34
- package/src/lib/settings-permission-authority.cjs +373 -0
- package/src/runtime/agent-core.js +88 -407
- package/src/runtime/headless-runner.js +8 -3
- package/src/runtime/headless-stream.js +10 -3
- package/src/runtime/permission-authority-host.js +151 -0
- package/src/runtime/provider-stream-state.js +379 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-ClqsIfTT.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-Bk-lK4Um.js +0 -1
- package/src/assets/web-panel/assets/Notes-BAj0Kgg4.js +0 -7
- package/src/assets/web-panel/assets/OrderTableRenderer-Dwqk3FlG.js +0 -1
- package/src/assets/web-panel/assets/Skills-BvDSQ3-d.js +0 -1
- package/src/assets/web-panel/assets/Tasks-CHHSWHom.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DgZ4fdGI.js +0 -1
- package/src/assets/web-panel/assets/index-jLEdASOV.js +0 -1
- 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)
|
|
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(
|
|
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: {
|
|
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, {
|
|
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, {
|
|
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
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
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(
|
|
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(
|
|
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)
|
|
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(
|
|
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 {
|
|
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 =
|
|
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
|
|
24
|
+
new SegmentedMemoryPort({
|
|
25
|
+
readOnly: !decision.canonical,
|
|
24
26
|
...(options.memoryFilePath ? { filePath: options.memoryFilePath } : {}),
|
|
25
27
|
});
|
|
26
28
|
const sessionPort =
|