chainlesschain 0.166.37 → 0.166.39
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/package.json +7 -2
- package/scripts/governed-learning-local-attestor-service.mjs +222 -0
- package/scripts/governed-learning-local-attestor-trust-approval-service.mjs +338 -0
- package/scripts/governed-learning-local-attestor-trust-operations-service.mjs +575 -0
- package/scripts/governed-learning-windows-secure-pipe-broker.ps1 +375 -0
- package/src/assets/web-panel/assets/{AIOps-B_Nt1Qe4.js → AIOps-qWUdiFr5.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CHQbie4X.js → ActionButton-B_f7go3E.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Bm9364Lw.js → Analytics-hSGFlSkB.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DTwlIh2v.js → AppLayout-CCYGgj71.js} +3 -3
- package/src/assets/web-panel/assets/{Artifacts-OibP0qB4.js → Artifacts-BdS1H9gq.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-B8Fwavkg.js → Audit-Cck9IebC.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-p1Vb2K2B.js → BackgroundAgents-DZzoM_QS.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BI3QT-wI.js → Backup-D8H_QtGu.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BW_VRWWu.js → BaseInput-CTsNF_pu.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CUEhDQfq.js → Chat-CcEiTYY8.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-C5UVXdVE.js → ChatBubbleRenderer-9BY1DPuc.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-URYsaaxv.js → Checkbox-BPB9NNJx.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DJAwC80a.js → Codegen-CKKMf7jD.js} +1 -1
- package/src/assets/web-panel/assets/{Col-DfRKFzc9.js → Col-DpSSB4Uu.js} +1 -1
- package/src/assets/web-panel/assets/{Community-GOkGHuly.js → Community-CfR6ikoH.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-CIMs13NC.js → Compact-CqnkGGjK.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BE-TQIxV.js → Compliance-9IzhdVQb.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CYmbJiWw.js → Cowork-eXsgH33N.js} +4 -4
- package/src/assets/web-panel/assets/{Cron-Be3OIWyM.js → Cron-DvkzHFRi.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-2xB2HS2D.js → Crosschain--az9d9f7.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B_lJO2yF.js → DID-_Eb4kpnJ.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DnVWqUER.js → Dashboard-aDVisdXj.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-C7ZJvHVa.js → Dropdown-oQ54XzS9.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DLevT-0F.js → EmailListRenderer-BUPdMau1.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BwhQ5BRU.js → FamilyGuardDashboard-DtQTOCQI.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BkGI-Xkq.js → Federation-Cpnb3Moe.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BgIIbMd7.js → FormItemContext-DmsrJkeU.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-qL-qN8Nb.js → GenericCardRenderer-CpFDYnh3.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BTzgrC4U.js → Git-HFG17p7Q.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-p28vdCN4.js → Governance-D5Z5c7N8.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Cqephrur.js → Inference-DH159h74.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-C3v5Q4Zp.js → KnowledgeGraph-DuL1pcJD.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-T6f0w32w.js → Logs-Gqn8hFsM.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-Dj5XPm3S.js → MarkdownRenderer-NHJaejHI.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-ClDsvHDH.js → Marketplace-BArcWifg.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-C4P-_snx.js → McpTools-Q1BfBSnd.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-BZZfG6y6.js → Memory-Cz8nRL7N.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DpIv_BLs.js → MobileBridge-CRuxLRJw.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Buz3NIQg.js → MobileProjects-B1CQIAGp.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-HS2PJB79.js → Mtc-CFhXZbPk.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-UmBrcU27.js → MtcAudit-C69LqcZ5.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-C00sXiZf.js → Multisig-y7yZeTTG.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Dj1ng_ph.js → NLProgramming-DgjhoWea.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C4LEVKlk.js → Notes-DRc2WTDh.js} +4 -4
- package/src/assets/web-panel/assets/{NotificationSettings-BWXwnekv.js → NotificationSettings-CLPx24yn.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-CZHfK8Nn.js → OrderTableRenderer-CMSNA4CO.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CFEtFPrV.js → Organization-Dm6LIyhZ.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-DSz4MJK1.js → Overflow-DP4DOYd-.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DyTEytwG.js → P2P-HFwvtFI1.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-B5QNGLVx.js → PdhVaultBrowser-D9gPfKRM.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-wEC_X7x4.js → Permissions-Bdtxniwh.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-If5GZlGZ.js → PersonalDataHub-Dgl2AbES.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-LB4gqqmX.js → Pipeline-DpZrzYwK.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-QVLhoxcN.js → Privacy-EQ551c0t.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-FaAbTYTo.js → ProjectInit-xUSeczsM.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-DhMeNA21.js → ProjectSettings-B66Sr_t8.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-5L4lkWAZ.js → Projects-B4zikj95.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DhZFp8fO.js → Providers-DjLbqQPh.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BZuJ7_xi.js → QrScannerModal-KVsAQCd_.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-TXddPYYb.js → QuickAsk-C4noJXu8.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DDuXIKYt.js → Recommend-Cn15clqY.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-CDrTXImv.js → RemoteSession-DdonMFwH.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-B2xKaKzt.js → Reputation-Bqe3NwWN.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DzAjWAOX.js → Row-CnxBgjkD.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CKH38BLF.js → RssFeed-CSRrgZyK.js} +2 -2
- package/src/assets/web-panel/assets/{Search-CuPqJYoQ.js → Search-DTUYUfFx.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DmAd2hxz.js → Security-BHExHVIm.js} +4 -4
- package/src/assets/web-panel/assets/{Services-Bt3nljnY.js → Services-B_IWqPes.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CP7RH093.js → Skeleton-C_oAtzmX.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DKNeMBTx.js → Skills-maJNokSL.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-CbpM8Nrd.js → Sla-CMM_ZsLH.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DTk-vTzF.js → SpeechSettings-D7w_oNwK.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DKiplwmc.js → SyncSettings-D0Zl3NIr.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-z-lOm8fx.js → Tasks-Bs0H0ctR.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-Rb-Q0DGX.js → Templates-C6T6oCpR.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-C2sqDUnR.js → Tenant-ByL-kAYO.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-DcyzskEE.js → Terminal-6JXNhc3b.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-lg0Eam7N.js → TimelineRenderer-KiuUtCsl.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-D9USIMIA.js → Tokens-C0TWTIER.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BQpaQJ5k.js → Trigger-DpC5aaJu.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-C-Mik04s.js → Trust-lqqflCwv.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DrnZ_o56.js → UkeySign-BYSlVfBc.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BDOsoZi0.js → VideoEditing-DX08oo_R.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-Ct_bleI7.js → Wallet-CcIFPvzL.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-B6b6FDao.js → WebAuthn-D8DfxfVT.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-ZUJMaIHr.js → WorkflowEditor-Csadpaln.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BII20OJy.js → chat-CewHWc_T.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DEsJRV3n.js → colors-B8at89r3.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DoDYAzN9.js → compact-item-v_gxtF5-.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-o_nofnVW.js → createContext-BOwFpJqA.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-DenB_kSS.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CAsABTHC.js → hasIn-DjHUzt7E.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeJSTcXw.js → index-1Tfwr_GA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVQSl1uY.js → index-5qmLo1us.js} +1 -1
- package/src/assets/web-panel/assets/index-B8bNwM9U.js +1 -0
- package/src/assets/web-panel/assets/{index-CQE-WMEU.js → index-BC20EQ7h.js} +1 -1
- package/src/assets/web-panel/assets/{index-DciLb_Ww.js → index-BGrmPk8T.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bqyg3PME.js → index-BPJ7uL2Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-DU2Rpx1m.js → index-BRNyE3Kb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CeWJqXNX.js → index-BVPsegMN.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWZNYecl.js → index-B_egGFcR.js} +3 -3
- package/src/assets/web-panel/assets/{index-TSwbtCYG.js → index-BdZLA7k9.js} +1 -1
- package/src/assets/web-panel/assets/{index-BrIIJ2s-.js → index-Bk_Te9OR.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5Fd4tdL.js → index-Bz8C8VXx.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4SfcwZA.js → index-C7MHbmwn.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bn2ZPUXO.js → index-CFL1Hewx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsoFTdA2.js → index-CV1SgaBd.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9hYHPhs.js → index-CXIPAeAB.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dgt1mKby.js → index-Ca8YZU2B.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRAA2McB.js → index-Caf9UjhG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcYbQoY7.js → index-Cb1uNDOv.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bycj011d.js → index-CquUCUzS.js} +1 -1
- package/src/assets/web-panel/assets/{index-BzMA6Ra3.js → index-CwHoF-TP.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbb34cAr.js → index-Cxk0mCoQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-BxT8yTwS.js → index-D3o-pacB.js} +1 -1
- package/src/assets/web-panel/assets/{index-DrsAF-Ar.js → index-DA3n0Y28.js} +1 -1
- package/src/assets/web-panel/assets/index-DC0cpgIP.js +1 -0
- package/src/assets/web-panel/assets/{index-B9Z75LfA.js → index-DRRK_8Eg.js} +1 -1
- package/src/assets/web-panel/assets/{index-kIyLNyoF.js → index-DUMvVGyf.js} +1 -1
- package/src/assets/web-panel/assets/{index-DQmX_-hk.js → index-DdHdbXpy.js} +1 -1
- package/src/assets/web-panel/assets/{index-tCeNfxv4.js → index-Ddw05Myq.js} +1 -1
- package/src/assets/web-panel/assets/{index-BDRh3v44.js → index-Dfrb3Prv.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bmwo5wQG.js → index-DiKaYIdo.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1YDdyQ1.js → index-DmZLZsyC.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dhnau6uw.js → index-FgUrhq_H.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf3sFEoE.js → index-Khw7wzVk.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0ApxOMw.js → index-San3zacc.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_CMB_wC.js → index-coOi37of.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnbnmRqg.js → index-hyeBuocp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DDQzBK3l.js → index-uk59xr0W.js} +1 -1
- package/src/assets/web-panel/assets/{index-CE2J04dA.js → index-wjvn8-9F.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CNjeeoKE.js → initDefaultProps-Id2dFdjh.js} +1 -1
- package/src/assets/web-panel/assets/{motion-CBT8IZDm.js → motion-DRxtwxng.js} +1 -1
- package/src/assets/web-panel/assets/{move-h1MOxjqv.js → move-BDYvdTb6.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-C_3pqNmn.js → mtc-parser-cz8LGI8Z.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CMUnPFDk.js → omit-DHJeh6tH.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-p8_c1xq0.js → pickAttrs-XJEQIp7e.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-D6O67r23.js → placementArrow-AFcf8lEn.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DquhepAK.js → responsiveObserve-CDEeBxs1.js} +1 -1
- package/src/assets/web-panel/assets/{slide-CZ-m6gmS.js → slide-CvbVfi6T.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-k9ejZFtd.js → statusUtils-DtCyuEnq.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-NX6_137R.js → styleChecker--UgmTsGY.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-bCqR70lP.js → useFlexGapSupport-D9i1as-Y.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-2l0vSqyY.js → useFs-CJx3zw01.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-1yccm4O7.js → usePersonalDataHub-ZsIKYdZv.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CxQzajDo.js → vnode-B2RGEQG4.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CrTKwFyb.js → zoom-ob-0px2z.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/evolution-attestor-trust.js +113 -0
- package/src/commands/evolution.js +2 -0
- package/src/commands/learning.js +34 -5
- package/src/data/changelog.json +26 -0
- package/src/lib/evolution/evolution-artifact-ports.js +21 -0
- package/src/lib/evolution/evolution-deployment-loader.js +56 -0
- package/src/lib/evolution/evolution-immutable-ledger-segment-store.js +812 -0
- package/src/lib/evolution/evolution-ledger-file-manifest-catalog.js +218 -0
- package/src/lib/evolution/evolution-ledger-manifest-catalog.js +472 -0
- package/src/lib/evolution/evolution-ledger-manifest-chain.js +997 -0
- package/src/lib/evolution/evolution-ledger-manifest-head-store.js +408 -0
- package/src/lib/evolution/evolution-ledger-manifest-witness-adapter.js +554 -0
- package/src/lib/evolution/evolution-ledger-v2-manifest-backend.js +460 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-ipc-endpoint.js +94 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-trust-approval-client.js +485 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-trust-ipc-capability.js +200 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-trust-ledger.js +1222 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operations-cli-host.js +802 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operations-client.js +445 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operations.js +1082 -0
- package/src/lib/evolution/governed-skill-synthesis-attestor-trust-operator-registry.js +1453 -0
- package/src/lib/evolution/governed-skill-synthesis-candidate-evaluator.js +147 -0
- package/src/lib/evolution/governed-skill-synthesis-cli-host.js +115 -0
- package/src/lib/evolution/governed-skill-synthesis-evaluation-ledger-adapter.js +715 -0
- package/src/lib/evolution/governed-skill-synthesis-external-attestor.js +499 -0
- package/src/lib/evolution/governed-skill-synthesis-model-evaluator.js +514 -0
- package/src/lib/evolution/governed-skill-synthesis-process-attestor-worker.mjs +208 -0
- package/src/lib/evolution/governed-skill-synthesis-process-attestor.js +557 -0
- package/src/lib/evolution/governed-skill-synthesis-process-grader-worker.mjs +143 -0
- package/src/lib/evolution/governed-skill-synthesis-process-grader.js +444 -0
- package/src/lib/evolution/governed-skill-synthesis-provider-chat.js +220 -0
- package/src/lib/evolution/governed-skill-synthesis-windows-secure-pipe-host.js +236 -0
- package/src/lib/hook-audit-store.js +68 -2
- package/src/lib/hooks-v2-runtime.js +52 -26
- package/src/lib/learning/skill-synthesizer.js +66 -5
- package/src/lib/remote-read-loop-guard.js +30 -3
- package/src/assets/web-panel/assets/devWarning-0tgDCszN.js +0 -1
- package/src/assets/web-panel/assets/index-CFF8XEFE.js +0 -1
- package/src/assets/web-panel/assets/index-DVUEISry.js +0 -1
|
@@ -0,0 +1,485 @@
|
|
|
1
|
+
import { createHash, createPublicKey, randomBytes, verify } from "node:crypto";
|
|
2
|
+
import net from "node:net";
|
|
3
|
+
import { types as utilTypes } from "node:util";
|
|
4
|
+
|
|
5
|
+
import { isGovernedSkillSynthesisAttestorIpcEndpoint } from "./governed-skill-synthesis-attestor-ipc-endpoint.js";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_SCHEMA,
|
|
9
|
+
digestGovernedSkillSynthesisAttestorTrustApproval,
|
|
10
|
+
governedSkillSynthesisAttestorTrustApprovalMessage,
|
|
11
|
+
} from "./governed-skill-synthesis-attestor-trust-operations.js";
|
|
12
|
+
import {
|
|
13
|
+
GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_OPERATOR_REGISTRY_APPROVAL_SCHEMA,
|
|
14
|
+
digestGovernedSkillSynthesisAttestorTrustOperatorRegistryApproval,
|
|
15
|
+
governedSkillSynthesisAttestorTrustOperatorRegistryApprovalMessage,
|
|
16
|
+
} from "./governed-skill-synthesis-attestor-trust-operator-registry.js";
|
|
17
|
+
import {
|
|
18
|
+
createGovernedSkillSynthesisAttestorTrustIpcAuthorization,
|
|
19
|
+
normalizeGovernedSkillSynthesisAttestorTrustIpcCapability,
|
|
20
|
+
} from "./governed-skill-synthesis-attestor-trust-ipc-capability.js";
|
|
21
|
+
|
|
22
|
+
export const GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_CLIENT_SCHEMA =
|
|
23
|
+
"chainlesschain.governed-skill-synthesis-attestor-trust-approval-client/v4";
|
|
24
|
+
export const GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_IPC_SCHEMA =
|
|
25
|
+
"chainlesschain.governed-skill-synthesis-attestor-trust-approval-ipc/v3";
|
|
26
|
+
export const GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_SERVICE_SCHEMA =
|
|
27
|
+
"chainlesschain.governed-skill-synthesis-attestor-trust-approval-service/v4";
|
|
28
|
+
|
|
29
|
+
const CLIENTS = new WeakSet();
|
|
30
|
+
const ID = /^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u;
|
|
31
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
32
|
+
const KEY_ID = /^key:ed25519:[a-f0-9]{64}$/u;
|
|
33
|
+
const MAX_FRAME_BYTES = 256 * 1024;
|
|
34
|
+
const FUTURE_SKEW_MS = 30 * 1000;
|
|
35
|
+
const MAX_REQUESTS = 256;
|
|
36
|
+
const CAPABILITY_SERVICE = "attestor-trust-approval";
|
|
37
|
+
const OPTION_KEYS = new Set([
|
|
38
|
+
"capabilityToken",
|
|
39
|
+
"descriptor",
|
|
40
|
+
"endpoint",
|
|
41
|
+
"now",
|
|
42
|
+
"timeoutMs",
|
|
43
|
+
]);
|
|
44
|
+
const DESCRIPTOR_KEYS = new Set([
|
|
45
|
+
"capability",
|
|
46
|
+
"keyId",
|
|
47
|
+
"operatorId",
|
|
48
|
+
"policyDigest",
|
|
49
|
+
"policyId",
|
|
50
|
+
"publicKeySpki",
|
|
51
|
+
"revision",
|
|
52
|
+
"schema",
|
|
53
|
+
"signerId",
|
|
54
|
+
"tenantId",
|
|
55
|
+
"transportSecurity",
|
|
56
|
+
]);
|
|
57
|
+
const TRANSPORT_SECURITY_KEYS = new Set([
|
|
58
|
+
"acl",
|
|
59
|
+
"aclDigest",
|
|
60
|
+
"peerIdentity",
|
|
61
|
+
"principalDigest",
|
|
62
|
+
"remoteClients",
|
|
63
|
+
]);
|
|
64
|
+
const APPROVAL_KEYS = new Set([
|
|
65
|
+
"approvedAt",
|
|
66
|
+
"attestation",
|
|
67
|
+
"automated",
|
|
68
|
+
"expiresAt",
|
|
69
|
+
"operatorId",
|
|
70
|
+
"policyDigest",
|
|
71
|
+
"receiptDigest",
|
|
72
|
+
"requestDigest",
|
|
73
|
+
"schema",
|
|
74
|
+
"tenantId",
|
|
75
|
+
]);
|
|
76
|
+
const ATTESTATION_KEYS = new Set(["algorithm", "keyId", "value"]);
|
|
77
|
+
|
|
78
|
+
function exact(value, keys, label) {
|
|
79
|
+
if (
|
|
80
|
+
!value ||
|
|
81
|
+
typeof value !== "object" ||
|
|
82
|
+
Array.isArray(value) ||
|
|
83
|
+
utilTypes.isProxy(value) ||
|
|
84
|
+
Object.getPrototypeOf(value) !== Object.prototype ||
|
|
85
|
+
Reflect.ownKeys(value).length !== keys.size ||
|
|
86
|
+
Reflect.ownKeys(value).some((key) => {
|
|
87
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
88
|
+
return (
|
|
89
|
+
typeof key !== "string" ||
|
|
90
|
+
!keys.has(key) ||
|
|
91
|
+
!descriptor ||
|
|
92
|
+
!("value" in descriptor) ||
|
|
93
|
+
descriptor.enumerable !== true
|
|
94
|
+
);
|
|
95
|
+
})
|
|
96
|
+
) {
|
|
97
|
+
throw new TypeError(`${label} is invalid`);
|
|
98
|
+
}
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function text(value, label, maximum = 4096) {
|
|
103
|
+
if (
|
|
104
|
+
typeof value !== "string" ||
|
|
105
|
+
value.trim() !== value ||
|
|
106
|
+
value.length < 1 ||
|
|
107
|
+
value.length > maximum ||
|
|
108
|
+
value.includes("\0")
|
|
109
|
+
) {
|
|
110
|
+
throw new TypeError(`${label} is invalid`);
|
|
111
|
+
}
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function timestamp(value, label) {
|
|
116
|
+
const milliseconds = Date.parse(value);
|
|
117
|
+
if (
|
|
118
|
+
typeof value !== "string" ||
|
|
119
|
+
!Number.isFinite(milliseconds) ||
|
|
120
|
+
new Date(milliseconds).toISOString() !== value
|
|
121
|
+
) {
|
|
122
|
+
throw new TypeError(`${label} is invalid`);
|
|
123
|
+
}
|
|
124
|
+
return milliseconds;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function endpoint(value) {
|
|
128
|
+
const normalized = text(value, "approval endpoint", 1024);
|
|
129
|
+
if (
|
|
130
|
+
!isGovernedSkillSynthesisAttestorIpcEndpoint(normalized, {
|
|
131
|
+
kind: "trust-approval",
|
|
132
|
+
})
|
|
133
|
+
) {
|
|
134
|
+
throw new TypeError("approval endpoint is not a dedicated local IPC path");
|
|
135
|
+
}
|
|
136
|
+
return normalized;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function normalizeDescriptor(value, capabilityToken, now) {
|
|
140
|
+
exact(value, DESCRIPTOR_KEYS, "approval service descriptor");
|
|
141
|
+
if (
|
|
142
|
+
value.schema !==
|
|
143
|
+
GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_SERVICE_SCHEMA ||
|
|
144
|
+
!ID.test(value.tenantId ?? "") ||
|
|
145
|
+
!ID.test(value.operatorId ?? "") ||
|
|
146
|
+
!ID.test(value.policyId ?? "") ||
|
|
147
|
+
!ID.test(value.signerId ?? "") ||
|
|
148
|
+
!KEY_ID.test(value.keyId ?? "") ||
|
|
149
|
+
!DIGEST.test(value.policyDigest ?? "") ||
|
|
150
|
+
!Number.isSafeInteger(value.revision) ||
|
|
151
|
+
value.revision < 1 ||
|
|
152
|
+
typeof value.publicKeySpki !== "string"
|
|
153
|
+
) {
|
|
154
|
+
throw new TypeError("approval service descriptor is invalid");
|
|
155
|
+
}
|
|
156
|
+
exact(
|
|
157
|
+
value.transportSecurity,
|
|
158
|
+
TRANSPORT_SECURITY_KEYS,
|
|
159
|
+
"approval transport security",
|
|
160
|
+
);
|
|
161
|
+
const expectedAcl =
|
|
162
|
+
process.platform === "win32"
|
|
163
|
+
? "protected-current-logon-dacl"
|
|
164
|
+
: "unix-owner-mode-0600";
|
|
165
|
+
const expectedPeerIdentity =
|
|
166
|
+
process.platform === "win32"
|
|
167
|
+
? "client-process-token-user-and-logon-sid"
|
|
168
|
+
: "capability-authenticated-client";
|
|
169
|
+
if (
|
|
170
|
+
value.transportSecurity.acl !== expectedAcl ||
|
|
171
|
+
value.transportSecurity.peerIdentity !== expectedPeerIdentity ||
|
|
172
|
+
value.transportSecurity.remoteClients !== false ||
|
|
173
|
+
!DIGEST.test(value.transportSecurity.aclDigest ?? "") ||
|
|
174
|
+
!DIGEST.test(value.transportSecurity.principalDigest ?? "")
|
|
175
|
+
) {
|
|
176
|
+
throw new TypeError("approval transport security is invalid");
|
|
177
|
+
}
|
|
178
|
+
let publicKey;
|
|
179
|
+
try {
|
|
180
|
+
const bytes = Buffer.from(value.publicKeySpki, "base64url");
|
|
181
|
+
if (bytes.toString("base64url") !== value.publicKeySpki) throw new Error();
|
|
182
|
+
publicKey = createPublicKey({ key: bytes, type: "spki", format: "der" });
|
|
183
|
+
if (publicKey.asymmetricKeyType !== "ed25519") throw new Error();
|
|
184
|
+
const keyId = `key:ed25519:${createHash("sha256")
|
|
185
|
+
.update(bytes)
|
|
186
|
+
.digest("hex")}`;
|
|
187
|
+
if (keyId !== value.keyId) throw new Error();
|
|
188
|
+
} catch {
|
|
189
|
+
throw new TypeError("approval service public key is invalid");
|
|
190
|
+
}
|
|
191
|
+
const capability = normalizeGovernedSkillSynthesisAttestorTrustIpcCapability({
|
|
192
|
+
capability: value.capability,
|
|
193
|
+
maxUsesLimit: MAX_REQUESTS,
|
|
194
|
+
now,
|
|
195
|
+
service: CAPABILITY_SERVICE,
|
|
196
|
+
token: capabilityToken,
|
|
197
|
+
});
|
|
198
|
+
const descriptor = structuredClone(value);
|
|
199
|
+
descriptor.capability = capability;
|
|
200
|
+
descriptor.transportSecurity = Object.freeze({
|
|
201
|
+
...descriptor.transportSecurity,
|
|
202
|
+
});
|
|
203
|
+
return {
|
|
204
|
+
descriptor: Object.freeze(descriptor),
|
|
205
|
+
publicKey,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function validateApproval({
|
|
210
|
+
value,
|
|
211
|
+
request,
|
|
212
|
+
service,
|
|
213
|
+
publicKey,
|
|
214
|
+
currentTime,
|
|
215
|
+
schema,
|
|
216
|
+
digestApproval,
|
|
217
|
+
approvalMessage,
|
|
218
|
+
policyFieldsRequired,
|
|
219
|
+
}) {
|
|
220
|
+
exact(value, APPROVAL_KEYS, "approval service result");
|
|
221
|
+
const attestation = exact(
|
|
222
|
+
value.attestation,
|
|
223
|
+
ATTESTATION_KEYS,
|
|
224
|
+
"approval service attestation",
|
|
225
|
+
);
|
|
226
|
+
const approvedAt = timestamp(value.approvedAt, "approval approvedAt");
|
|
227
|
+
const expiresAt = timestamp(value.expiresAt, "approval expiresAt");
|
|
228
|
+
if (
|
|
229
|
+
value.schema !== schema ||
|
|
230
|
+
value.tenantId !== service.tenantId ||
|
|
231
|
+
value.tenantId !== request?.tenantId ||
|
|
232
|
+
value.operatorId !== service.operatorId ||
|
|
233
|
+
value.policyDigest !== service.policyDigest ||
|
|
234
|
+
value.automated !== false ||
|
|
235
|
+
!DIGEST.test(value.requestDigest ?? "") ||
|
|
236
|
+
value.requestDigest !== request?.requestDigest ||
|
|
237
|
+
value.policyDigest !== request?.policyDigest ||
|
|
238
|
+
(policyFieldsRequired &&
|
|
239
|
+
(request?.policyId !== service.policyId ||
|
|
240
|
+
request?.revision !== service.revision)) ||
|
|
241
|
+
approvedAt <
|
|
242
|
+
timestamp(request?.requestedAt, "request requestedAt") - FUTURE_SKEW_MS ||
|
|
243
|
+
approvedAt > currentTime + FUTURE_SKEW_MS ||
|
|
244
|
+
approvedAt >= expiresAt ||
|
|
245
|
+
expiresAt !== timestamp(request?.expiresAt, "request expiresAt") ||
|
|
246
|
+
expiresAt <= currentTime ||
|
|
247
|
+
value.receiptDigest !== digestApproval(value) ||
|
|
248
|
+
attestation.algorithm !== "Ed25519" ||
|
|
249
|
+
attestation.keyId !== service.keyId ||
|
|
250
|
+
typeof attestation.value !== "string"
|
|
251
|
+
) {
|
|
252
|
+
throw new Error("approval service result is not exactly request-bound");
|
|
253
|
+
}
|
|
254
|
+
const signature = Buffer.from(attestation.value, "base64url");
|
|
255
|
+
if (
|
|
256
|
+
signature.length !== 64 ||
|
|
257
|
+
signature.toString("base64url") !== attestation.value ||
|
|
258
|
+
!verify(null, approvalMessage(value.receiptDigest), publicKey, signature)
|
|
259
|
+
) {
|
|
260
|
+
throw new Error("approval service result signature is invalid");
|
|
261
|
+
}
|
|
262
|
+
return Object.freeze(structuredClone(value));
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function callService({
|
|
266
|
+
target,
|
|
267
|
+
capability,
|
|
268
|
+
capabilityToken,
|
|
269
|
+
timeoutMs,
|
|
270
|
+
action,
|
|
271
|
+
payload,
|
|
272
|
+
now,
|
|
273
|
+
}) {
|
|
274
|
+
return new Promise((resolve, reject) => {
|
|
275
|
+
const currentTime = Number(now());
|
|
276
|
+
if (
|
|
277
|
+
!Number.isFinite(currentTime) ||
|
|
278
|
+
currentTime >= Date.parse(capability.expiresAt)
|
|
279
|
+
) {
|
|
280
|
+
const error = new Error("attestor trust approval capability expired");
|
|
281
|
+
error.code = "CC_ATTESTOR_TRUST_APPROVAL_CAPABILITY_EXPIRED";
|
|
282
|
+
reject(error);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const socket = net.connect(target);
|
|
286
|
+
const requestId = randomBytes(16).toString("hex");
|
|
287
|
+
const authorization =
|
|
288
|
+
createGovernedSkillSynthesisAttestorTrustIpcAuthorization({
|
|
289
|
+
action,
|
|
290
|
+
capabilityId: capability.id,
|
|
291
|
+
clientProcessId: process.pid,
|
|
292
|
+
payload,
|
|
293
|
+
requestId,
|
|
294
|
+
schema: GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_IPC_SCHEMA,
|
|
295
|
+
token: capabilityToken,
|
|
296
|
+
});
|
|
297
|
+
let carry = "";
|
|
298
|
+
let settled = false;
|
|
299
|
+
const finish = (error, value) => {
|
|
300
|
+
if (settled) return;
|
|
301
|
+
settled = true;
|
|
302
|
+
clearTimeout(timer);
|
|
303
|
+
socket.destroy();
|
|
304
|
+
if (error) reject(error);
|
|
305
|
+
else resolve(value);
|
|
306
|
+
};
|
|
307
|
+
const timer = setTimeout(() => {
|
|
308
|
+
const error = new Error(
|
|
309
|
+
`attestor trust approval service timed out after ${timeoutMs}ms`,
|
|
310
|
+
);
|
|
311
|
+
error.code = "CC_ATTESTOR_TRUST_APPROVAL_TIMEOUT";
|
|
312
|
+
finish(error);
|
|
313
|
+
}, timeoutMs);
|
|
314
|
+
timer.unref?.();
|
|
315
|
+
socket.once("connect", () => {
|
|
316
|
+
socket.write(
|
|
317
|
+
`${JSON.stringify({
|
|
318
|
+
schema: GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_IPC_SCHEMA,
|
|
319
|
+
requestId,
|
|
320
|
+
capabilityId: capability.id,
|
|
321
|
+
clientProcessId: process.pid,
|
|
322
|
+
authorization,
|
|
323
|
+
action,
|
|
324
|
+
payload,
|
|
325
|
+
})}\n`,
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
socket.on("data", (chunk) => {
|
|
329
|
+
carry += chunk.toString("utf8");
|
|
330
|
+
if (Buffer.byteLength(carry, "utf8") > MAX_FRAME_BYTES) {
|
|
331
|
+
finish(new Error("approval service response exceeded its byte limit"));
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
const newline = carry.indexOf("\n");
|
|
335
|
+
if (newline === -1) return;
|
|
336
|
+
if (carry.slice(newline + 1).trim().length > 0) {
|
|
337
|
+
finish(new Error("approval service returned multiple records"));
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
try {
|
|
341
|
+
const response = JSON.parse(
|
|
342
|
+
carry.slice(0, newline).replace(/\r$/u, ""),
|
|
343
|
+
);
|
|
344
|
+
exact(
|
|
345
|
+
response,
|
|
346
|
+
response?.ok === true
|
|
347
|
+
? new Set(["ok", "requestId", "result"])
|
|
348
|
+
: new Set(["code", "ok", "requestId"]),
|
|
349
|
+
"approval service response",
|
|
350
|
+
);
|
|
351
|
+
if (
|
|
352
|
+
response.requestId !== requestId ||
|
|
353
|
+
typeof response.ok !== "boolean"
|
|
354
|
+
) {
|
|
355
|
+
throw new Error("approval service response binding is invalid");
|
|
356
|
+
}
|
|
357
|
+
if (response.ok !== true) {
|
|
358
|
+
const error = new Error(
|
|
359
|
+
`attestor trust approval request denied: ${String(response.code ?? "unknown")}`,
|
|
360
|
+
);
|
|
361
|
+
error.code = "CC_ATTESTOR_TRUST_APPROVAL_DENIED";
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
364
|
+
finish(null, response.result);
|
|
365
|
+
} catch (error) {
|
|
366
|
+
finish(error);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
socket.once("error", (error) => finish(error));
|
|
370
|
+
socket.once("close", () => {
|
|
371
|
+
if (!settled)
|
|
372
|
+
finish(new Error("approval service closed without a response"));
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export function createGovernedSkillSynthesisAttestorTrustApprovalClient(
|
|
378
|
+
options = {},
|
|
379
|
+
) {
|
|
380
|
+
if (
|
|
381
|
+
!options ||
|
|
382
|
+
typeof options !== "object" ||
|
|
383
|
+
Array.isArray(options) ||
|
|
384
|
+
utilTypes.isProxy(options) ||
|
|
385
|
+
Object.getPrototypeOf(options) !== Object.prototype
|
|
386
|
+
) {
|
|
387
|
+
throw new TypeError("approval client options are invalid");
|
|
388
|
+
}
|
|
389
|
+
const normalizedOptions = Object.hasOwn(options, "now")
|
|
390
|
+
? options
|
|
391
|
+
: { ...options, now: Date.now };
|
|
392
|
+
exact(normalizedOptions, OPTION_KEYS, "approval client options");
|
|
393
|
+
const target = endpoint(normalizedOptions.endpoint);
|
|
394
|
+
const capabilityToken = text(
|
|
395
|
+
normalizedOptions.capabilityToken,
|
|
396
|
+
"approval capabilityToken",
|
|
397
|
+
);
|
|
398
|
+
if (capabilityToken.length < 32) {
|
|
399
|
+
throw new TypeError("approval capabilityToken is invalid");
|
|
400
|
+
}
|
|
401
|
+
if (
|
|
402
|
+
typeof normalizedOptions.now !== "function" ||
|
|
403
|
+
utilTypes.isProxy(normalizedOptions.now)
|
|
404
|
+
) {
|
|
405
|
+
throw new TypeError("approval client clock is invalid");
|
|
406
|
+
}
|
|
407
|
+
const currentTime = Number(normalizedOptions.now());
|
|
408
|
+
if (!Number.isFinite(currentTime)) {
|
|
409
|
+
throw new TypeError("approval client clock is invalid");
|
|
410
|
+
}
|
|
411
|
+
const normalized = normalizeDescriptor(
|
|
412
|
+
normalizedOptions.descriptor,
|
|
413
|
+
capabilityToken,
|
|
414
|
+
currentTime,
|
|
415
|
+
);
|
|
416
|
+
const timeoutMs = Number(normalizedOptions.timeoutMs);
|
|
417
|
+
if (
|
|
418
|
+
!Number.isSafeInteger(timeoutMs) ||
|
|
419
|
+
timeoutMs < 1_000 ||
|
|
420
|
+
timeoutMs > 30_000
|
|
421
|
+
) {
|
|
422
|
+
throw new TypeError("approval client timeoutMs is invalid");
|
|
423
|
+
}
|
|
424
|
+
const descriptor = Object.freeze({
|
|
425
|
+
schema: GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_CLIENT_SCHEMA,
|
|
426
|
+
isolation: "external-service",
|
|
427
|
+
transport: "local-ipc-v3",
|
|
428
|
+
endpointDigest: `sha256:${createHash("sha256")
|
|
429
|
+
.update(target, "utf8")
|
|
430
|
+
.digest("hex")}`,
|
|
431
|
+
requestTimeoutMs: timeoutMs,
|
|
432
|
+
service: normalized.descriptor,
|
|
433
|
+
});
|
|
434
|
+
const approve = async (action, request, approval) => {
|
|
435
|
+
const result = await callService({
|
|
436
|
+
target,
|
|
437
|
+
capabilityToken,
|
|
438
|
+
capability: normalized.descriptor.capability,
|
|
439
|
+
timeoutMs,
|
|
440
|
+
action,
|
|
441
|
+
payload: request,
|
|
442
|
+
now: normalizedOptions.now,
|
|
443
|
+
});
|
|
444
|
+
const currentTime = Number(normalizedOptions.now());
|
|
445
|
+
if (!Number.isFinite(currentTime)) {
|
|
446
|
+
throw new TypeError("approval client clock is invalid");
|
|
447
|
+
}
|
|
448
|
+
return validateApproval({
|
|
449
|
+
value: result,
|
|
450
|
+
request,
|
|
451
|
+
service: normalized.descriptor,
|
|
452
|
+
publicKey: normalized.publicKey,
|
|
453
|
+
currentTime,
|
|
454
|
+
...approval,
|
|
455
|
+
});
|
|
456
|
+
};
|
|
457
|
+
const client = Object.freeze({
|
|
458
|
+
descriptor,
|
|
459
|
+
approve(request) {
|
|
460
|
+
return approve("approve", request, {
|
|
461
|
+
schema: GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_APPROVAL_SCHEMA,
|
|
462
|
+
digestApproval: digestGovernedSkillSynthesisAttestorTrustApproval,
|
|
463
|
+
approvalMessage: governedSkillSynthesisAttestorTrustApprovalMessage,
|
|
464
|
+
policyFieldsRequired: false,
|
|
465
|
+
});
|
|
466
|
+
},
|
|
467
|
+
approveOperatorChange(request) {
|
|
468
|
+
return approve("operator-approve", request, {
|
|
469
|
+
schema:
|
|
470
|
+
GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_OPERATOR_REGISTRY_APPROVAL_SCHEMA,
|
|
471
|
+
digestApproval:
|
|
472
|
+
digestGovernedSkillSynthesisAttestorTrustOperatorRegistryApproval,
|
|
473
|
+
approvalMessage:
|
|
474
|
+
governedSkillSynthesisAttestorTrustOperatorRegistryApprovalMessage,
|
|
475
|
+
policyFieldsRequired: true,
|
|
476
|
+
});
|
|
477
|
+
},
|
|
478
|
+
});
|
|
479
|
+
CLIENTS.add(client);
|
|
480
|
+
return client;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
export function isGovernedSkillSynthesisAttestorTrustApprovalClient(value) {
|
|
484
|
+
return CLIENTS.has(value);
|
|
485
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { types as utilTypes } from "node:util";
|
|
3
|
+
|
|
4
|
+
export const GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_IPC_CAPABILITY_SCHEMA =
|
|
5
|
+
"chainlesschain.governed-skill-synthesis-attestor-trust-ipc-capability/v2";
|
|
6
|
+
|
|
7
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
8
|
+
const AUTHORIZATION = /^[A-Za-z0-9_-]{43}$/u;
|
|
9
|
+
const MAX_TTL_MS = 15 * 60 * 1000;
|
|
10
|
+
const FUTURE_SKEW_MS = 30 * 1000;
|
|
11
|
+
const CAPABILITY_KEYS = new Set(["expiresAt", "id", "issuedAt", "maxUses"]);
|
|
12
|
+
|
|
13
|
+
function canonical(value) {
|
|
14
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
15
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
16
|
+
return `{${Object.keys(value)
|
|
17
|
+
.sort()
|
|
18
|
+
.map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
|
|
19
|
+
.join(",")}}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function validToken(value) {
|
|
23
|
+
return (
|
|
24
|
+
typeof value === "string" &&
|
|
25
|
+
value.trim() === value &&
|
|
26
|
+
value.length >= 32 &&
|
|
27
|
+
value.length <= 4096 &&
|
|
28
|
+
!value.includes("\0")
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function timestamp(value, label) {
|
|
33
|
+
const milliseconds = Date.parse(value);
|
|
34
|
+
if (
|
|
35
|
+
typeof value !== "string" ||
|
|
36
|
+
!Number.isFinite(milliseconds) ||
|
|
37
|
+
new Date(milliseconds).toISOString() !== value
|
|
38
|
+
) {
|
|
39
|
+
throw new TypeError(`${label} is invalid`);
|
|
40
|
+
}
|
|
41
|
+
return milliseconds;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function safeEqual(left, right) {
|
|
45
|
+
const a = Buffer.from(String(left ?? ""));
|
|
46
|
+
const b = Buffer.from(String(right ?? ""));
|
|
47
|
+
return a.length > 0 && a.length === b.length && timingSafeEqual(a, b);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function capabilityMessage({
|
|
51
|
+
action,
|
|
52
|
+
capabilityId,
|
|
53
|
+
clientProcessId,
|
|
54
|
+
payload,
|
|
55
|
+
requestId,
|
|
56
|
+
schema,
|
|
57
|
+
}) {
|
|
58
|
+
return `${GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_IPC_CAPABILITY_SCHEMA}\0${canonical(
|
|
59
|
+
{ action, capabilityId, clientProcessId, payload, requestId, schema },
|
|
60
|
+
)}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function governedSkillSynthesisAttestorTrustIpcCapabilityId({
|
|
64
|
+
service,
|
|
65
|
+
token,
|
|
66
|
+
}) {
|
|
67
|
+
if (typeof service !== "string" || service.length < 1 || !validToken(token)) {
|
|
68
|
+
throw new TypeError("attestor trust IPC capability identity is invalid");
|
|
69
|
+
}
|
|
70
|
+
return `sha256:${createHash("sha256")
|
|
71
|
+
.update(GOVERNED_SKILL_SYNTHESIS_ATTESTOR_TRUST_IPC_CAPABILITY_SCHEMA)
|
|
72
|
+
.update("\0")
|
|
73
|
+
.update(service)
|
|
74
|
+
.update("\0")
|
|
75
|
+
.update(token)
|
|
76
|
+
.digest("hex")}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function createGovernedSkillSynthesisAttestorTrustIpcAuthorization({
|
|
80
|
+
action,
|
|
81
|
+
capabilityId,
|
|
82
|
+
clientProcessId,
|
|
83
|
+
payload,
|
|
84
|
+
requestId,
|
|
85
|
+
schema,
|
|
86
|
+
token,
|
|
87
|
+
}) {
|
|
88
|
+
if (
|
|
89
|
+
!DIGEST.test(capabilityId ?? "") ||
|
|
90
|
+
!Number.isSafeInteger(clientProcessId) ||
|
|
91
|
+
clientProcessId < 1 ||
|
|
92
|
+
!validToken(token)
|
|
93
|
+
) {
|
|
94
|
+
throw new TypeError("attestor trust IPC capability is invalid");
|
|
95
|
+
}
|
|
96
|
+
return createHmac("sha256", token)
|
|
97
|
+
.update(
|
|
98
|
+
capabilityMessage({
|
|
99
|
+
action,
|
|
100
|
+
capabilityId,
|
|
101
|
+
clientProcessId,
|
|
102
|
+
payload,
|
|
103
|
+
requestId,
|
|
104
|
+
schema,
|
|
105
|
+
}),
|
|
106
|
+
)
|
|
107
|
+
.digest("base64url");
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function verifyGovernedSkillSynthesisAttestorTrustIpcAuthorization({
|
|
111
|
+
authorization,
|
|
112
|
+
...input
|
|
113
|
+
}) {
|
|
114
|
+
if (!AUTHORIZATION.test(authorization ?? "")) return false;
|
|
115
|
+
let expected;
|
|
116
|
+
try {
|
|
117
|
+
expected = createGovernedSkillSynthesisAttestorTrustIpcAuthorization(input);
|
|
118
|
+
} catch {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
return safeEqual(authorization, expected);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function normalizeGovernedSkillSynthesisAttestorTrustIpcCapability({
|
|
125
|
+
capability,
|
|
126
|
+
maxUsesLimit,
|
|
127
|
+
now = Date.now(),
|
|
128
|
+
service,
|
|
129
|
+
token,
|
|
130
|
+
}) {
|
|
131
|
+
if (
|
|
132
|
+
!capability ||
|
|
133
|
+
typeof capability !== "object" ||
|
|
134
|
+
Array.isArray(capability) ||
|
|
135
|
+
utilTypes.isProxy(capability) ||
|
|
136
|
+
Object.getPrototypeOf(capability) !== Object.prototype
|
|
137
|
+
) {
|
|
138
|
+
throw new TypeError("attestor trust IPC capability descriptor is invalid");
|
|
139
|
+
}
|
|
140
|
+
const keys = Reflect.ownKeys(capability);
|
|
141
|
+
if (
|
|
142
|
+
keys.length !== CAPABILITY_KEYS.size ||
|
|
143
|
+
keys.some((key) => {
|
|
144
|
+
const descriptor = Object.getOwnPropertyDescriptor(capability, key);
|
|
145
|
+
return (
|
|
146
|
+
typeof key !== "string" ||
|
|
147
|
+
!CAPABILITY_KEYS.has(key) ||
|
|
148
|
+
!descriptor ||
|
|
149
|
+
!("value" in descriptor) ||
|
|
150
|
+
descriptor.enumerable !== true
|
|
151
|
+
);
|
|
152
|
+
}) ||
|
|
153
|
+
!DIGEST.test(capability.id ?? "") ||
|
|
154
|
+
!Number.isSafeInteger(capability.maxUses) ||
|
|
155
|
+
capability.maxUses < 1 ||
|
|
156
|
+
capability.maxUses > maxUsesLimit ||
|
|
157
|
+
!Number.isFinite(now)
|
|
158
|
+
) {
|
|
159
|
+
throw new TypeError("attestor trust IPC capability descriptor is invalid");
|
|
160
|
+
}
|
|
161
|
+
const issuedAt = timestamp(capability.issuedAt, "capability issuedAt");
|
|
162
|
+
const expiresAt = timestamp(capability.expiresAt, "capability expiresAt");
|
|
163
|
+
if (
|
|
164
|
+
issuedAt > now + FUTURE_SKEW_MS ||
|
|
165
|
+
expiresAt <= now ||
|
|
166
|
+
expiresAt <= issuedAt ||
|
|
167
|
+
expiresAt > issuedAt + MAX_TTL_MS ||
|
|
168
|
+
capability.id !==
|
|
169
|
+
governedSkillSynthesisAttestorTrustIpcCapabilityId({ service, token })
|
|
170
|
+
) {
|
|
171
|
+
throw new TypeError("attestor trust IPC capability is invalid or expired");
|
|
172
|
+
}
|
|
173
|
+
return Object.freeze({ ...capability });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function createGovernedSkillSynthesisAttestorTrustIpcCapability({
|
|
177
|
+
expiresAt,
|
|
178
|
+
issuedAt,
|
|
179
|
+
maxUses,
|
|
180
|
+
maxUsesLimit,
|
|
181
|
+
now = Date.now(),
|
|
182
|
+
service,
|
|
183
|
+
token,
|
|
184
|
+
}) {
|
|
185
|
+
return normalizeGovernedSkillSynthesisAttestorTrustIpcCapability({
|
|
186
|
+
capability: {
|
|
187
|
+
id: governedSkillSynthesisAttestorTrustIpcCapabilityId({
|
|
188
|
+
service,
|
|
189
|
+
token,
|
|
190
|
+
}),
|
|
191
|
+
issuedAt,
|
|
192
|
+
expiresAt,
|
|
193
|
+
maxUses,
|
|
194
|
+
},
|
|
195
|
+
maxUsesLimit,
|
|
196
|
+
now,
|
|
197
|
+
service,
|
|
198
|
+
token,
|
|
199
|
+
});
|
|
200
|
+
}
|