chainlesschain 0.166.45 → 0.166.47
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 +6 -4
- package/package.json +3 -1
- package/src/assets/web-panel/assets/{AIOps-CrMhYNeH.js → AIOps-CDpT0WXV.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DLY5blZ3.js → ActionButton-BNfUljWx.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C0NhKQB0.js → Analytics-C9323DEx.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DLyepgMq.js → AppLayout-CRrjb2db.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-Depk01Sa.js → Artifacts-Db-DGqJS.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-jKe6NQ3J.js → Audit-CJdHRJ0W.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-CG4GKT9s.js → BackgroundAgents-_RSCnTYs.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-DYWCkzwM.js → Backup-8GFQi-dM.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-xm5vodmJ.js → BaseInput-C87NtgUZ.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-B20_PNd3.js → Chat-DcTMWS8G.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-D4d-eh0F.js → ChatBubbleRenderer-5ZDPTW_H.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CfgwkV_r.js → Checkbox-DM9EmYee.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DbnoWI44.js → Codegen-M2YqDRNN.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CfzzhgGw.js → Col-oB1LLxyf.js} +1 -1
- package/src/assets/web-panel/assets/{Community-BU7mGM8p.js → Community-TcVZK5tF.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DpYim0an.js → Compact-XKmq-3K_.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BNJcO6ra.js → Compliance-C6CBiDRy.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CecZ-pWj.js → Cowork-Dz9CGqXH.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-BG_C1fe3.js → Cron-CxJDgDVL.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BAeILQLL.js → Crosschain-DMP0JsaQ.js} +1 -1
- package/src/assets/web-panel/assets/{DID-CYqOEkXi.js → DID-I5IQeogb.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-BYU8wmL1.js → Dashboard-BfLW2MXj.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DYlJeTTa.js → Dropdown-BK8EjAlh.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-C0M6py3K.js → EmailListRenderer-C3iqSv5I.js} +1 -1
- package/src/assets/web-panel/assets/EvolutionSettings-BJmBzpW6.js +1 -0
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Du90iDch.js → FamilyGuardDashboard-T19rnqm-.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-DkFp_hzB.js → Federation-CozrbPMy.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BGgtGTfG.js → FormItemContext-k1dCLNNJ.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BIDsSCei.js → GenericCardRenderer-DbaW_Jvt.js} +1 -1
- package/src/assets/web-panel/assets/{Git--d3Te93J.js → Git-CQHRyEIt.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CZwD0vmO.js → Governance-BMJYZgMy.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DiDcSFEW.js → Inference-B7mpNU7V.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Bi0hSfzg.js → KnowledgeGraph-Br0Blg6B.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-C8NHSc0K.js → Logs-HIdk0S6M.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-DfDuADqF.js → MarkdownRenderer-HxeocBHy.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-D6kD0bNf.js → Marketplace-Bkfq69UP.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-mTSamCr5.js → McpTools-dtmx0bHO.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-YQBXfLjU.js → Memory-CrRlOuEf.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-D2awuupp.js → MobileBridge-D4ZIZiAH.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Bl7lZc_-.js → MobileProjects-C90Rw7GE.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CBqjLK2Q.js → Mtc-CC6k_uh4.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-C4poRInZ.js → MtcAudit-T_CUIYUy.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-C_J0zXYZ.js → Multisig-N_e0RRWk.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Ci43sWOU.js → NLProgramming-Iq3VzEv0.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-DN7A-GFZ.js → Notes-B5sKJUJt.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-D5jNm71V.js → NotificationSettings-K8UVp8qQ.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-C9UsPOG8.js → OrderTableRenderer-BWNyM-6m.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BapYMJrP.js → Organization-DMO1NJxI.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BwxwjhFw.js → Overflow-BBY6b31Z.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-TObXXOu3.js → P2P-DmsL0y0v.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-UwJvMbFO.js → PdhVaultBrowser-C65AX_RY.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-Damnxv-O.js → Permissions-CWcpRtWa.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-d_7jlBb-.js → PersonalDataHub--ZNDIdsn.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-DA87VjLw.js → Pipeline-DCdj5NGb.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DzO_UvWn.js → Privacy-BRKu7Q3E.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CwqECDhs.js → ProjectInit-BJ7ozIAb.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CT5YdIl6.js → ProjectSettings-B2cVLiXW.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-D3KdZPCv.js → Projects-Ce9r_W-p.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BjBIS8kk.js → Providers-BDespvGZ.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-mMFqiKkI.js → QrScannerModal-BUNO4fDU.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BwGi9ZU1.js → QuickAsk-D2TUqeBV.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-BY65SR5s.js → Recommend-BNNQPHBH.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BGsVH_XU.js → RemoteSession-D2t1V_Cm.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-DpPbxSgI.js → Reputation-DVK5hEqI.js} +1 -1
- package/src/assets/web-panel/assets/{Row-B5YBYoVz.js → Row-BB9RTwmE.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DvM5jaoh.js → RssFeed-DmEO7liZ.js} +2 -2
- package/src/assets/web-panel/assets/{Search-6RX39EPO.js → Search-UwEYjnDB.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Beal-7cM.js → Security-DebqSsMp.js} +4 -4
- package/src/assets/web-panel/assets/{Services-D6rjVLe-.js → Services-CuuPts3C.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Dur7R7vz.js → Skeleton-DbWpmbgf.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-D1QkGwMk.js → Skills-BaK7SxzT.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-3ObrX8Es.js → Sla-BFHv51Jb.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DG_KAiH1.js → SpeechSettings-B9b1R6uK.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BaHq0SJ2.js → SyncSettings-BnO0CN02.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-BDpAkBAB.js → Tasks-Dy01Vq49.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-tYdoRd-c.js → Templates-BCy2AMHc.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-yGS5zIQ1.js → Tenant-4Tx9y_Y1.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B3QbmVFa.js → Terminal-CPOoUH8J.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-B_7Pr5dS.js → TimelineRenderer-C85GlJzu.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-DPvpDa53.js → Tokens-_xneFBGF.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DcSAD0GZ.js → Trigger-BizG4rTr.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-BBzEq-uy.js → Trust-Dh8EIn3n.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-Dssav7-5.js → UkeySign-C5NWoHWQ.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CPOZf4yi.js → VideoEditing-0YfrySL6.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BzBVRXEq.js → Wallet-BZVH8Ags.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DdSGaCCh.js → WebAuthn-kNofa6vm.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-CKjBFoSs.js → WorkflowEditor-BNO34_j0.js} +1 -1
- package/src/assets/web-panel/assets/{chat-B9aMGLg0.js → chat-ifQ2FlwD.js} +1 -1
- package/src/assets/web-panel/assets/{colors-GFCMctSV.js → colors-1TL8H6EH.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BqSDFAYJ.js → compact-item-DBfRjs_T.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BwUm3Ffp.js → createContext-Bs6V4iBf.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BHnbnuYL.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-DN1kMJOT.js → hasIn-Bz6LMY_0.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4dI_csl.js → index--WvT2Il3.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7Yu5wwV.js → index-84mi5rsv.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAK28GY8.js → index-B5SJCUZ7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmEHzOsw.js → index-B6RClMZl.js} +1 -1
- package/src/assets/web-panel/assets/{index-By9GbJhu.js → index-BB1Af7Fv.js} +1 -1
- package/src/assets/web-panel/assets/{index-7W1e9Vi4.js → index-BQL_tldd.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDL2MwxN.js → index-BXJXMaZe.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEMl-Qte.js → index-BhPDhmvN.js} +1 -1
- package/src/assets/web-panel/assets/{index-BCnbC2z7.js → index-BiZ7Nz5-.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cwih67e8.js → index-BoCTDcn6.js} +1 -1
- package/src/assets/web-panel/assets/{index-DI90Wo_P.js → index-BxqC3LiO.js} +1 -1
- package/src/assets/web-panel/assets/{index-THsr_UUJ.js → index-C6c0j-Ki.js} +1 -1
- package/src/assets/web-panel/assets/{index-PKwZkQDC.js → index-C7d6QlfR.js} +1 -1
- package/src/assets/web-panel/assets/{index-rCTtYCGu.js → index-C9QYxq61.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ci0zIpSX.js → index-CBh48_Mh.js} +1 -1
- package/src/assets/web-panel/assets/{index-tMF_deZb.js → index-CNKHoXWI.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9Pe-EyB.js → index-CXVBQ82k.js} +3 -3
- package/src/assets/web-panel/assets/{index-B4MfxM5W.js → index-CXtiLagi.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaFr7XB1.js → index-Cn7EIWmI.js} +1 -1
- package/src/assets/web-panel/assets/index-CsRz9-ZH.js +1 -0
- package/src/assets/web-panel/assets/{index-D8jcp9Rj.js → index-CtB45Hok.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cli0VREv.js → index-Cu_V6ZJH.js} +1 -1
- package/src/assets/web-panel/assets/{index-DO-IKERp.js → index-Cykt9BbN.js} +1 -1
- package/src/assets/web-panel/assets/{index-y7cfh9rP.js → index-DDhy4eCS.js} +1 -1
- package/src/assets/web-panel/assets/{index-CH2wK5dx.js → index-DEPPzM8I.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeycSy7n.js → index-DMVktlxG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BwssFWI1.js → index-DOww5Qny.js} +1 -1
- package/src/assets/web-panel/assets/{index-PJt1Zrx2.js → index-DWPp-d07.js} +1 -1
- package/src/assets/web-panel/assets/index-DnjMFf3m.js +1 -0
- package/src/assets/web-panel/assets/{index-BPGlcDvs.js → index-DvM2xBUA.js} +1 -1
- package/src/assets/web-panel/assets/{index-BL_0ndQc.js → index-EK3XtMxA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DnJt9DaX.js → index-XJIV7HEw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpiR6uzH.js → index-cNwsev6n.js} +1 -1
- package/src/assets/web-panel/assets/{index-bwb4cg_D.js → index-f_7L9GvP.js} +1 -1
- package/src/assets/web-panel/assets/{index-DbDhKroq.js → index-lUL3bD2z.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvvJWwT8.js → index-pOUFfRdN.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBMW8bQO.js → index-rGhS02f8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRikhGgx.js → index-vHtnQsnV.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHUxz4dy.js → index-vb1XIxEB.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-B6e5CZ5p.js → initDefaultProps-DpRIjwTt.js} +1 -1
- package/src/assets/web-panel/assets/{motion-riMM1KfJ.js → motion-CG4_9o-Z.js} +1 -1
- package/src/assets/web-panel/assets/{move-C1NSDMjc.js → move-Dku1fXtf.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-Bibuny9B.js → mtc-parser-BvAVeX-3.js} +1 -1
- package/src/assets/web-panel/assets/{omit-Cmf6FoRn.js → omit-DFu0x78D.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BSsYBUCY.js → pickAttrs-CmI-FNcK.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-gSB7-GAS.js → placementArrow-CGERYewB.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-qaqttvKa.js → responsiveObserve-D7G8bF5J.js} +1 -1
- package/src/assets/web-panel/assets/{slide-RX2gxl3k.js → slide-B2sXwWXy.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DEJmkhqw.js → statusUtils-DI5yh0n3.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CIWmJ78O.js → styleChecker-deGJ5dp_.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-D-UPSQBE.js → useFlexGapSupport-OqHBXEmi.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-9QFtqADc.js → useFs-Dqgx0Qv_.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DM6kyift.js → usePersonalDataHub-Be-lveh2.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-C-q6FNSJ.js → vnode-CFxB876W.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-D4WJY2m8.js → zoom-BFOYrl4e.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +11 -7
- package/src/commands/background-session.js +31 -3
- package/src/commands/chat.js +5 -1
- package/src/commands/eval.js +86 -28
- package/src/commands/llm.js +104 -1
- package/src/commands/plugin.js +130 -1
- package/src/commands/sandbox.js +121 -2
- package/src/commands/serve.js +11 -2
- package/src/commands/skill.js +29 -0
- package/src/data/changelog.json +26 -0
- package/src/gateways/ws/session-protocol.js +13 -0
- package/src/gateways/ws/ws-agent-handler.js +17 -0
- package/src/gateways/ws/ws-server.js +3 -0
- package/src/gateways/ws/ws-session-state.js +131 -0
- package/src/generated/cc-agent-protocol.schema.json +4 -0
- package/src/lazy-dispatch.js +8 -1
- package/src/lib/agent-sandbox.js +337 -53
- package/src/lib/app-server/cli-agent-kernel-adapter.js +28 -0
- package/src/lib/app-server/server.js +93 -0
- package/src/lib/background-agent-keeper-client.js +2 -0
- package/src/lib/background-agent-keeper-protocol.js +7 -0
- package/src/lib/background-agent-supervisor.js +194 -47
- package/src/lib/codex-app-server-adapter.js +81 -27
- package/src/lib/context-memory-kernel/durable-memory-port.js +31 -8
- package/src/lib/context-memory-kernel/provider-context.js +53 -19
- package/src/lib/deferred-question-context.js +122 -0
- package/src/lib/eval/evidence.js +202 -64
- package/src/lib/eval/plugin-suite.js +917 -0
- package/src/lib/eval/runner.js +10 -3
- package/src/lib/evolution/agent-evolution-ingress.js +60 -8
- package/src/lib/evolution/agent-evolution-runtime-composition.js +236 -1
- package/src/lib/evolution/agent-model-projection.js +97 -1
- package/src/lib/evolution/evidence-backed-wiki-maintainer.js +154 -1
- package/src/lib/evolution/evolution-artifact-ports.js +6 -0
- package/src/lib/evolution/evolution-deployment-loader.js +188 -10
- package/src/lib/evolution/evolution-eval-gate.js +8 -0
- package/src/lib/evolution/evolution-eval-runtime-composition.js +255 -0
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +58 -2
- package/src/lib/evolution/evolution-ledger-file-backend.js +23 -2
- package/src/lib/evolution/evolution-ledger-manifest-chain.js +223 -7
- package/src/lib/evolution/evolution-ledger-v2-journal.js +525 -0
- package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +46 -2
- package/src/lib/evolution/evolution-ledger.js +57 -1
- package/src/lib/evolution/evolution-run-ledger-adapter.js +93 -0
- package/src/lib/evolution/evolution-run-wiki-evidence-resolver.js +259 -0
- package/src/lib/evolution/governed-hub-llm.js +238 -5
- package/src/lib/evolution/governed-hub-resolver.js +82 -4
- package/src/lib/evolution/governed-hub-skill.js +11 -5
- package/src/lib/evolution/governed-skill-synthesis-provider-chat.js +10 -1
- package/src/lib/evolution/skill-runtime-revalidation-ledger-adapter.js +254 -0
- package/src/lib/evolution/skill-runtime-revalidation.js +530 -0
- package/src/lib/evolution/skill-target-matrix-eval.js +4 -4
- package/src/lib/evolution/wiki-evidence-commit-guard.js +366 -0
- package/src/lib/evolution/wiki-informed-skill-proposer.js +13 -1
- package/src/lib/goal-context.js +14 -5
- package/src/lib/interaction-adapter.js +166 -1
- package/src/lib/model-capabilities.js +271 -0
- package/src/lib/model-context-catalog.js +105 -0
- package/src/lib/model-context-window.js +4 -49
- package/src/lib/openai-responses.js +428 -0
- package/src/lib/plugin-runtime/scopes.js +7 -1
- package/src/lib/remote-read-loop-guard.js +2 -2
- package/src/lib/runtime-usage-ledger.js +16 -0
- package/src/lib/skill-loader.js +12 -0
- package/src/lib/with-file-lock.js +3 -1
- package/src/repl/agent-repl.js +6 -2
- package/src/runtime/agent-core.js +357 -44
- package/src/runtime/agent-runtime.js +7 -0
- package/src/runtime/coding-agent-contract-shared.cjs +13 -1
- package/src/runtime/headless-runner.js +4 -1
- package/src/runtime/headless-stream.js +133 -44
- package/src/runtime/runtime-factory.js +26 -2
- package/src/workers/background-agent-keeper.js +23 -13
- package/src/workers/background-agent-worker.js +27 -13
- package/src/assets/web-panel/assets/EvolutionSettings-_QnjPFZJ.js +0 -1
- package/src/assets/web-panel/assets/devWarning-LxtRBsCm.js +0 -1
- package/src/assets/web-panel/assets/index-36hxBH-o.js +0 -1
- package/src/assets/web-panel/assets/index-C0b78zWZ.js +0 -1
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { types as utilTypes } from "node:util";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
EvolutionEvalChildEvidenceLedgerAdapter,
|
|
5
|
+
createEvolutionEvalChildEvidenceStorePort,
|
|
6
|
+
} from "./evolution-eval-child-evidence-ledger-adapter.js";
|
|
7
|
+
import {
|
|
8
|
+
SkillTargetMatrixEvalAggregator,
|
|
9
|
+
SkillTargetMatrixEvalReceiptVerifier,
|
|
10
|
+
} from "./skill-target-matrix-eval.js";
|
|
11
|
+
import { createSkillEvaluatedPromotionDurabilityAdapter } from "./skill-evaluated-promotion-durability.js";
|
|
12
|
+
|
|
13
|
+
export const EVOLUTION_EVAL_RUNTIME_COMPOSITION_SCHEMA =
|
|
14
|
+
"chainlesschain.evolution-eval-runtime-composition/v1";
|
|
15
|
+
export const EVOLUTION_EVAL_COMPOSITION_UNAVAILABLE_CODE =
|
|
16
|
+
"CC_EVOLUTION_EVAL_COMPOSITION_UNAVAILABLE";
|
|
17
|
+
|
|
18
|
+
const COMPOSITIONS = new WeakMap();
|
|
19
|
+
const DESCRIPTOR_KEYS = [
|
|
20
|
+
"tenantId",
|
|
21
|
+
"runId",
|
|
22
|
+
"authorityId",
|
|
23
|
+
"revision",
|
|
24
|
+
"handlerArtifactDigest",
|
|
25
|
+
];
|
|
26
|
+
const ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
|
|
27
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
28
|
+
|
|
29
|
+
function unavailable(message, cause) {
|
|
30
|
+
const error = new Error(message, cause ? { cause } : undefined);
|
|
31
|
+
error.code = EVOLUTION_EVAL_COMPOSITION_UNAVAILABLE_CODE;
|
|
32
|
+
return error;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function record(value, keys, label) {
|
|
36
|
+
if (
|
|
37
|
+
!value ||
|
|
38
|
+
typeof value !== "object" ||
|
|
39
|
+
utilTypes.isProxy(value) ||
|
|
40
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(value))
|
|
41
|
+
)
|
|
42
|
+
throw unavailable(`${label} must be a plain data record`);
|
|
43
|
+
const ownKeys = Reflect.ownKeys(value);
|
|
44
|
+
if (
|
|
45
|
+
keys &&
|
|
46
|
+
(ownKeys.length !== keys.length ||
|
|
47
|
+
ownKeys.some((key) => !keys.includes(key)))
|
|
48
|
+
)
|
|
49
|
+
throw unavailable(`${label} must contain exactly the required ports`);
|
|
50
|
+
for (const key of ownKeys) {
|
|
51
|
+
const property = Object.getOwnPropertyDescriptor(value, key);
|
|
52
|
+
if (
|
|
53
|
+
typeof key !== "string" ||
|
|
54
|
+
!property ||
|
|
55
|
+
!("value" in property) ||
|
|
56
|
+
!property.enumerable
|
|
57
|
+
)
|
|
58
|
+
throw unavailable(`${label}.${String(key)} must be an own data property`);
|
|
59
|
+
}
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function descriptor(input) {
|
|
64
|
+
record(input, DESCRIPTOR_KEYS, "Eval composition descriptor");
|
|
65
|
+
for (const key of ["tenantId", "runId", "authorityId"])
|
|
66
|
+
if (typeof input[key] !== "string" || !ID.test(input[key]))
|
|
67
|
+
throw unavailable(`Eval composition ${key} is invalid`);
|
|
68
|
+
if (
|
|
69
|
+
!Number.isSafeInteger(input.revision) ||
|
|
70
|
+
input.revision < 1 ||
|
|
71
|
+
typeof input.handlerArtifactDigest !== "string" ||
|
|
72
|
+
!DIGEST.test(input.handlerArtifactDigest)
|
|
73
|
+
)
|
|
74
|
+
throw unavailable("Eval composition authority revision/digest is invalid");
|
|
75
|
+
return Object.freeze({ ...input });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Host-authorized construction only: supplies no signing keys, policy defaults,
|
|
80
|
+
* grader, corpus, reservation service, supervisor, or durability authority.
|
|
81
|
+
* Receipt verification uses the exact authority pair captured by the aggregator.
|
|
82
|
+
*/
|
|
83
|
+
export function createEvolutionEvalRuntimeComposition(options) {
|
|
84
|
+
try {
|
|
85
|
+
record(
|
|
86
|
+
options,
|
|
87
|
+
[
|
|
88
|
+
"descriptor",
|
|
89
|
+
"aggregatorOptions",
|
|
90
|
+
"verificationLimits",
|
|
91
|
+
"durabilityOptions",
|
|
92
|
+
],
|
|
93
|
+
"Eval composition options",
|
|
94
|
+
);
|
|
95
|
+
const binding = descriptor(options.descriptor);
|
|
96
|
+
const matrix = {
|
|
97
|
+
...record(options.aggregatorOptions, null, "Eval aggregator options"),
|
|
98
|
+
};
|
|
99
|
+
const limits = record(
|
|
100
|
+
options.verificationLimits,
|
|
101
|
+
["maximumReceiptTtlMs", "maximumVerificationMs"],
|
|
102
|
+
"Eval verification limits",
|
|
103
|
+
);
|
|
104
|
+
if (matrix.tenantId !== binding.tenantId)
|
|
105
|
+
throw unavailable("Eval aggregator belongs to another tenant");
|
|
106
|
+
const aggregator = new SkillTargetMatrixEvalAggregator(matrix);
|
|
107
|
+
const receiptVerifier = new SkillTargetMatrixEvalReceiptVerifier({
|
|
108
|
+
matrixReceiptVerifier: matrix.matrixReceiptVerifier,
|
|
109
|
+
matrixReceiptSignerDescriptor:
|
|
110
|
+
matrix.matrixReceiptSigner.authorityDescriptor,
|
|
111
|
+
matrixReceiptTrust: matrix.matrixReceiptTrust,
|
|
112
|
+
matrixSupervisor: matrix.matrixSupervisor,
|
|
113
|
+
supervisorPolicy: matrix.supervisorPolicy,
|
|
114
|
+
clock: matrix.clock,
|
|
115
|
+
clockPolicy: matrix.clockPolicy,
|
|
116
|
+
...limits,
|
|
117
|
+
});
|
|
118
|
+
const durability = createSkillEvaluatedPromotionDurabilityAdapter(
|
|
119
|
+
options.durabilityOptions,
|
|
120
|
+
);
|
|
121
|
+
const composition = Object.freeze({
|
|
122
|
+
schema: EVOLUTION_EVAL_RUNTIME_COMPOSITION_SCHEMA,
|
|
123
|
+
descriptor: binding,
|
|
124
|
+
// Downstream promotion can reuse the same read-only receipt authorities.
|
|
125
|
+
receiptVerifier,
|
|
126
|
+
receiptResolver: durability.resolver,
|
|
127
|
+
});
|
|
128
|
+
COMPOSITIONS.set(
|
|
129
|
+
composition,
|
|
130
|
+
Object.freeze({
|
|
131
|
+
aggregator,
|
|
132
|
+
receiptVerifier,
|
|
133
|
+
durability,
|
|
134
|
+
childReceiptStore: matrix.childReceiptStore,
|
|
135
|
+
}),
|
|
136
|
+
);
|
|
137
|
+
return composition;
|
|
138
|
+
} catch (cause) {
|
|
139
|
+
if (cause?.code === EVOLUTION_EVAL_COMPOSITION_UNAVAILABLE_CODE)
|
|
140
|
+
throw cause;
|
|
141
|
+
throw unavailable("Eval production authority construction failed", cause);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export function captureEvolutionEvalRuntimeComposition(value, expected) {
|
|
146
|
+
const ports = COMPOSITIONS.get(value);
|
|
147
|
+
if (!ports)
|
|
148
|
+
throw unavailable("a branded Eval runtime composition is required");
|
|
149
|
+
if (expected) {
|
|
150
|
+
for (const key of DESCRIPTOR_KEYS)
|
|
151
|
+
if (value.descriptor[key] !== expected.descriptor[key])
|
|
152
|
+
throw unavailable(`Eval composition differs from runtime ${key}`);
|
|
153
|
+
if (ports.childReceiptStore !== expected.childReceiptStore)
|
|
154
|
+
throw unavailable(
|
|
155
|
+
"Eval composition must use the runtime child evidence store",
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
return ports;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Root-owned authenticated storage; the host receives no ledger write port. */
|
|
162
|
+
export function createEvolutionEvalRuntimeChildEvidenceStore({
|
|
163
|
+
descriptor: input,
|
|
164
|
+
artifactPorts,
|
|
165
|
+
ledger,
|
|
166
|
+
ledgerArtifactResolver,
|
|
167
|
+
audience,
|
|
168
|
+
now,
|
|
169
|
+
}) {
|
|
170
|
+
const binding = descriptor(input);
|
|
171
|
+
const storeDescriptor = Object.freeze({
|
|
172
|
+
tenantId: binding.tenantId,
|
|
173
|
+
streamId: binding.runId,
|
|
174
|
+
authorityId: binding.authorityId,
|
|
175
|
+
revision: binding.revision,
|
|
176
|
+
handlerArtifactDigest: binding.handlerArtifactDigest,
|
|
177
|
+
});
|
|
178
|
+
const adapter = new EvolutionEvalChildEvidenceLedgerAdapter({
|
|
179
|
+
descriptor: {
|
|
180
|
+
...storeDescriptor,
|
|
181
|
+
artifactTenantId: binding.tenantId,
|
|
182
|
+
audience,
|
|
183
|
+
purpose: "evolution-ledger",
|
|
184
|
+
},
|
|
185
|
+
artifactPorts,
|
|
186
|
+
ledger,
|
|
187
|
+
ledgerArtifactResolver,
|
|
188
|
+
now,
|
|
189
|
+
});
|
|
190
|
+
return createEvolutionEvalChildEvidenceStorePort({
|
|
191
|
+
descriptor: storeDescriptor,
|
|
192
|
+
retain: adapter.retain.bind(adapter),
|
|
193
|
+
resolve: adapter.resolve.bind(adapter),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/** Called only by the Agent root after constructing its authenticated backend. */
|
|
198
|
+
export function createEvolutionEvalRuntimeStageConfiguration({
|
|
199
|
+
configuration,
|
|
200
|
+
tenantId,
|
|
201
|
+
runId,
|
|
202
|
+
...storage
|
|
203
|
+
}) {
|
|
204
|
+
try {
|
|
205
|
+
record(
|
|
206
|
+
configuration,
|
|
207
|
+
[
|
|
208
|
+
"descriptor",
|
|
209
|
+
"createComposition",
|
|
210
|
+
"planRef",
|
|
211
|
+
"expectedReceipt",
|
|
212
|
+
"usage",
|
|
213
|
+
],
|
|
214
|
+
"releaseTrain.domain.eval",
|
|
215
|
+
);
|
|
216
|
+
record(
|
|
217
|
+
configuration.descriptor,
|
|
218
|
+
["authorityId", "revision", "handlerArtifactDigest"],
|
|
219
|
+
"releaseTrain.domain.eval.descriptor",
|
|
220
|
+
);
|
|
221
|
+
const binding = descriptor({
|
|
222
|
+
...configuration.descriptor,
|
|
223
|
+
tenantId,
|
|
224
|
+
runId,
|
|
225
|
+
});
|
|
226
|
+
const factory = configuration.createComposition;
|
|
227
|
+
if (
|
|
228
|
+
typeof factory !== "function" ||
|
|
229
|
+
utilTypes.isProxy(factory) ||
|
|
230
|
+
utilTypes.isAsyncFunction(factory) ||
|
|
231
|
+
utilTypes.isGeneratorFunction(factory)
|
|
232
|
+
)
|
|
233
|
+
throw unavailable("Eval createComposition must be a synchronous factory");
|
|
234
|
+
const childReceiptStore = createEvolutionEvalRuntimeChildEvidenceStore({
|
|
235
|
+
descriptor: binding,
|
|
236
|
+
...storage,
|
|
237
|
+
});
|
|
238
|
+
const context = Object.freeze({ descriptor: binding, childReceiptStore });
|
|
239
|
+
const composition = Reflect.apply(factory, undefined, [context]);
|
|
240
|
+
const { aggregator, receiptVerifier, durability } =
|
|
241
|
+
captureEvolutionEvalRuntimeComposition(composition, context);
|
|
242
|
+
return Object.freeze({
|
|
243
|
+
aggregator,
|
|
244
|
+
receiptVerifier,
|
|
245
|
+
durability,
|
|
246
|
+
planRef: configuration.planRef,
|
|
247
|
+
expectedReceipt: configuration.expectedReceipt,
|
|
248
|
+
usage: configuration.usage,
|
|
249
|
+
});
|
|
250
|
+
} catch (cause) {
|
|
251
|
+
if (cause?.code === EVOLUTION_EVAL_COMPOSITION_UNAVAILABLE_CODE)
|
|
252
|
+
throw cause;
|
|
253
|
+
throw unavailable("Eval production composition is unavailable", cause);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -12,9 +12,11 @@ import { types as utilTypes } from "node:util";
|
|
|
12
12
|
import { ArtifactStore } from "../artifact-store.js";
|
|
13
13
|
import {
|
|
14
14
|
EvolutionArtifactPorts,
|
|
15
|
+
EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
|
|
15
16
|
EVOLUTION_ARTIFACT_DEFAULT_TTL_MS,
|
|
16
17
|
EVOLUTION_ARTIFACT_MAX_TTL_MS,
|
|
17
18
|
} from "./evolution-artifact-ports.js";
|
|
19
|
+
import { EVOLUTION_ARTIFACT_REF_SCHEMA } from "./evolution-ledger.js";
|
|
18
20
|
import {
|
|
19
21
|
EVOLUTION_RAW_STORAGE_RECEIPT_SCHEMA,
|
|
20
22
|
EvolutionEvidenceBundleVerifier,
|
|
@@ -340,6 +342,7 @@ export class EvolutionEvidenceArtifactAdapter {
|
|
|
340
342
|
#projectAgentModel;
|
|
341
343
|
#verify;
|
|
342
344
|
#ports;
|
|
345
|
+
#resolveManifestRef;
|
|
343
346
|
|
|
344
347
|
constructor({
|
|
345
348
|
tenantId,
|
|
@@ -384,6 +387,10 @@ export class EvolutionEvidenceArtifactAdapter {
|
|
|
384
387
|
);
|
|
385
388
|
this.#verify = captureMethod(bundleVerifier, "verify", "bundleVerifier");
|
|
386
389
|
this.#ports = artifactPorts;
|
|
390
|
+
this.#resolveManifestRef =
|
|
391
|
+
artifactPorts.createEvolutionLedgerArtifactResolver({
|
|
392
|
+
purpose: this.#purpose,
|
|
393
|
+
});
|
|
387
394
|
Object.freeze(this);
|
|
388
395
|
}
|
|
389
396
|
|
|
@@ -468,11 +475,60 @@ export class EvolutionEvidenceArtifactAdapter {
|
|
|
468
475
|
purpose: this.#purpose,
|
|
469
476
|
tenantId: this.#tenantId,
|
|
470
477
|
});
|
|
471
|
-
|
|
478
|
+
return this.#resolveManifest(manifestResolved.value, result.evidenceId);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Authenticate retained bytes at a Run's manifest locator. This is NOT Run
|
|
483
|
+
* membership or caller read authorization: the Wiki resolver obtains the
|
|
484
|
+
* event from its captured Run capability and separately calls readTrusted.
|
|
485
|
+
*/
|
|
486
|
+
async resolveRunEvidence({ event, ledgerId, epoch } = {}) {
|
|
487
|
+
if (
|
|
488
|
+
event?.type !== "raw-event-referenced" ||
|
|
489
|
+
event.tenantId !== this.#tenantId ||
|
|
490
|
+
event.data?.derivationManifestDigest !== event.payloadDigest
|
|
491
|
+
) {
|
|
492
|
+
throw new TypeError("Run evidence manifest binding is invalid");
|
|
493
|
+
}
|
|
494
|
+
const evidenceId = normalizeId(event.subjectId, "Run evidenceId");
|
|
495
|
+
const resolved = this.#resolveManifestRef({
|
|
496
|
+
tenantId: this.#tenantId,
|
|
497
|
+
ledgerId,
|
|
498
|
+
epoch,
|
|
499
|
+
ref: {
|
|
500
|
+
schema: EVOLUTION_ARTIFACT_REF_SCHEMA,
|
|
501
|
+
ref: event.artifactRef,
|
|
502
|
+
digest: event.payloadDigest,
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
if (
|
|
506
|
+
resolved.authenticated !== true ||
|
|
507
|
+
resolved.found !== true ||
|
|
508
|
+
resolved.digest !== event.payloadDigest ||
|
|
509
|
+
resolved.ref !== event.artifactRef ||
|
|
510
|
+
!Buffer.isBuffer(resolved.bytes)
|
|
511
|
+
) {
|
|
512
|
+
throw new Error("Run evidence manifest resolution is unbound");
|
|
513
|
+
}
|
|
514
|
+
const record = JSON.parse(resolved.bytes.toString("utf8"));
|
|
515
|
+
if (
|
|
516
|
+
record.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
|
|
517
|
+
record.tenantId !== this.#tenantId ||
|
|
518
|
+
record.audience !== this.#audience ||
|
|
519
|
+
record.purpose !== this.#purpose ||
|
|
520
|
+
record.type !== "evidence"
|
|
521
|
+
) {
|
|
522
|
+
throw new Error("Run evidence manifest record is unbound");
|
|
523
|
+
}
|
|
524
|
+
return this.#resolveManifest(record.value, evidenceId);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
async #resolveManifest(manifest, evidenceId) {
|
|
472
528
|
if (
|
|
473
529
|
manifest.schema !== EVOLUTION_EVIDENCE_DERIVATION_MANIFEST_SCHEMA ||
|
|
474
530
|
manifest.tenantId !== this.#tenantId ||
|
|
475
|
-
manifest.evidenceId !==
|
|
531
|
+
manifest.evidenceId !== evidenceId
|
|
476
532
|
) {
|
|
477
533
|
throw new Error("evidence derivation manifest is invalid");
|
|
478
534
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { createEvolutionFileWitness } from "./evolution-file-witness.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
EvolutionLedger,
|
|
6
|
+
captureEvolutionLedgerMigrationSource,
|
|
7
|
+
} from "./evolution-ledger.js";
|
|
8
|
+
import { createEvolutionLedgerV2JournalFromFactory } from "./evolution-ledger-v2-journal.js";
|
|
5
9
|
|
|
6
10
|
export const EVOLUTION_LEDGER_FILE_BACKEND_SCHEMA =
|
|
7
11
|
"chainlesschain.evolution-ledger-file-backend/v1";
|
|
@@ -110,6 +114,7 @@ export function createEvolutionLedgerFileBackend({
|
|
|
110
114
|
crashHook = null,
|
|
111
115
|
witnessMaximumBytes,
|
|
112
116
|
witnessMaximumHistoryBytes,
|
|
117
|
+
manifestV2 = null,
|
|
113
118
|
} = {}) {
|
|
114
119
|
if (typeof artifactResolver !== "function") {
|
|
115
120
|
throw new TypeError("artifactResolver port is required");
|
|
@@ -151,7 +156,7 @@ export function createEvolutionLedgerFileBackend({
|
|
|
151
156
|
: { maximumHistoryBytes: witnessMaximumHistoryBytes }),
|
|
152
157
|
};
|
|
153
158
|
const witness = createEvolutionFileWitness(witnessOptions);
|
|
154
|
-
const
|
|
159
|
+
const sourceLedger = new EvolutionLedger({
|
|
155
160
|
rootDir: paths.eventRoot,
|
|
156
161
|
authorityRootDir: paths.authorityRoot,
|
|
157
162
|
secure,
|
|
@@ -170,6 +175,22 @@ export function createEvolutionLedgerFileBackend({
|
|
|
170
175
|
...(lockTimeoutMs === undefined ? {} : { lockTimeoutMs }),
|
|
171
176
|
crashHook,
|
|
172
177
|
});
|
|
178
|
+
if (
|
|
179
|
+
manifestV2 === null &&
|
|
180
|
+
captureEvolutionLedgerMigrationSource(sourceLedger).requiresV2()
|
|
181
|
+
) {
|
|
182
|
+
throw Object.assign(
|
|
183
|
+
new Error("migrated ledger requires its authenticated v2 composition"),
|
|
184
|
+
{ code: "CC_EVOLUTION_LEDGER_V2_REQUIRED" },
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
const ledger =
|
|
188
|
+
manifestV2 === null
|
|
189
|
+
? sourceLedger
|
|
190
|
+
: createEvolutionLedgerV2JournalFromFactory(sourceLedger, manifestV2, {
|
|
191
|
+
...(lock === undefined ? {} : { lock }),
|
|
192
|
+
...(lockTimeoutMs === undefined ? {} : { lockTimeoutMs }),
|
|
193
|
+
});
|
|
173
194
|
const backend = Object.freeze({
|
|
174
195
|
schema: EVOLUTION_LEDGER_FILE_BACKEND_SCHEMA,
|
|
175
196
|
descriptor: Object.freeze({
|
|
@@ -11,6 +11,8 @@ export const EVOLUTION_LEDGER_MANIFEST_CHAIN_SCHEMA =
|
|
|
11
11
|
"chainlesschain.evolution-ledger-manifest-chain/v2";
|
|
12
12
|
export const EVOLUTION_LEDGER_SEGMENT_PAYLOAD_SCHEMA =
|
|
13
13
|
"chainlesschain.evolution-ledger-segment-payload/v2";
|
|
14
|
+
export const EVOLUTION_LEDGER_EVENT_PAYLOAD_SCHEMA =
|
|
15
|
+
"chainlesschain.evolution-ledger-event-payload/v2";
|
|
14
16
|
export const EVOLUTION_LEDGER_SEGMENT_MANIFEST_SCHEMA =
|
|
15
17
|
"chainlesschain.evolution-ledger-segment-manifest/v2";
|
|
16
18
|
export const EVOLUTION_LEDGER_MANIFEST_HEAD_SCHEMA =
|
|
@@ -336,8 +338,163 @@ function payload(sequenceStart, eventDigests) {
|
|
|
336
338
|
});
|
|
337
339
|
}
|
|
338
340
|
|
|
341
|
+
// Snapshot only bounded canonical JSON. Do not invoke getters, toJSON or Proxy
|
|
342
|
+
// traps while capturing signed event bytes supplied to the storage boundary.
|
|
343
|
+
function snapshotEvent(
|
|
344
|
+
value,
|
|
345
|
+
depth = 0,
|
|
346
|
+
seen = new Set(),
|
|
347
|
+
budget = { bytes: 64 * 1024 * 1024, nodes: 1_000_000 },
|
|
348
|
+
) {
|
|
349
|
+
rejectProxy(value, "event payload");
|
|
350
|
+
budget.bytes -=
|
|
351
|
+
typeof value === "string" ? Buffer.byteLength(value, "utf8") : 8;
|
|
352
|
+
if (--budget.nodes < 0 || budget.bytes < 0)
|
|
353
|
+
throw failure(
|
|
354
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
355
|
+
"event payload exceeds bounded capacity",
|
|
356
|
+
);
|
|
357
|
+
if (depth > 32 || seen.has(value))
|
|
358
|
+
throw failure(
|
|
359
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
360
|
+
"event payload is cyclic or too deep",
|
|
361
|
+
);
|
|
362
|
+
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
363
|
+
return value;
|
|
364
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
365
|
+
if (
|
|
366
|
+
!value ||
|
|
367
|
+
typeof value !== "object" ||
|
|
368
|
+
![Array.isArray(value) ? Array.prototype : Object.prototype, null].includes(
|
|
369
|
+
Object.getPrototypeOf(value),
|
|
370
|
+
)
|
|
371
|
+
)
|
|
372
|
+
throw failure(
|
|
373
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
374
|
+
"event payload must be JSON data",
|
|
375
|
+
);
|
|
376
|
+
seen.add(value);
|
|
377
|
+
const array = Array.isArray(value);
|
|
378
|
+
const result = array ? [] : Object.create(null);
|
|
379
|
+
const keys = Reflect.ownKeys(value).filter(
|
|
380
|
+
(key) => !(array && key === "length"),
|
|
381
|
+
);
|
|
382
|
+
if (array && keys.length !== value.length)
|
|
383
|
+
throw failure(
|
|
384
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
385
|
+
"event payload array must be dense",
|
|
386
|
+
);
|
|
387
|
+
for (const key of keys) {
|
|
388
|
+
const property = Object.getOwnPropertyDescriptor(value, key);
|
|
389
|
+
if (
|
|
390
|
+
typeof key !== "string" ||
|
|
391
|
+
!property.enumerable ||
|
|
392
|
+
!("value" in property) ||
|
|
393
|
+
(array &&
|
|
394
|
+
(!/^(0|[1-9][0-9]*)$/u.test(key) || Number(key) >= value.length))
|
|
395
|
+
)
|
|
396
|
+
throw failure(
|
|
397
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
398
|
+
"event payload must contain own data properties",
|
|
399
|
+
);
|
|
400
|
+
budget.bytes -= Buffer.byteLength(key, "utf8");
|
|
401
|
+
result[key] = snapshotEvent(property.value, depth + 1, seen, budget);
|
|
402
|
+
}
|
|
403
|
+
seen.delete(value);
|
|
404
|
+
return Object.freeze(result);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function eventPayload(sequenceStart, input, expected = {}) {
|
|
408
|
+
rejectProxy(input, "event payload");
|
|
409
|
+
if (
|
|
410
|
+
!Array.isArray(input) ||
|
|
411
|
+
input.length < 1 ||
|
|
412
|
+
input.length > MAX_EVENTS_PER_SEGMENT
|
|
413
|
+
)
|
|
414
|
+
throw failure(
|
|
415
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
416
|
+
"event payload count is invalid",
|
|
417
|
+
);
|
|
418
|
+
const events = snapshotEvent(input);
|
|
419
|
+
if (
|
|
420
|
+
!Array.isArray(events) ||
|
|
421
|
+
events.length < 1 ||
|
|
422
|
+
events.length > MAX_EVENTS_PER_SEGMENT
|
|
423
|
+
)
|
|
424
|
+
throw failure(
|
|
425
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
426
|
+
"event payload count is invalid",
|
|
427
|
+
);
|
|
428
|
+
let previous = expected.previousDigest;
|
|
429
|
+
for (const [index, event] of events.entries()) {
|
|
430
|
+
if (
|
|
431
|
+
!event ||
|
|
432
|
+
![
|
|
433
|
+
"chainlesschain.evolution-event/v2",
|
|
434
|
+
"chainlesschain.evolution-domain-event/v1",
|
|
435
|
+
].includes(event.schema)
|
|
436
|
+
)
|
|
437
|
+
throw failure(
|
|
438
|
+
EVOLUTION_LEDGER_MANIFEST_CORRUPT_CODE,
|
|
439
|
+
"event payload schema is invalid",
|
|
440
|
+
);
|
|
441
|
+
const { eventDigest, signature, ...core } = event;
|
|
442
|
+
const signatureFields = exactRecord(
|
|
443
|
+
signature,
|
|
444
|
+
new Set(["algorithm", "keyId", "trustPolicyDigest", "value"]),
|
|
445
|
+
"event payload signature",
|
|
446
|
+
EVOLUTION_LEDGER_MANIFEST_CORRUPT_CODE,
|
|
447
|
+
);
|
|
448
|
+
if (
|
|
449
|
+
["algorithm", "keyId", "trustPolicyDigest"].some(
|
|
450
|
+
(field) => data(signatureFields, field) !== event[field],
|
|
451
|
+
) ||
|
|
452
|
+
typeof signature.value !== "string" ||
|
|
453
|
+
signature.value.length < 1 ||
|
|
454
|
+
signature.value.length > 16_384
|
|
455
|
+
)
|
|
456
|
+
throw failure(
|
|
457
|
+
EVOLUTION_LEDGER_MANIFEST_CORRUPT_CODE,
|
|
458
|
+
"event signature binding differs",
|
|
459
|
+
);
|
|
460
|
+
if (
|
|
461
|
+
!signature ||
|
|
462
|
+
event.sequence !== sequenceStart + index ||
|
|
463
|
+
eventDigest !==
|
|
464
|
+
sha256(Buffer.from(`${event.schema}\0${canonical(core)}`, "utf8")) ||
|
|
465
|
+
(previous !== undefined && event.prevDigest !== previous) ||
|
|
466
|
+
(expected.epoch !== undefined && event.epoch !== expected.epoch) ||
|
|
467
|
+
(expected.ledgerId !== undefined &&
|
|
468
|
+
event.ledgerId !== expected.ledgerId) ||
|
|
469
|
+
(expected.tenantId !== undefined && event.tenantId !== expected.tenantId)
|
|
470
|
+
)
|
|
471
|
+
throw failure(
|
|
472
|
+
EVOLUTION_LEDGER_MANIFEST_CORRUPT_CODE,
|
|
473
|
+
"event payload digest, sequence or scope is invalid",
|
|
474
|
+
);
|
|
475
|
+
if (Buffer.byteLength(canonical(event), "utf8") > 1024 * 1024)
|
|
476
|
+
throw failure(
|
|
477
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
478
|
+
"event payload exceeds the event byte limit",
|
|
479
|
+
);
|
|
480
|
+
previous = eventDigest;
|
|
481
|
+
}
|
|
482
|
+
return Object.freeze({
|
|
483
|
+
events,
|
|
484
|
+
schema: EVOLUTION_LEDGER_EVENT_PAYLOAD_SCHEMA,
|
|
485
|
+
sequenceStart,
|
|
486
|
+
sequenceEnd: sequenceStart + events.length - 1,
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
|
|
339
490
|
function payloadBytes(value) {
|
|
340
|
-
|
|
491
|
+
const bytes = Buffer.from(canonical(value), "utf8");
|
|
492
|
+
if (bytes.length > 64 * 1024 * 1024)
|
|
493
|
+
throw failure(
|
|
494
|
+
EVOLUTION_LEDGER_MANIFEST_INVALID_CODE,
|
|
495
|
+
"event segment exceeds byte capacity",
|
|
496
|
+
);
|
|
497
|
+
return bytes;
|
|
341
498
|
}
|
|
342
499
|
|
|
343
500
|
function parsePayload(bytes, expected) {
|
|
@@ -356,6 +513,28 @@ function parsePayload(bytes, expected) {
|
|
|
356
513
|
"manifest segment payload is not JSON",
|
|
357
514
|
);
|
|
358
515
|
}
|
|
516
|
+
if (raw.schema === EVOLUTION_LEDGER_EVENT_PAYLOAD_SCHEMA) {
|
|
517
|
+
exactRecord(
|
|
518
|
+
raw,
|
|
519
|
+
new Set(["events", "schema", "sequenceStart", "sequenceEnd"]),
|
|
520
|
+
"event segment payload",
|
|
521
|
+
);
|
|
522
|
+
const parsed = eventPayload(expected.sequenceStart, raw.events, expected);
|
|
523
|
+
if (
|
|
524
|
+
!payloadBytes(parsed).equals(bytes) ||
|
|
525
|
+
raw.sequenceEnd !== expected.sequenceEnd
|
|
526
|
+
)
|
|
527
|
+
throw failure(
|
|
528
|
+
EVOLUTION_LEDGER_MANIFEST_CORRUPT_CODE,
|
|
529
|
+
"event segment payload range differs",
|
|
530
|
+
);
|
|
531
|
+
return Object.freeze({
|
|
532
|
+
...parsed,
|
|
533
|
+
eventDigests: Object.freeze(
|
|
534
|
+
parsed.events.map((event) => event.eventDigest),
|
|
535
|
+
),
|
|
536
|
+
});
|
|
537
|
+
}
|
|
359
538
|
const fields = exactRecord(
|
|
360
539
|
raw,
|
|
361
540
|
PAYLOAD_KEYS,
|
|
@@ -798,9 +977,17 @@ export function captureEvolutionLedgerManifestAuthority(value) {
|
|
|
798
977
|
}
|
|
799
978
|
|
|
800
979
|
export function sealEvolutionLedgerManifestSegment(options = undefined) {
|
|
980
|
+
const fullEvents =
|
|
981
|
+
options && !utilTypes.isProxy(options) && Object.hasOwn(options, "events");
|
|
801
982
|
const fields = exactRecord(
|
|
802
983
|
options,
|
|
803
|
-
|
|
984
|
+
fullEvents
|
|
985
|
+
? new Set(
|
|
986
|
+
[...SEAL_CONFIG_KEYS]
|
|
987
|
+
.filter((key) => key !== "eventDigests")
|
|
988
|
+
.concat("events"),
|
|
989
|
+
)
|
|
990
|
+
: SEAL_CONFIG_KEYS,
|
|
804
991
|
"manifest segment seal configuration",
|
|
805
992
|
);
|
|
806
993
|
const descriptorValue = descriptor(data(fields, "descriptor"));
|
|
@@ -818,8 +1005,17 @@ export function sealEvolutionLedgerManifestSegment(options = undefined) {
|
|
|
818
1005
|
descriptorValue,
|
|
819
1006
|
authority,
|
|
820
1007
|
);
|
|
1008
|
+
const sequenceStart = (previous?.sequence || 0) + 1;
|
|
1009
|
+
const fullPayload = fullEvents
|
|
1010
|
+
? eventPayload(sequenceStart, data(fields, "events"), {
|
|
1011
|
+
...descriptorValue,
|
|
1012
|
+
previousDigest: previous?.eventDigest ?? null,
|
|
1013
|
+
})
|
|
1014
|
+
: null;
|
|
821
1015
|
const eventDigests = normalizeDigests(
|
|
822
|
-
|
|
1016
|
+
fullPayload
|
|
1017
|
+
? fullPayload.events.map((event) => event.eventDigest)
|
|
1018
|
+
: data(fields, "eventDigests"),
|
|
823
1019
|
"eventDigests",
|
|
824
1020
|
descriptorValue.maximumEventsPerSegment,
|
|
825
1021
|
);
|
|
@@ -841,8 +1037,7 @@ export function sealEvolutionLedgerManifestSegment(options = undefined) {
|
|
|
841
1037
|
new Date(nowMs).toISOString(),
|
|
842
1038
|
"manifest issuedAt",
|
|
843
1039
|
).value;
|
|
844
|
-
const
|
|
845
|
-
const segmentPayload = payload(sequenceStart, eventDigests);
|
|
1040
|
+
const segmentPayload = fullPayload ?? payload(sequenceStart, eventDigests);
|
|
846
1041
|
let receipt;
|
|
847
1042
|
try {
|
|
848
1043
|
receipt = store.retain({
|
|
@@ -958,7 +1153,7 @@ export function verifyEvolutionLedgerSegmentManifest(options = undefined) {
|
|
|
958
1153
|
);
|
|
959
1154
|
}
|
|
960
1155
|
|
|
961
|
-
|
|
1156
|
+
function verifyChain(options, includeEvents) {
|
|
962
1157
|
const fields = exactRecord(
|
|
963
1158
|
options,
|
|
964
1159
|
VERIFY_CONFIG_KEYS,
|
|
@@ -987,6 +1182,7 @@ export function verifyEvolutionLedgerManifestChain(options = undefined) {
|
|
|
987
1182
|
);
|
|
988
1183
|
}
|
|
989
1184
|
let previous = null;
|
|
1185
|
+
const events = [];
|
|
990
1186
|
for (const rawManifest of manifests) {
|
|
991
1187
|
const manifest = normalizeManifest(rawManifest, descriptorValue, authority);
|
|
992
1188
|
if (
|
|
@@ -1023,7 +1219,18 @@ export function verifyEvolutionLedgerManifestChain(options = undefined) {
|
|
|
1023
1219
|
"manifest segment resolution is not authenticated immutable storage",
|
|
1024
1220
|
);
|
|
1025
1221
|
}
|
|
1026
|
-
const parsed = parsePayload(resolution.bytes,
|
|
1222
|
+
const parsed = parsePayload(resolution.bytes, {
|
|
1223
|
+
...manifest,
|
|
1224
|
+
previousDigest: previous?.eventDigests.at(-1) ?? null,
|
|
1225
|
+
});
|
|
1226
|
+
if (includeEvents) {
|
|
1227
|
+
if (!parsed.events)
|
|
1228
|
+
throw failure(
|
|
1229
|
+
EVOLUTION_LEDGER_MANIFEST_CORRUPT_CODE,
|
|
1230
|
+
"digest-only segments cannot recover event payloads",
|
|
1231
|
+
);
|
|
1232
|
+
events.push(...parsed.events);
|
|
1233
|
+
}
|
|
1027
1234
|
if (canonical(parsed.eventDigests) !== canonical(manifest.eventDigests)) {
|
|
1028
1235
|
throw failure(
|
|
1029
1236
|
EVOLUTION_LEDGER_MANIFEST_CORRUPT_CODE,
|
|
@@ -1049,5 +1256,14 @@ export function verifyEvolutionLedgerManifestChain(options = undefined) {
|
|
|
1049
1256
|
head,
|
|
1050
1257
|
manifestCount: manifests.length,
|
|
1051
1258
|
sequence: head.sequence,
|
|
1259
|
+
...(includeEvents ? { events: Object.freeze(events) } : {}),
|
|
1052
1260
|
});
|
|
1053
1261
|
}
|
|
1262
|
+
|
|
1263
|
+
export function verifyEvolutionLedgerManifestChain(options = undefined) {
|
|
1264
|
+
return verifyChain(options, false);
|
|
1265
|
+
}
|
|
1266
|
+
|
|
1267
|
+
export function readEvolutionLedgerManifestEvents(options = undefined) {
|
|
1268
|
+
return verifyChain(options, true);
|
|
1269
|
+
}
|