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,530 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { types } from "node:util";
|
|
3
|
+
import { captureSkillReleaseRegistryReader } from "./skill-release-registry.js";
|
|
4
|
+
import {
|
|
5
|
+
verifySkillDependencyLock,
|
|
6
|
+
verifySkillRuntimeManifest,
|
|
7
|
+
} from "./skill-execution-manifest.js";
|
|
8
|
+
import { captureSkillExecutionSnapshot } from "../skill-execution-identity.js";
|
|
9
|
+
|
|
10
|
+
export const SKILL_RUNTIME_STATE_SCHEMA =
|
|
11
|
+
"chainlesschain.skill-runtime-state/v1";
|
|
12
|
+
export const SKILL_RUNTIME_EVALUATION_SCHEMA =
|
|
13
|
+
"chainlesschain.skill-runtime-evaluation/v1";
|
|
14
|
+
export const SKILL_RUNTIME_STALE_CODE = "CC_SKILL_STALE_NEEDS_REVALIDATION";
|
|
15
|
+
export const SKILL_RUNTIME_STALE = "stale-needs-revalidation";
|
|
16
|
+
const admissions = new WeakSet();
|
|
17
|
+
const proofs = new WeakSet();
|
|
18
|
+
const loaderAdmissions = new WeakMap();
|
|
19
|
+
const requiredLoaders = new WeakSet();
|
|
20
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
21
|
+
|
|
22
|
+
export function runtimeCanonical(value) {
|
|
23
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
24
|
+
if (Array.isArray(value)) return `[${value.map(runtimeCanonical).join(",")}]`;
|
|
25
|
+
return `{${Object.keys(value)
|
|
26
|
+
.sort()
|
|
27
|
+
.map((key) => `${JSON.stringify(key)}:${runtimeCanonical(value[key])}`)
|
|
28
|
+
.join(",")}}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function digestSkillRuntimeValue(value) {
|
|
32
|
+
return `sha256:${createHash("sha256").update("chainlesschain.skill-runtime/v1\0").update(runtimeCanonical(value)).digest("hex")}`;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function fail(message, cause) {
|
|
36
|
+
const error = new Error(message, cause ? { cause } : undefined);
|
|
37
|
+
error.code = SKILL_RUNTIME_STALE_CODE;
|
|
38
|
+
error.status = SKILL_RUNTIME_STALE;
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function text(value, name) {
|
|
43
|
+
if (typeof value !== "string" || !value.trim() || value.length > 1024)
|
|
44
|
+
fail(`${name} is unknown`);
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function digest(value, name) {
|
|
49
|
+
if (typeof value !== "string" || !DIGEST.test(value))
|
|
50
|
+
fail(`${name} is unknown`);
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function freeze(value) {
|
|
55
|
+
if (value && typeof value === "object") {
|
|
56
|
+
for (const child of Object.values(value)) freeze(child);
|
|
57
|
+
Object.freeze(value);
|
|
58
|
+
}
|
|
59
|
+
return value;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function exact(value, keys, label) {
|
|
63
|
+
if (
|
|
64
|
+
!value ||
|
|
65
|
+
typeof value !== "object" ||
|
|
66
|
+
types.isProxy(value) ||
|
|
67
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(value)) ||
|
|
68
|
+
Reflect.ownKeys(value).length !== keys.length ||
|
|
69
|
+
keys.some(
|
|
70
|
+
(key) =>
|
|
71
|
+
!Object.getOwnPropertyDescriptor(value, key)?.enumerable ||
|
|
72
|
+
!("value" in Object.getOwnPropertyDescriptor(value, key)),
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
fail(`${label} is invalid`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const BINDING_KEYS = [
|
|
79
|
+
"tenantId",
|
|
80
|
+
"skillName",
|
|
81
|
+
"activeStateDigest",
|
|
82
|
+
"releaseDigest",
|
|
83
|
+
"contentDigest",
|
|
84
|
+
"filesystemDigest",
|
|
85
|
+
"runtimeManifestDigest",
|
|
86
|
+
"dependencyLockDigest",
|
|
87
|
+
"runtimeId",
|
|
88
|
+
"targetEnvironmentRef",
|
|
89
|
+
"environmentDigest",
|
|
90
|
+
"modelDigest",
|
|
91
|
+
"toolDigest",
|
|
92
|
+
"hostRuntimeDigest",
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
function binding(value) {
|
|
96
|
+
exact(value, BINDING_KEYS, "runtime binding");
|
|
97
|
+
for (const key of BINDING_KEYS) {
|
|
98
|
+
if (key.endsWith("Digest")) digest(value[key], key);
|
|
99
|
+
else text(value[key], key);
|
|
100
|
+
}
|
|
101
|
+
return freeze({ ...value });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function verifySkillRuntimeEvaluation(value) {
|
|
105
|
+
exact(
|
|
106
|
+
value,
|
|
107
|
+
[
|
|
108
|
+
"schema",
|
|
109
|
+
"evaluationId",
|
|
110
|
+
"binding",
|
|
111
|
+
"expectedEligibilityDigest",
|
|
112
|
+
"passed",
|
|
113
|
+
"evidenceDigest",
|
|
114
|
+
"receiptDigest",
|
|
115
|
+
],
|
|
116
|
+
"runtime evaluation",
|
|
117
|
+
);
|
|
118
|
+
if (value.schema !== SKILL_RUNTIME_EVALUATION_SCHEMA || value.passed !== true)
|
|
119
|
+
fail("evaluation did not pass");
|
|
120
|
+
const core = {
|
|
121
|
+
schema: value.schema,
|
|
122
|
+
evaluationId: text(value.evaluationId, "evaluationId"),
|
|
123
|
+
binding: binding(value.binding),
|
|
124
|
+
expectedEligibilityDigest: digest(
|
|
125
|
+
value.expectedEligibilityDigest,
|
|
126
|
+
"expectedEligibilityDigest",
|
|
127
|
+
),
|
|
128
|
+
passed: true,
|
|
129
|
+
evidenceDigest: digest(value.evidenceDigest, "evidenceDigest"),
|
|
130
|
+
};
|
|
131
|
+
if (digestSkillRuntimeValue(core) !== value.receiptDigest)
|
|
132
|
+
fail("evaluation receipt digest differs");
|
|
133
|
+
return freeze({ ...core, receiptDigest: value.receiptDigest });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function verifySkillRuntimeState(value, tenantId, skillName) {
|
|
137
|
+
exact(
|
|
138
|
+
value,
|
|
139
|
+
[
|
|
140
|
+
"schema",
|
|
141
|
+
"tenantId",
|
|
142
|
+
"skillName",
|
|
143
|
+
"revision",
|
|
144
|
+
"previousStateDigest",
|
|
145
|
+
"status",
|
|
146
|
+
"binding",
|
|
147
|
+
"reason",
|
|
148
|
+
"evaluationReceipt",
|
|
149
|
+
"stateDigest",
|
|
150
|
+
],
|
|
151
|
+
"runtime state",
|
|
152
|
+
);
|
|
153
|
+
const { stateDigest, ...core } = value;
|
|
154
|
+
if (
|
|
155
|
+
core.schema !== SKILL_RUNTIME_STATE_SCHEMA ||
|
|
156
|
+
core.tenantId !== tenantId ||
|
|
157
|
+
core.skillName !== skillName ||
|
|
158
|
+
!Number.isSafeInteger(core.revision) ||
|
|
159
|
+
core.revision < 1 ||
|
|
160
|
+
![SKILL_RUNTIME_STALE, "eligible"].includes(core.status) ||
|
|
161
|
+
digestSkillRuntimeValue(core) !== stateDigest
|
|
162
|
+
)
|
|
163
|
+
fail("runtime state bindings are invalid");
|
|
164
|
+
if (core.previousStateDigest !== null)
|
|
165
|
+
digest(core.previousStateDigest, "previousStateDigest");
|
|
166
|
+
text(core.reason, "reason");
|
|
167
|
+
if (core.binding !== null) binding(core.binding);
|
|
168
|
+
if (core.status === "eligible") {
|
|
169
|
+
const receipt = verifySkillRuntimeEvaluation(core.evaluationReceipt);
|
|
170
|
+
if (
|
|
171
|
+
!core.binding ||
|
|
172
|
+
runtimeCanonical(receipt.binding) !== runtimeCanonical(core.binding) ||
|
|
173
|
+
receipt.expectedEligibilityDigest !== core.previousStateDigest
|
|
174
|
+
)
|
|
175
|
+
fail("eligible state lacks exact evaluation evidence");
|
|
176
|
+
} else if (core.evaluationReceipt !== null)
|
|
177
|
+
fail("stale state cannot carry eligibility evidence");
|
|
178
|
+
return freeze(structuredClone(value));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// The privileged controller owns persistence, a genuine registry reader and a
|
|
182
|
+
// deployment-owned evaluation verifier. Execution receives only admission.
|
|
183
|
+
// No caller-supplied `passed` / descriptor field can restore eligibility.
|
|
184
|
+
export function createSkillRuntimeRevalidationAuthority({
|
|
185
|
+
releaseRegistry,
|
|
186
|
+
persistence,
|
|
187
|
+
resolveRuntime,
|
|
188
|
+
verifyEvaluation,
|
|
189
|
+
} = {}) {
|
|
190
|
+
const registry = captureSkillReleaseRegistryReader(releaseRegistry);
|
|
191
|
+
if (
|
|
192
|
+
typeof persistence?.load !== "function" ||
|
|
193
|
+
typeof persistence?.commit !== "function" ||
|
|
194
|
+
typeof resolveRuntime !== "function" ||
|
|
195
|
+
typeof verifyEvaluation !== "function"
|
|
196
|
+
) {
|
|
197
|
+
throw new TypeError(
|
|
198
|
+
"runtime revalidation requires persistence, runtime and evaluation authority ports",
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
const load = persistence.load.bind(persistence);
|
|
202
|
+
const commit = persistence.commit.bind(persistence);
|
|
203
|
+
const tenantId = registry.tenantId;
|
|
204
|
+
function read(skillName) {
|
|
205
|
+
const result = load({ tenantId, skillName });
|
|
206
|
+
if (
|
|
207
|
+
!result ||
|
|
208
|
+
result.authenticated !== true ||
|
|
209
|
+
result.durable !== true ||
|
|
210
|
+
typeof result.found !== "boolean" ||
|
|
211
|
+
result.found !== (result.state !== null)
|
|
212
|
+
)
|
|
213
|
+
fail("runtime state is unavailable");
|
|
214
|
+
return result.found
|
|
215
|
+
? verifySkillRuntimeState(result.state, tenantId, skillName)
|
|
216
|
+
: null;
|
|
217
|
+
}
|
|
218
|
+
function write(
|
|
219
|
+
skillName,
|
|
220
|
+
previous,
|
|
221
|
+
status,
|
|
222
|
+
observed,
|
|
223
|
+
reason,
|
|
224
|
+
receipt = null,
|
|
225
|
+
) {
|
|
226
|
+
const core = {
|
|
227
|
+
schema: SKILL_RUNTIME_STATE_SCHEMA,
|
|
228
|
+
tenantId,
|
|
229
|
+
skillName,
|
|
230
|
+
revision: (previous?.revision ?? 0) + 1,
|
|
231
|
+
previousStateDigest: previous?.stateDigest ?? null,
|
|
232
|
+
status,
|
|
233
|
+
binding: observed,
|
|
234
|
+
reason,
|
|
235
|
+
evaluationReceipt: receipt,
|
|
236
|
+
};
|
|
237
|
+
const state = verifySkillRuntimeState(
|
|
238
|
+
{ ...core, stateDigest: digestSkillRuntimeValue(core) },
|
|
239
|
+
tenantId,
|
|
240
|
+
skillName,
|
|
241
|
+
);
|
|
242
|
+
const result = commit({
|
|
243
|
+
state,
|
|
244
|
+
expectedStateDigest: previous?.stateDigest ?? null,
|
|
245
|
+
});
|
|
246
|
+
if (
|
|
247
|
+
result?.authenticated !== true ||
|
|
248
|
+
result.durable !== true ||
|
|
249
|
+
result.committed !== true ||
|
|
250
|
+
result.stateDigest !== state.stateDigest ||
|
|
251
|
+
read(skillName)?.stateDigest !== state.stateDigest
|
|
252
|
+
)
|
|
253
|
+
fail("runtime state commit was not confirmed");
|
|
254
|
+
return state;
|
|
255
|
+
}
|
|
256
|
+
function observe(skill, context, active) {
|
|
257
|
+
const declared = skill.releaseBinding ?? skill.evolutionRelease ?? skill;
|
|
258
|
+
for (const [key, expected] of [
|
|
259
|
+
["tenantId", tenantId],
|
|
260
|
+
["skillName", active.state.skillName],
|
|
261
|
+
["releaseDigest", active.release.releaseDigest],
|
|
262
|
+
["activeReleaseDigest", active.release.releaseDigest],
|
|
263
|
+
["activeStateDigest", active.state.stateDigest],
|
|
264
|
+
]) {
|
|
265
|
+
if (declared[key] != null && declared[key] !== expected)
|
|
266
|
+
fail("descriptor release binding differs from active release");
|
|
267
|
+
}
|
|
268
|
+
const runtime = resolveRuntime({
|
|
269
|
+
tenantId,
|
|
270
|
+
skillName: active.state.skillName,
|
|
271
|
+
context,
|
|
272
|
+
});
|
|
273
|
+
if (!runtime || typeof runtime.then === "function")
|
|
274
|
+
fail("current runtime is unknown");
|
|
275
|
+
const manifest = verifySkillRuntimeManifest(runtime.runtimeManifest);
|
|
276
|
+
const lock = verifySkillDependencyLock(runtime.dependencyLock);
|
|
277
|
+
if (
|
|
278
|
+
manifest.tenantId !== tenantId ||
|
|
279
|
+
lock.tenantId !== tenantId ||
|
|
280
|
+
!manifest.runtimes.some((entry) => entry.runtimeId === runtime.runtimeId)
|
|
281
|
+
)
|
|
282
|
+
fail("current runtime tenant or runtime is invalid");
|
|
283
|
+
const model = context.llmOptions;
|
|
284
|
+
text(model?.provider, "model provider");
|
|
285
|
+
text(model?.model, "model identity");
|
|
286
|
+
const toolNames = context.effectiveAllowedToolNames;
|
|
287
|
+
if (
|
|
288
|
+
!Array.isArray(toolNames) ||
|
|
289
|
+
toolNames.some((name) => typeof name !== "string" || !name)
|
|
290
|
+
)
|
|
291
|
+
fail("current tool surface is unknown");
|
|
292
|
+
const snapshot = captureSkillExecutionSnapshot({
|
|
293
|
+
skillDir: skill.skillDir,
|
|
294
|
+
skillId: active.state.skillName,
|
|
295
|
+
source: skill.source,
|
|
296
|
+
});
|
|
297
|
+
const contentDigest = `sha256:${createHash("sha256").update(snapshot.skillMdContent, "utf8").digest("hex")}`;
|
|
298
|
+
if (contentDigest !== active.release.contentDigest)
|
|
299
|
+
fail("filesystem content differs from the active release");
|
|
300
|
+
return binding({
|
|
301
|
+
tenantId,
|
|
302
|
+
skillName: active.state.skillName,
|
|
303
|
+
activeStateDigest: active.state.stateDigest,
|
|
304
|
+
releaseDigest: active.release.releaseDigest,
|
|
305
|
+
contentDigest,
|
|
306
|
+
filesystemDigest: snapshot.contentDigest,
|
|
307
|
+
runtimeManifestDigest: manifest.runtimeManifestDigest,
|
|
308
|
+
dependencyLockDigest: lock.dependencyLockDigest,
|
|
309
|
+
runtimeId: runtime.runtimeId,
|
|
310
|
+
targetEnvironmentRef: runtime.targetEnvironmentRef,
|
|
311
|
+
environmentDigest: runtime.environmentDigest,
|
|
312
|
+
modelDigest: digestSkillRuntimeValue({
|
|
313
|
+
provider: model.provider,
|
|
314
|
+
model: model.model,
|
|
315
|
+
baseUrl: model.baseUrl ?? null,
|
|
316
|
+
}),
|
|
317
|
+
toolDigest: digestSkillRuntimeValue({
|
|
318
|
+
names: [...new Set(toolNames)].sort(),
|
|
319
|
+
manifestDigest: digest(
|
|
320
|
+
runtime.toolManifestDigest,
|
|
321
|
+
"toolManifestDigest",
|
|
322
|
+
),
|
|
323
|
+
}),
|
|
324
|
+
hostRuntimeDigest: digestSkillRuntimeValue({
|
|
325
|
+
node: process.versions.node,
|
|
326
|
+
platform: process.platform,
|
|
327
|
+
arch: process.arch,
|
|
328
|
+
}),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
function inspect({ skill, context = {} }) {
|
|
332
|
+
const skillName = text(skill?.id || skill?.dirName, "skillName");
|
|
333
|
+
const previous = read(skillName);
|
|
334
|
+
let active;
|
|
335
|
+
let observed = null;
|
|
336
|
+
let reason = "runtime binding changed";
|
|
337
|
+
try {
|
|
338
|
+
active = registry.readActive(skillName);
|
|
339
|
+
if (!active && !previous && !hasSkillReleaseBinding(skill))
|
|
340
|
+
return Object.freeze({ governed: false, status: "unassessed" });
|
|
341
|
+
if (!active) fail("active release is unknown");
|
|
342
|
+
observed = observe(skill, context, active);
|
|
343
|
+
} catch {
|
|
344
|
+
reason = "active release or current runtime is unknown";
|
|
345
|
+
}
|
|
346
|
+
if (
|
|
347
|
+
observed &&
|
|
348
|
+
previous?.status === "eligible" &&
|
|
349
|
+
runtimeCanonical(previous.binding) === runtimeCanonical(observed)
|
|
350
|
+
) {
|
|
351
|
+
// Re-check trust on every execution; a persisted eligible flag alone is
|
|
352
|
+
// insufficient after evaluator revocation or verifier failure.
|
|
353
|
+
try {
|
|
354
|
+
if (verifyEvaluation(previous.evaluationReceipt) === true) {
|
|
355
|
+
const freshActive = registry.readActive(skillName);
|
|
356
|
+
const freshBinding = observe(skill, context, freshActive);
|
|
357
|
+
if (
|
|
358
|
+
runtimeCanonical(freshBinding) !== runtimeCanonical(observed) ||
|
|
359
|
+
read(skillName)?.stateDigest !== previous.stateDigest
|
|
360
|
+
) {
|
|
361
|
+
observed = freshBinding;
|
|
362
|
+
fail("runtime or active release changed during admission");
|
|
363
|
+
}
|
|
364
|
+
const proof = freeze({
|
|
365
|
+
governed: true,
|
|
366
|
+
status: "eligible",
|
|
367
|
+
binding: observed,
|
|
368
|
+
eligibilityDigest: previous.stateDigest,
|
|
369
|
+
});
|
|
370
|
+
proofs.add(proof);
|
|
371
|
+
return proof;
|
|
372
|
+
}
|
|
373
|
+
} catch {
|
|
374
|
+
/* Unknown trust is stale. */
|
|
375
|
+
}
|
|
376
|
+
reason = "evaluation authority is unavailable or revoked";
|
|
377
|
+
}
|
|
378
|
+
const state =
|
|
379
|
+
previous?.status === SKILL_RUNTIME_STALE &&
|
|
380
|
+
runtimeCanonical(previous.binding) === runtimeCanonical(observed) &&
|
|
381
|
+
previous.reason === reason
|
|
382
|
+
? previous
|
|
383
|
+
: write(skillName, previous, SKILL_RUNTIME_STALE, observed, reason);
|
|
384
|
+
return freeze({
|
|
385
|
+
governed: true,
|
|
386
|
+
status: SKILL_RUNTIME_STALE,
|
|
387
|
+
binding: observed,
|
|
388
|
+
eligibilityDigest: state.stateDigest,
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
const admission = Object.freeze({
|
|
392
|
+
tenantId,
|
|
393
|
+
inspect,
|
|
394
|
+
assertEligible(request) {
|
|
395
|
+
try {
|
|
396
|
+
const result = inspect(request);
|
|
397
|
+
if (result.status === SKILL_RUNTIME_STALE)
|
|
398
|
+
fail(`Skill requires revalidation (${result.eligibilityDigest})`);
|
|
399
|
+
return result;
|
|
400
|
+
} catch (cause) {
|
|
401
|
+
fail("Skill runtime admission failed closed", cause);
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
admissions.add(admission);
|
|
406
|
+
return Object.freeze({
|
|
407
|
+
admission,
|
|
408
|
+
inspect,
|
|
409
|
+
revalidate({ skill, context = {}, receipt: input }) {
|
|
410
|
+
const current = inspect({ skill, context });
|
|
411
|
+
if (
|
|
412
|
+
!current.governed ||
|
|
413
|
+
!current.binding ||
|
|
414
|
+
current.status !== SKILL_RUNTIME_STALE
|
|
415
|
+
)
|
|
416
|
+
fail("revalidation requires a stale active release and known runtime");
|
|
417
|
+
const receipt = verifySkillRuntimeEvaluation(input);
|
|
418
|
+
if (
|
|
419
|
+
receipt.expectedEligibilityDigest !== current.eligibilityDigest ||
|
|
420
|
+
runtimeCanonical(receipt.binding) !==
|
|
421
|
+
runtimeCanonical(current.binding) ||
|
|
422
|
+
verifyEvaluation(receipt) !== true
|
|
423
|
+
)
|
|
424
|
+
fail(
|
|
425
|
+
"fresh evaluation does not bind the current active release and runtime",
|
|
426
|
+
);
|
|
427
|
+
// Verifiers may call external authority: repeat both release CAS and all
|
|
428
|
+
// observed bindings before committing eligibility.
|
|
429
|
+
const checked = inspect({ skill, context });
|
|
430
|
+
if (
|
|
431
|
+
checked.eligibilityDigest !== current.eligibilityDigest ||
|
|
432
|
+
runtimeCanonical(checked.binding) !== runtimeCanonical(current.binding)
|
|
433
|
+
)
|
|
434
|
+
fail("active release or runtime changed during revalidation");
|
|
435
|
+
const previous = read(receipt.binding.skillName);
|
|
436
|
+
if (previous?.stateDigest !== current.eligibilityDigest)
|
|
437
|
+
fail("runtime eligibility changed during revalidation");
|
|
438
|
+
write(
|
|
439
|
+
receipt.binding.skillName,
|
|
440
|
+
previous,
|
|
441
|
+
"eligible",
|
|
442
|
+
current.binding,
|
|
443
|
+
"fresh evaluation accepted",
|
|
444
|
+
receipt,
|
|
445
|
+
);
|
|
446
|
+
return admission.assertEligible({ skill, context });
|
|
447
|
+
},
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
export function captureSkillRuntimeAdmission(value) {
|
|
452
|
+
if (!admissions.has(value))
|
|
453
|
+
fail("a branded Skill runtime admission port is required");
|
|
454
|
+
return value;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
export function bindSkillRuntimeAdmission(
|
|
458
|
+
loader,
|
|
459
|
+
admission,
|
|
460
|
+
{ required = false } = {},
|
|
461
|
+
) {
|
|
462
|
+
if (required) requiredLoaders.add(loader);
|
|
463
|
+
if (admission === null) return;
|
|
464
|
+
const captured = captureSkillRuntimeAdmission(admission);
|
|
465
|
+
if (loaderAdmissions.has(loader) && loaderAdmissions.get(loader) !== captured)
|
|
466
|
+
fail("loader runtime admission cannot be replaced");
|
|
467
|
+
loaderAdmissions.set(loader, captured);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export function hasSkillReleaseBinding(skill) {
|
|
471
|
+
return [
|
|
472
|
+
"evolutionRelease",
|
|
473
|
+
"releaseBinding",
|
|
474
|
+
"activeReleaseDigest",
|
|
475
|
+
"releaseDigest",
|
|
476
|
+
"runtimeManifest",
|
|
477
|
+
"runtimeManifestDigest",
|
|
478
|
+
].some((key) => skill?.[key] != null);
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
export function assertSkillRuntimeAdmission({
|
|
482
|
+
skill,
|
|
483
|
+
loader,
|
|
484
|
+
admission = null,
|
|
485
|
+
required = false,
|
|
486
|
+
expectedSkillName = null,
|
|
487
|
+
context = {},
|
|
488
|
+
}) {
|
|
489
|
+
if (
|
|
490
|
+
expectedSkillName !== null &&
|
|
491
|
+
(skill?.id || skill?.dirName) !== expectedSkillName
|
|
492
|
+
)
|
|
493
|
+
fail("materialization changed the admitted Skill identity");
|
|
494
|
+
const bound = loaderAdmissions.get(loader);
|
|
495
|
+
if (
|
|
496
|
+
bound &&
|
|
497
|
+
admission !== null &&
|
|
498
|
+
admission !== undefined &&
|
|
499
|
+
bound !== admission
|
|
500
|
+
)
|
|
501
|
+
fail("loader and execution runtime admission differ");
|
|
502
|
+
const port = bound ?? admission;
|
|
503
|
+
if (port !== null && port !== undefined)
|
|
504
|
+
return captureSkillRuntimeAdmission(port).assertEligible({
|
|
505
|
+
skill,
|
|
506
|
+
context,
|
|
507
|
+
});
|
|
508
|
+
if (required || requiredLoaders.has(loader) || hasSkillReleaseBinding(skill))
|
|
509
|
+
fail("governed Skill is missing its runtime admission port");
|
|
510
|
+
return Object.freeze({ governed: false, status: "unassessed" });
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
export function captureSkillRuntimeDependencies(options = {}, tenantId = null) {
|
|
514
|
+
const admission =
|
|
515
|
+
options.skillRuntimeAdmission == null
|
|
516
|
+
? null
|
|
517
|
+
: captureSkillRuntimeAdmission(options.skillRuntimeAdmission);
|
|
518
|
+
if (admission && tenantId && admission.tenantId !== tenantId)
|
|
519
|
+
fail("runtime admission tenant differs from the execution tenant");
|
|
520
|
+
return Object.freeze({
|
|
521
|
+
...(admission === null ? {} : { skillRuntimeAdmission: admission }),
|
|
522
|
+
...(options.skillRuntimeAdmissionRequired === true
|
|
523
|
+
? { skillRuntimeAdmissionRequired: true }
|
|
524
|
+
: {}),
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export function isSkillRuntimeAdmissionProof(value) {
|
|
529
|
+
return proofs.has(value);
|
|
530
|
+
}
|
|
@@ -4,8 +4,8 @@ import { types as utilTypes } from "node:util";
|
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
EVOLUTION_EVAL_AUTHORITY_DESCRIPTOR_SCHEMA,
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
isEvolutionEvalGate,
|
|
8
|
+
isEvolutionEvalReceiptVerifier,
|
|
9
9
|
computeEvolutionEvalContextDigest,
|
|
10
10
|
runEvolutionEvalGate,
|
|
11
11
|
verifyEvolutionEvalReceipt,
|
|
@@ -1707,13 +1707,13 @@ function captureCellRuntimes(value) {
|
|
|
1707
1707
|
const receiptVerifier = ownData(rawConfig, "receiptVerifier", label);
|
|
1708
1708
|
rejectProxy(gate, `${label}.gate`);
|
|
1709
1709
|
rejectProxy(receiptVerifier, `${label}.receiptVerifier`);
|
|
1710
|
-
if (!(gate
|
|
1710
|
+
if (!isEvolutionEvalGate(gate)) {
|
|
1711
1711
|
throw matrixError(
|
|
1712
1712
|
SKILL_TARGET_MATRIX_EVAL_INVALID_CODE,
|
|
1713
1713
|
`${label}.gate must be a branded EvolutionEvalGate`,
|
|
1714
1714
|
);
|
|
1715
1715
|
}
|
|
1716
|
-
if (!(receiptVerifier
|
|
1716
|
+
if (!isEvolutionEvalReceiptVerifier(receiptVerifier)) {
|
|
1717
1717
|
throw matrixError(
|
|
1718
1718
|
SKILL_TARGET_MATRIX_EVAL_INVALID_CODE,
|
|
1719
1719
|
`${label}.receiptVerifier must be a branded EvolutionEvalReceiptVerifier`,
|