chainlesschain 0.166.65 → 0.166.69
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 +20 -12
- package/package.json +4 -4
- package/src/assets/web-panel/assets/{AIOps-Byz17CTN.js → AIOps-FhevRfL6.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-C5LiW2-J.js → ActionButton-rOeOykx5.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D1INcvZF.js → Analytics-BK_wYlfz.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DZzHO1VV.js → AppLayout-_2cCtZKV.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-WfYQL6Ia.js → Artifacts-D5MSvVzk.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DohBoGWO.js → Audit-yd-Ah-A3.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-Chtk-Hde.js → BackgroundAgents-yCaw_Gu_.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-B813PuMz.js → Backup-G3ADD4N-.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-DaDdWWgK.js → BaseInput-ByDhkLbF.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-D4pJ6oZ7.js → Chat-BMrc7qjz.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-nA7n0I6S.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Clo9TvO6.js → Checkbox-BHYgyZWA.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-uejLg8Ih.js → Codegen-DJfcy0jC.js} +1 -1
- package/src/assets/web-panel/assets/{Col-B7nbx-iJ.js → Col-C27zROxc.js} +1 -1
- package/src/assets/web-panel/assets/{Community-FEyjPK1j.js → Community-CuS5tq_1.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-B6Fk0Kn6.js → Compact-BrYJNe7Q.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BQG8goUl.js → Compliance-8hfahYHT.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-CbBeEfHp.js → Cowork-DdE0n2lp.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-DPzlFcEZ.js → Cron-CUq3aSiX.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-B8pWJrbg.js → Crosschain-BM4XSPWG.js} +1 -1
- package/src/assets/web-panel/assets/{DID-gGQHUlFN.js → DID-CdaBY57N.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-C2TMFHrn.js → Dashboard-Cwtd52So.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-BVPxGbll.js → Dropdown-BvlObh6U.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-CNPxs0hd.js → EmailListRenderer-e3fLhjnX.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-_XTiB7q1.js → EvolutionSettings-CTtk1Zo8.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-UyE3VWtI.js → FamilyGuardDashboard-BpPJUnCU.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-CLt6FHK-.js → Federation-vzjZ6_nQ.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CdNQPRPw.js → FormItemContext-DEDNLhkE.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BJ0AMhrh.js → GenericCardRenderer-DEl2Te5f.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CQnvMfOM.js → Git-BzsYQnCq.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-deYsHC-o.js → Governance-zxJs6Y8s.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-qaSck43z.js → Inference-5JUsrmF1.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-De0aJ3Ls.js → KnowledgeGraph-Br8b5Htz.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-ZtS98jCm.js → Logs-D-tubDMJ.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-In4itZX2.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-Byz3xCBN.js → Marketplace-s8MmWkS9.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DOZUUW6z.js → McpTools-Wu-WRg4M.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-C33wC2hA.js → Memory-B_i-eX9w.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-zZe-T_6M.js → MobileBridge-Ca64kjVx.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CRnUIume.js → MobileProjects-Cq9AFiO4.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-C1xlRVAN.js → Mtc-DKvGmG3y.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-D0U07bIi.js → MtcAudit-BVvWx8pF.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DF8uvV3h.js → Multisig-wqeJ2O9x.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-bBPGAFlt.js → NLProgramming-DX87ysYu.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BHAaOsgg.js → Notes-ChenGdu0.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-Cl0fG_rA.js → NotificationSettings-BZRa68-x.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BEPAs8Zv.js → OrderTableRenderer-DZ6xG1M6.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-BAxSwgk5.js → Organization-BWJp4VPX.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-D68KubAu.js → Overflow-BoM4bYt5.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-bhdT17zk.js → P2P-Cvi8YV09.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-DqaO6wgH.js → PdhVaultBrowser-CNVC1NIj.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-Bq8fvkak.js → Permissions-DNd1MRjW.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BYd2JEic.js → PersonalDataHub-DGSBYZ5-.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-Csg_ja69.js → Pipeline-DkcoGMBo.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-lwxwLj4M.js → Privacy-DltwvMAW.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BdBZkH8z.js → ProjectInit-ChYbpHg8.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-ClWgFy-K.js → ProjectSettings-B8FWiHTJ.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Bu-qj8N1.js → Projects-DuyhtSm4.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DEjxrxw3.js → Providers-Bo18Tx_6.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-eccy-8Vi.js → QrScannerModal-6W85KlsG.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Vx3uDvFg.js → QuickAsk-DznRUedP.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CfUivNps.js → Recommend-CQDN3_p-.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-BU4gk7GI.js → RemoteSession-CiJgokEj.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-CbPzdZ0C.js → Reputation-DexzGH7E.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CYLrgfKA.js → Row-BgZOIvSi.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-DbY1oyuv.js → RssFeed-BWIZJ_Jr.js} +3 -3
- package/src/assets/web-panel/assets/{Search-QeW41K5r.js → Search-B376EwWJ.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CJxf1kLZ.js → Security-92mUR5OD.js} +4 -4
- package/src/assets/web-panel/assets/{Services-CFO9ySZc.js → Services-ClSEAOHk.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CQFjeQN0.js → Skeleton-DVhLbv99.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-CLLB4INW.js → Skills-JTcXs_xI.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DxeLIJk0.js → Sla-DnKY9zy9.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-D4FA9KYI.js → SpeechSettings-GO1JefAH.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-C6NOkcQK.js → SyncSettings-jX5tB2St.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-LmVPWDfQ.js → Tasks-BxRBzhUc.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BdEfUoVB.js → Templates-CAVkbTG1.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-IUlESacN.js → Tenant-5Y7sHBkz.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B9pDe7sn.js → Terminal-CbbLShYb.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-ZCwB-Pki.js → TimelineRenderer-2HptWihL.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-4qk16LX1.js → Tokens-B-jGxzHl.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-jXNyargn.js → Trigger-9DGa90DT.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-D13PydtT.js → Trust-BSJEkEOO.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-yPgws6mS.js → UkeySign-C807So5R.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-B329WjpG.js → VideoEditing-ByiieAv-.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-T8VM-Ttm.js → Wallet-BixbIOUv.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-XuRibrpP.js → WebAuthn-z7akhor4.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-D1Gwz3YR.js → WorkflowEditor-KvijuUuR.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DjydtnT-.js → chat-BYKoh0YG.js} +1 -1
- package/src/assets/web-panel/assets/{colors-gFtBvPrr.js → colors-CLT8IYBt.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-CndxhGfx.js → compact-item-DlBIyYHF.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DnfGpd0L.js → createContext-5XmAnNLr.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BmcCIHwY.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CmT5hRVW.js → hasIn-rPdRhm7K.js} +1 -1
- package/src/assets/web-panel/assets/{index-DoBKSzqu.js → index-8un-eUDI.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGbKeg8G.js → index-B-0nAxf5.js} +1 -1
- package/src/assets/web-panel/assets/{index-DreYqebI.js → index-B1VfBUPB.js} +1 -1
- package/src/assets/web-panel/assets/{index-zQf599Uq.js → index-BBt2CSAx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BlTcxT_L.js → index-BDtlwjSr.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqpR0Des.js → index-BIRl2Ii5.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3HvYeA3.js → index-BgevTkUv.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0WFjxWs.js → index-Bve7Wsgf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNHdO6Jr.js → index-Bzd0sFkp.js} +1 -1
- package/src/assets/web-panel/assets/{index-DV2PR3Fa.js → index-C2sFDVb_.js} +1 -1
- package/src/assets/web-panel/assets/{index-D2d7358Y.js → index-CErvHCDe.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaEPE2DC.js → index-CM_a9spK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DKyuE_Y2.js → index-CY6TMc2m.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVM_w30N.js → index-ChlzaTV3.js} +1 -1
- package/src/assets/web-panel/assets/{index-CZLDbPTa.js → index-CsnbOKdI.js} +1 -1
- package/src/assets/web-panel/assets/{index-HHP1zzo7.js → index-D3-NL-x-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFif4Cev.js → index-D3f9Jzx2.js} +1 -1
- package/src/assets/web-panel/assets/{index-C14jryXi.js → index-DCDSycWo.js} +1 -1
- package/src/assets/web-panel/assets/{index-CB27echm.js → index-DIVrVGvf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BGlmPbl_.js → index-DI_tYFBe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BsRKmb6k.js → index-DPS4mWnI.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXNUTiW8.js → index-DTslLzPJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbpk75MO.js → index-DW8vozBS.js} +1 -1
- package/src/assets/web-panel/assets/index-DY8rmd6x.js +1 -0
- package/src/assets/web-panel/assets/{index-DjY-3sMA.js → index-DZiSMYoD.js} +3 -3
- package/src/assets/web-panel/assets/{index-DV6NrfJx.js → index-DZjGcIGU.js} +1 -1
- package/src/assets/web-panel/assets/{index-ktN-K1Tf.js → index-Dea32nOK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DjcR-CwS.js → index-Djd7uqwM.js} +1 -1
- package/src/assets/web-panel/assets/{index-CuOx4Pbe.js → index-Dntid6oj.js} +1 -1
- package/src/assets/web-panel/assets/{index-BW3nWiu0.js → index-DqZU4_7J.js} +1 -1
- package/src/assets/web-panel/assets/{index-C4Mqhmas.js → index-DuvweiCz.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRqz8TtI.js → index-DzExCCLS.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5na0B7G.js → index-LKT-Ol0A.js} +1 -1
- package/src/assets/web-panel/assets/{index-_-wGLtAg.js → index-akwXS-FF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CgMKElUh.js → index-b-rQCMkx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUlubR4l.js → index-eHbr3f5I.js} +1 -1
- package/src/assets/web-panel/assets/{index-D88-8bsB.js → index-kx6zDWew.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuAvYTmY.js → index-rRuCGdKW.js} +1 -1
- package/src/assets/web-panel/assets/index-sbwcUeRS.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-KV3V-PNH.js → initDefaultProps-a8411LiK.js} +1 -1
- package/src/assets/web-panel/assets/{motion-PFGQg7_X.js → motion-oVcQdpCm.js} +1 -1
- package/src/assets/web-panel/assets/{move-Dnl79wq4.js → move-B-eyzzzL.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-Bwl5JH9V.js → mtc-parser-BCYIxuG7.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DCcTtM1l.js → omit-DuFtWiYh.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Cl6BjjDf.js → pickAttrs-CVAoJhGu.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-fdqhyo42.js → placementArrow-Y2iub2bO.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-DYQpmcDW.js → responsiveObserve-BHenWIVD.js} +1 -1
- package/src/assets/web-panel/assets/{slide-C4l-VfO4.js → slide-CKrMaL29.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-DYDw_dyZ.js → statusUtils-w8eb_1da.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BEsubSMu.js → styleChecker-CCVi_Ww3.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-Cj82ggQ_.js → useFlexGapSupport-BsmR_q0r.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-B7L1eJ0V.js → useFs-a8GMBjnc.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DVlJVD4d.js → usePersonalDataHub-BMUYSPn-.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BBAbRN_Y.js → vnode-DL2pI31V.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BYn48q-I.js → zoom-Cbi8fISi.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/data/changelog.json +33 -7
- package/src/lib/dependency-install-policy.js +1 -1
- package/src/lib/evolution/browser-download-action-authority.js +747 -0
- package/src/lib/evolution/browser-download-artifact-disposal-authority.js +436 -0
- package/src/lib/evolution/browser-filesystem-quarantine-custody.js +2453 -0
- package/src/lib/evolution/browser-filesystem-quarantine-disposal.js +36 -0
- package/src/lib/evolution/browser-keyboard-action-authority.js +560 -0
- package/src/lib/evolution/browser-navigation-action-authority.js +546 -0
- package/src/lib/evolution/browser-quarantine-lock-maintenance-authority.js +573 -0
- package/src/lib/evolution/browser-quarantine-operator-revocation-authority.js +442 -0
- package/src/lib/evolution/browser-quarantine-retention-authority.js +503 -0
- package/src/lib/evolution/browser-quarantine-retention-scheduler.js +207 -0
- package/src/lib/evolution/browser-quarantined-download-executor.js +525 -0
- package/src/lib/evolution/browser-tab-open-action-authority.js +491 -0
- package/src/lib/evolution/browser-vision-action-authority.js +444 -0
- package/src/lib/evolution/browser-vision-observation-authority.js +304 -0
- package/src/lib/evolution/evolution-deployment-loader.js +241 -1
- package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +5 -0
- package/src/lib/evolution/evolution-eval-gate.js +2 -1
- package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +71 -9
- package/src/lib/evolution/evolution-eval-process-supervisor.js +276 -9
- package/src/lib/evolution/evolution-workbench-metrics.js +81 -21
- package/src/lib/evolution/pm-exploration-benchmark.js +747 -0
- package/src/lib/evolution/pm-exploration-budget-executor.js +106 -9
- package/src/lib/evolution/pm-exploration-egress-authority.js +382 -0
- package/src/lib/evolution/pm-exploration-evidence-bundle.js +149 -44
- package/src/lib/evolution/pm-exploration-execution-host.js +1254 -8
- package/src/lib/evolution/pm-exploration-process-grader.js +458 -0
- package/src/lib/evolution/pm-exploration-process-reviewer.js +456 -0
- package/src/lib/evolution/pm-exploration-process-runner.js +500 -0
- package/src/lib/evolution/pm-exploration-receipts.js +211 -11
- package/src/lib/evolution/pm-exploration-recovery-snapshot-store.js +465 -46
- package/src/lib/evolution/pm-exploration-transition-committer.js +185 -34
- package/src/lib/evolution/skill-outcome-index-authority.js +7 -3
- package/src/lib/evolution/skill-writer-inventory-manifest.js +0 -39
- package/src/lib/evolution/volcengine-function-execution-authority.js +2949 -0
- package/src/lib/evolution/volcengine-function-process-executor.js +615 -0
- package/src/lib/evolution/volcengine-function-replay-store.js +836 -0
- package/src/lib/evolution/volcengine-function-revocation-status-floor-store.js +480 -0
- package/src/lib/governance-coverage.js +1 -1
- package/src/lib/headless-manifest.js +1 -1
- package/src/lib/protocol-replay.js +1 -1
- package/src/lib/skill-outcome-transcript-authority.js +45 -5
- package/src/runtime/agent-core.js +17 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-Cf3LLgDc.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-CTsYo9NN.js +0 -1
- package/src/assets/web-panel/assets/devWarning-D60SbiD-.js +0 -1
- package/src/assets/web-panel/assets/index-C0yR4_7h.js +0 -1
- package/src/assets/web-panel/assets/index-D4xuvo03.js +0 -1
|
@@ -1,14 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { createInterface } from "node:readline";
|
|
2
|
+
|
|
3
|
+
const lines = createInterface({ input: process.stdin, crlfDelay: Infinity });
|
|
4
|
+
const iterator = lines[Symbol.asyncIterator]();
|
|
5
|
+
const first = await iterator.next();
|
|
6
|
+
if (first.done || Buffer.byteLength(first.value) > 1024 * 1024)
|
|
7
|
+
throw new Error("evaluation process input exceeds 1 MiB");
|
|
8
|
+
const request = JSON.parse(first.value);
|
|
8
9
|
const moduleUrl = new URL(request.moduleUrl);
|
|
9
10
|
const implementation = await import(moduleUrl.href);
|
|
10
11
|
const handler = implementation[request.exportName];
|
|
11
12
|
if (typeof handler !== "function")
|
|
12
13
|
throw new Error("evaluation process export is unavailable");
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
if (request.protocol !== "chainlesschain.evolution-process-broker/v1") {
|
|
16
|
+
const extra = await iterator.next();
|
|
17
|
+
if (!extra.done) throw new Error("evaluation process received extra input");
|
|
18
|
+
const value = await handler(request.payload);
|
|
19
|
+
process.stdout.write(`${JSON.stringify({ ok: true, value })}\n`);
|
|
20
|
+
} else {
|
|
21
|
+
let sequence = 0;
|
|
22
|
+
const pending = new Map();
|
|
23
|
+
const readResponses = (async () => {
|
|
24
|
+
for await (const line of iterator) {
|
|
25
|
+
if (Buffer.byteLength(line) > 1024 * 1024)
|
|
26
|
+
throw new Error("evaluation broker response exceeds 1 MiB");
|
|
27
|
+
const message = JSON.parse(line);
|
|
28
|
+
const waiter = pending.get(message?.requestId);
|
|
29
|
+
if (
|
|
30
|
+
!waiter ||
|
|
31
|
+
message?.type !== "broker-response" ||
|
|
32
|
+
typeof message.ok !== "boolean" ||
|
|
33
|
+
Object.keys(message).some(
|
|
34
|
+
(key) => !["type", "requestId", "ok", "value", "error"].includes(key),
|
|
35
|
+
)
|
|
36
|
+
) {
|
|
37
|
+
throw new Error("evaluation broker response is invalid");
|
|
38
|
+
}
|
|
39
|
+
pending.delete(message.requestId);
|
|
40
|
+
if (message.ok) waiter.resolve(message.value);
|
|
41
|
+
else waiter.reject(new Error("parent broker rejected the operation"));
|
|
42
|
+
}
|
|
43
|
+
if (pending.size > 0)
|
|
44
|
+
throw new Error("evaluation broker closed with pending operations");
|
|
45
|
+
})();
|
|
46
|
+
|
|
47
|
+
const call = (operation, input) =>
|
|
48
|
+
new Promise((resolve, reject) => {
|
|
49
|
+
sequence += 1;
|
|
50
|
+
const requestId = `broker-${sequence}`;
|
|
51
|
+
pending.set(requestId, { resolve, reject });
|
|
52
|
+
process.stdout.write(
|
|
53
|
+
`${JSON.stringify({
|
|
54
|
+
type: "broker-request",
|
|
55
|
+
requestId,
|
|
56
|
+
operation,
|
|
57
|
+
input,
|
|
58
|
+
})}\n`,
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
const runtime = Object.freeze({
|
|
62
|
+
recordTokens: (count) => call("record-tokens", { count }),
|
|
63
|
+
invokeTool: (toolId, input) => call("invoke-tool", { toolId, input }),
|
|
64
|
+
retrieveMemory: (input) => call("retrieve-memory", { input }),
|
|
65
|
+
invokeModel: (input) => call("invoke-model", { input }),
|
|
66
|
+
});
|
|
67
|
+
const value = await handler(request.payload, runtime);
|
|
68
|
+
if (pending.size > 0)
|
|
69
|
+
throw new Error(
|
|
70
|
+
"evaluation target returned with unsettled broker requests",
|
|
71
|
+
);
|
|
72
|
+
process.stdout.write(`${JSON.stringify({ type: "result", value })}\n`, () =>
|
|
73
|
+
process.exit(0),
|
|
74
|
+
);
|
|
75
|
+
await readResponses;
|
|
76
|
+
}
|
|
@@ -3,6 +3,7 @@ import { lstat, readFile, realpath } from "node:fs/promises";
|
|
|
3
3
|
import { lstatSync, readFileSync, realpathSync } from "node:fs";
|
|
4
4
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { isProxy } from "node:util/types";
|
|
6
7
|
|
|
7
8
|
import executionBroker from "../process-execution-broker/index.js";
|
|
8
9
|
import { isEvolutionEvalChildEvidenceStore } from "./evolution-eval-child-evidence-ledger-adapter.js";
|
|
@@ -29,6 +30,7 @@ const MIN_MEMORY_LIMIT_MB = 32;
|
|
|
29
30
|
const MAX_MEMORY_LIMIT_MB = 1024;
|
|
30
31
|
const MAX_PERMISSION_PATHS = 32;
|
|
31
32
|
const PROCESS_SUPERVISORS = new WeakSet();
|
|
33
|
+
const PROCESS_RUNTIME_BROKERS = new WeakMap();
|
|
32
34
|
|
|
33
35
|
function canonical(value) {
|
|
34
36
|
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
@@ -127,14 +129,23 @@ function sandboxPolicy(value) {
|
|
|
127
129
|
if (paths === undefined) return Object.freeze([]);
|
|
128
130
|
if (!Array.isArray(paths) || paths.length > MAX_PERMISSION_PATHS)
|
|
129
131
|
throw new TypeError(`${label} must be a bounded array`);
|
|
130
|
-
const
|
|
132
|
+
const requested = paths.map((path) => {
|
|
131
133
|
if (typeof path !== "string" || !isAbsolute(path))
|
|
132
134
|
throw new TypeError(`${label} paths must be absolute`);
|
|
133
135
|
return resolve(path);
|
|
134
136
|
});
|
|
135
|
-
if (new Set(
|
|
137
|
+
if (new Set(requested).size !== requested.length)
|
|
136
138
|
throw new TypeError(`${label} paths must be unique`);
|
|
137
|
-
|
|
139
|
+
const normalized = requested.flatMap((absolute) => {
|
|
140
|
+
try {
|
|
141
|
+
const physical = realpathSync(absolute);
|
|
142
|
+
return physical === absolute ? [absolute] : [absolute, physical];
|
|
143
|
+
} catch (cause) {
|
|
144
|
+
if (cause?.code === "ENOENT") return [absolute];
|
|
145
|
+
throw new Error(`${label} path could not be resolved`, { cause });
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
return Object.freeze([...new Set(normalized)]);
|
|
138
149
|
};
|
|
139
150
|
const memoryLimitMb = value.memoryLimitMb ?? DEFAULT_MEMORY_LIMIT_MB;
|
|
140
151
|
if (
|
|
@@ -237,6 +248,253 @@ function processResult(child, input) {
|
|
|
237
248
|
});
|
|
238
249
|
}
|
|
239
250
|
|
|
251
|
+
function writeBrokerMessage(child, value) {
|
|
252
|
+
const encoded = `${JSON.stringify(value)}\n`;
|
|
253
|
+
if (Buffer.byteLength(encoded) > MAX_OUTPUT_BYTES)
|
|
254
|
+
return Promise.reject(new Error("evaluation broker message exceeds 1 MiB"));
|
|
255
|
+
return new Promise((resolveWrite, reject) => {
|
|
256
|
+
if (child.stdin.destroyed || child.stdin.writableEnded) {
|
|
257
|
+
reject(new Error("evaluation broker input is closed"));
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
child.stdin.write(encoded, (error) => {
|
|
261
|
+
if (error) reject(error);
|
|
262
|
+
else resolveWrite();
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function processBrokeredResult(child, input, brokerValue) {
|
|
268
|
+
const broker = PROCESS_RUNTIME_BROKERS.get(brokerValue);
|
|
269
|
+
if (!broker)
|
|
270
|
+
return Promise.reject(
|
|
271
|
+
new TypeError("a branded evaluation process runtime broker is required"),
|
|
272
|
+
);
|
|
273
|
+
return new Promise((resolveResult, reject) => {
|
|
274
|
+
let stdoutBuffer = "";
|
|
275
|
+
let stdoutBytes = 0;
|
|
276
|
+
let stderr = "";
|
|
277
|
+
let settled = false;
|
|
278
|
+
let completionError = null;
|
|
279
|
+
let resultSeen = false;
|
|
280
|
+
let resultValue;
|
|
281
|
+
let requestCount = 0;
|
|
282
|
+
const requestIds = new Set();
|
|
283
|
+
let messages = Promise.resolve();
|
|
284
|
+
const rejectOnce = (error) => {
|
|
285
|
+
if (settled) return;
|
|
286
|
+
settled = true;
|
|
287
|
+
reject(error);
|
|
288
|
+
};
|
|
289
|
+
const handleMessage = async (line) => {
|
|
290
|
+
if (!line || Buffer.byteLength(line) > MAX_OUTPUT_BYTES)
|
|
291
|
+
throw new Error("evaluation broker record exceeds 1 MiB");
|
|
292
|
+
const message = JSON.parse(line);
|
|
293
|
+
if (message?.type === "result") {
|
|
294
|
+
if (
|
|
295
|
+
resultSeen ||
|
|
296
|
+
Object.keys(message).length !== 2 ||
|
|
297
|
+
requestIds.size !== 0
|
|
298
|
+
) {
|
|
299
|
+
throw new Error("evaluation broker result is invalid or premature");
|
|
300
|
+
}
|
|
301
|
+
resultSeen = true;
|
|
302
|
+
resultValue = jsonClone(message.value, "evaluation target result");
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (
|
|
306
|
+
resultSeen ||
|
|
307
|
+
message?.type !== "broker-request" ||
|
|
308
|
+
typeof message.requestId !== "string" ||
|
|
309
|
+
!/^broker-[1-9][0-9]*$/u.test(message.requestId) ||
|
|
310
|
+
![
|
|
311
|
+
"record-tokens",
|
|
312
|
+
"invoke-tool",
|
|
313
|
+
"retrieve-memory",
|
|
314
|
+
"invoke-model",
|
|
315
|
+
].includes(message.operation) ||
|
|
316
|
+
!message.input ||
|
|
317
|
+
typeof message.input !== "object" ||
|
|
318
|
+
Array.isArray(message.input) ||
|
|
319
|
+
Object.keys(message).length !== 4 ||
|
|
320
|
+
requestIds.has(message.requestId) ||
|
|
321
|
+
requestCount >= 512
|
|
322
|
+
) {
|
|
323
|
+
throw new Error("evaluation broker request is invalid");
|
|
324
|
+
}
|
|
325
|
+
requestCount += 1;
|
|
326
|
+
requestIds.add(message.requestId);
|
|
327
|
+
try {
|
|
328
|
+
let value;
|
|
329
|
+
if (message.operation === "record-tokens") {
|
|
330
|
+
if (
|
|
331
|
+
Object.keys(message.input).length !== 1 ||
|
|
332
|
+
!Number.isSafeInteger(message.input.count) ||
|
|
333
|
+
message.input.count < 0
|
|
334
|
+
) {
|
|
335
|
+
throw new TypeError("broker token count is invalid");
|
|
336
|
+
}
|
|
337
|
+
value = await broker.recordTokens(message.input.count);
|
|
338
|
+
} else if (message.operation === "invoke-tool") {
|
|
339
|
+
if (
|
|
340
|
+
Object.keys(message.input).length !== 2 ||
|
|
341
|
+
typeof message.input.toolId !== "string"
|
|
342
|
+
) {
|
|
343
|
+
throw new TypeError("broker tool request is invalid");
|
|
344
|
+
}
|
|
345
|
+
value = await broker.invokeTool(
|
|
346
|
+
message.input.toolId,
|
|
347
|
+
jsonClone(message.input.input, "evaluation broker tool input"),
|
|
348
|
+
);
|
|
349
|
+
} else {
|
|
350
|
+
if (Object.keys(message.input).length !== 1) {
|
|
351
|
+
throw new TypeError("broker egress request is invalid");
|
|
352
|
+
}
|
|
353
|
+
const inputValue = jsonClone(
|
|
354
|
+
message.input.input,
|
|
355
|
+
"evaluation broker egress input",
|
|
356
|
+
);
|
|
357
|
+
const port =
|
|
358
|
+
message.operation === "retrieve-memory"
|
|
359
|
+
? broker.retrieveMemory
|
|
360
|
+
: broker.invokeModel;
|
|
361
|
+
if (port === null)
|
|
362
|
+
throw new Error("evaluation broker egress port is unavailable");
|
|
363
|
+
value = await port(inputValue);
|
|
364
|
+
}
|
|
365
|
+
await writeBrokerMessage(child, {
|
|
366
|
+
type: "broker-response",
|
|
367
|
+
requestId: message.requestId,
|
|
368
|
+
ok: true,
|
|
369
|
+
value: jsonClone(value, "evaluation broker result"),
|
|
370
|
+
});
|
|
371
|
+
} catch {
|
|
372
|
+
await writeBrokerMessage(child, {
|
|
373
|
+
type: "broker-response",
|
|
374
|
+
requestId: message.requestId,
|
|
375
|
+
ok: false,
|
|
376
|
+
error: "operation-rejected",
|
|
377
|
+
}).catch(() => {});
|
|
378
|
+
} finally {
|
|
379
|
+
requestIds.delete(message.requestId);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
child.stdout.on("data", (chunk) => {
|
|
383
|
+
const text = chunk.toString("utf8");
|
|
384
|
+
stdoutBytes += Buffer.byteLength(text);
|
|
385
|
+
if (!completionError && stdoutBytes > MAX_OUTPUT_BYTES) {
|
|
386
|
+
completionError = new Error("evaluation target stdout exceeds 1 MiB");
|
|
387
|
+
child.kill("SIGKILL");
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
stdoutBuffer += text;
|
|
391
|
+
for (;;) {
|
|
392
|
+
const newline = stdoutBuffer.indexOf("\n");
|
|
393
|
+
if (newline < 0) break;
|
|
394
|
+
const line = stdoutBuffer.slice(0, newline);
|
|
395
|
+
stdoutBuffer = stdoutBuffer.slice(newline + 1);
|
|
396
|
+
messages = messages.then(() => handleMessage(line));
|
|
397
|
+
}
|
|
398
|
+
messages.catch((cause) => {
|
|
399
|
+
completionError ??= new Error("evaluation broker protocol failed", {
|
|
400
|
+
cause,
|
|
401
|
+
});
|
|
402
|
+
child.kill("SIGKILL");
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
child.stderr.on("data", (chunk) => {
|
|
406
|
+
stderr += chunk.toString("utf8");
|
|
407
|
+
if (!completionError && Buffer.byteLength(stderr) > MAX_OUTPUT_BYTES) {
|
|
408
|
+
completionError = new Error("evaluation target stderr exceeds 1 MiB");
|
|
409
|
+
child.kill("SIGKILL");
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
child.once("error", rejectOnce);
|
|
413
|
+
child.once("close", (code, signal) => {
|
|
414
|
+
messages.then(
|
|
415
|
+
() => {
|
|
416
|
+
if (settled) return;
|
|
417
|
+
if (completionError) {
|
|
418
|
+
rejectOnce(completionError);
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
if (code !== 0) {
|
|
422
|
+
rejectOnce(
|
|
423
|
+
new Error(
|
|
424
|
+
`evaluation target exited ${code ?? "null"}/${signal ?? "none"}: ${stderr.slice(0, 512)}`,
|
|
425
|
+
),
|
|
426
|
+
);
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
if (stdoutBuffer.length !== 0 || !resultSeen) {
|
|
430
|
+
rejectOnce(new Error("evaluation broker result is incomplete"));
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
settled = true;
|
|
434
|
+
resolveResult(resultValue);
|
|
435
|
+
},
|
|
436
|
+
(cause) =>
|
|
437
|
+
rejectOnce(
|
|
438
|
+
new Error("evaluation broker response is invalid", { cause }),
|
|
439
|
+
),
|
|
440
|
+
);
|
|
441
|
+
});
|
|
442
|
+
child.stdin.once("error", (error) => {
|
|
443
|
+
completionError ??= error;
|
|
444
|
+
});
|
|
445
|
+
writeBrokerMessage(child, {
|
|
446
|
+
...input,
|
|
447
|
+
protocol: "chainlesschain.evolution-process-broker/v1",
|
|
448
|
+
}).catch((cause) => {
|
|
449
|
+
completionError ??= cause;
|
|
450
|
+
child.kill("SIGKILL");
|
|
451
|
+
});
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export function createEvolutionEvalProcessRuntimeBroker(options = {}) {
|
|
456
|
+
const plain =
|
|
457
|
+
!options ||
|
|
458
|
+
typeof options !== "object" ||
|
|
459
|
+
Array.isArray(options) ||
|
|
460
|
+
isProxy(options) ||
|
|
461
|
+
Object.getPrototypeOf(options) !== Object.prototype;
|
|
462
|
+
if (plain)
|
|
463
|
+
throw new TypeError("evaluation process runtime broker ports are invalid");
|
|
464
|
+
const hasMemory = Object.hasOwn(options, "retrieveMemory");
|
|
465
|
+
const hasModel = Object.hasOwn(options, "invokeModel");
|
|
466
|
+
if (
|
|
467
|
+
Reflect.ownKeys(options).length !==
|
|
468
|
+
2 + Number(hasMemory) + Number(hasModel) ||
|
|
469
|
+
!Object.hasOwn(options, "recordTokens") ||
|
|
470
|
+
!Object.hasOwn(options, "invokeTool") ||
|
|
471
|
+
typeof options.recordTokens !== "function" ||
|
|
472
|
+
isProxy(options.recordTokens) ||
|
|
473
|
+
typeof options.invokeTool !== "function" ||
|
|
474
|
+
isProxy(options.invokeTool) ||
|
|
475
|
+
(hasMemory &&
|
|
476
|
+
(typeof options.retrieveMemory !== "function" ||
|
|
477
|
+
isProxy(options.retrieveMemory))) ||
|
|
478
|
+
(hasModel &&
|
|
479
|
+
(typeof options.invokeModel !== "function" ||
|
|
480
|
+
isProxy(options.invokeModel)))
|
|
481
|
+
) {
|
|
482
|
+
throw new TypeError("evaluation process runtime broker ports are invalid");
|
|
483
|
+
}
|
|
484
|
+
const broker = Object.freeze({});
|
|
485
|
+
PROCESS_RUNTIME_BROKERS.set(broker, {
|
|
486
|
+
recordTokens: options.recordTokens,
|
|
487
|
+
invokeTool: options.invokeTool,
|
|
488
|
+
retrieveMemory: hasMemory ? options.retrieveMemory : null,
|
|
489
|
+
invokeModel: hasModel ? options.invokeModel : null,
|
|
490
|
+
});
|
|
491
|
+
return broker;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export function isEvolutionEvalProcessRuntimeBroker(value) {
|
|
495
|
+
return PROCESS_RUNTIME_BROKERS.has(value);
|
|
496
|
+
}
|
|
497
|
+
|
|
240
498
|
export function createEvolutionEvalProcessSupervisor({
|
|
241
499
|
targets,
|
|
242
500
|
authorityDescriptor,
|
|
@@ -446,7 +704,7 @@ export function createEvolutionEvalProcessSupervisor({
|
|
|
446
704
|
);
|
|
447
705
|
}
|
|
448
706
|
|
|
449
|
-
async function invokeTarget(request) {
|
|
707
|
+
async function invokeTarget(request, context = null) {
|
|
450
708
|
const entry = registry.get(request?.target?.handlerId);
|
|
451
709
|
if (!entry) {
|
|
452
710
|
if (fallbackSupervisor) return fallbackSupervisor.invokeTarget(request);
|
|
@@ -478,11 +736,14 @@ export function createEvolutionEvalProcessSupervisor({
|
|
|
478
736
|
);
|
|
479
737
|
active.set(request.capabilityDigest, { child, closed });
|
|
480
738
|
try {
|
|
481
|
-
const
|
|
739
|
+
const processInput = {
|
|
482
740
|
moduleUrl: entry.snapshot.moduleUrl,
|
|
483
741
|
exportName: entry.exportName,
|
|
484
742
|
payload: request.payload,
|
|
485
|
-
}
|
|
743
|
+
};
|
|
744
|
+
const value = PROCESS_RUNTIME_BROKERS.has(context)
|
|
745
|
+
? await processBrokeredResult(child, processInput, context)
|
|
746
|
+
: await processResult(child, processInput);
|
|
486
747
|
await moduleSnapshot(entry.snapshot.physical, entry.snapshot.digest);
|
|
487
748
|
return Object.freeze({
|
|
488
749
|
value,
|
|
@@ -534,15 +795,21 @@ export function createEvolutionEvalProcessSupervisor({
|
|
|
534
795
|
terminatedAt: revocation.terminatedAt,
|
|
535
796
|
supervisorRevision,
|
|
536
797
|
};
|
|
537
|
-
return
|
|
538
|
-
|
|
798
|
+
return persistEvidence(
|
|
799
|
+
"supervision",
|
|
800
|
+
await attest(
|
|
801
|
+
core,
|
|
802
|
+
EVOLUTION_EVAL_ATTESTATION_PURPOSES.supervisor,
|
|
803
|
+
attestSupervisor,
|
|
804
|
+
),
|
|
539
805
|
EVOLUTION_EVAL_ATTESTATION_PURPOSES.supervisor,
|
|
540
|
-
attestSupervisor,
|
|
541
806
|
);
|
|
542
807
|
}
|
|
543
808
|
|
|
544
809
|
const supervisor = Object.freeze({
|
|
545
810
|
authorityDescriptor: Object.freeze(structuredClone(authorityDescriptor)),
|
|
811
|
+
childEvidenceStoreDescriptor:
|
|
812
|
+
durableEvidence === null ? null : durableEvidence.descriptor,
|
|
546
813
|
invokeTarget,
|
|
547
814
|
revokeTarget,
|
|
548
815
|
verifyEnforcement,
|
|
@@ -3,10 +3,17 @@ import { types as utilTypes } from "node:util";
|
|
|
3
3
|
|
|
4
4
|
import skillInvocationReceipt from "@chainlesschain/session-core/skill-invocation-receipt";
|
|
5
5
|
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
inspectSkillInvocationReceiptCompatibility,
|
|
8
|
+
verifySkillInvocationReceipt,
|
|
9
|
+
} = skillInvocationReceipt;
|
|
7
10
|
|
|
8
|
-
export const
|
|
11
|
+
export const LEGACY_EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA =
|
|
9
12
|
"chainlesschain.evolution-workbench-metrics-snapshot/v1";
|
|
13
|
+
export const EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA =
|
|
14
|
+
"chainlesschain.evolution-workbench-metrics-snapshot/v2";
|
|
15
|
+
export const EVOLUTION_WORKBENCH_RECEIPT_COMPATIBILITY_POLICY =
|
|
16
|
+
"environment-bound-v2";
|
|
10
17
|
export const EVOLUTION_WORKBENCH_METRICS_MAX_RECEIPTS = 100_000;
|
|
11
18
|
export const EVOLUTION_WORKBENCH_METRICS_MAX_DELTA = 10_000;
|
|
12
19
|
export const EVOLUTION_WORKBENCH_METRICS_MAX_HOT_RECEIPTS = 10_000;
|
|
@@ -39,6 +46,13 @@ const LEGACY_SNAPSHOT_KEYS = Object.freeze(
|
|
|
39
46
|
const OUTCOME_SNAPSHOT_KEYS = Object.freeze(
|
|
40
47
|
[...RETENTION_SNAPSHOT_KEYS, "outcomeHistoryComplete"].sort(),
|
|
41
48
|
);
|
|
49
|
+
const COMPATIBILITY_SNAPSHOT_KEYS = Object.freeze(
|
|
50
|
+
[
|
|
51
|
+
...OUTCOME_SNAPSHOT_KEYS,
|
|
52
|
+
"excludedReceiptCount",
|
|
53
|
+
"receiptCompatibilityPolicy",
|
|
54
|
+
].sort(),
|
|
55
|
+
);
|
|
42
56
|
const LEGACY_VERSION_KEYS = Object.freeze(
|
|
43
57
|
[
|
|
44
58
|
"blocked",
|
|
@@ -161,6 +175,9 @@ export function createEmptyEvolutionWorkbenchMetricsSnapshot(
|
|
|
161
175
|
retainedReceiptCount: 0,
|
|
162
176
|
retentionRootDigest: null,
|
|
163
177
|
outcomeHistoryComplete: true,
|
|
178
|
+
excludedReceiptCount: 0,
|
|
179
|
+
receiptCompatibilityPolicy:
|
|
180
|
+
EVOLUTION_WORKBENCH_RECEIPT_COMPATIBILITY_POLICY,
|
|
164
181
|
receiptDigests: [],
|
|
165
182
|
versions: [],
|
|
166
183
|
};
|
|
@@ -246,12 +263,17 @@ export function verifyEvolutionWorkbenchMetricsSnapshot(
|
|
|
246
263
|
value,
|
|
247
264
|
{ tenantId, evolutionRunId, skillName },
|
|
248
265
|
) {
|
|
266
|
+
const exactCompatibility = exactRecord(value, COMPATIBILITY_SNAPSHOT_KEYS);
|
|
249
267
|
const exactOutcome = exactRecord(value, OUTCOME_SNAPSHOT_KEYS);
|
|
250
268
|
const exactRetention = exactRecord(value, RETENTION_SNAPSHOT_KEYS);
|
|
251
269
|
const exactLegacy = exactRecord(value, LEGACY_SNAPSHOT_KEYS);
|
|
270
|
+
const currentSchema =
|
|
271
|
+
value?.schema === EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA;
|
|
272
|
+
const legacySchema =
|
|
273
|
+
value?.schema === LEGACY_EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA;
|
|
252
274
|
if (
|
|
253
|
-
(!
|
|
254
|
-
|
|
275
|
+
((!currentSchema || !exactCompatibility) &&
|
|
276
|
+
(!legacySchema || (!exactOutcome && !exactRetention && !exactLegacy))) ||
|
|
255
277
|
!boundedString(value.tenantId) ||
|
|
256
278
|
!boundedString(value.evolutionRunId) ||
|
|
257
279
|
!boundedString(value.skillName) ||
|
|
@@ -280,6 +302,9 @@ export function verifyEvolutionWorkbenchMetricsSnapshot(
|
|
|
280
302
|
}
|
|
281
303
|
const retainedReceiptCount = value.retainedReceiptCount ?? 0;
|
|
282
304
|
const retentionRootDigest = value.retentionRootDigest ?? null;
|
|
305
|
+
const excludedReceiptCount = exactCompatibility
|
|
306
|
+
? value.excludedReceiptCount
|
|
307
|
+
: 0;
|
|
283
308
|
if (
|
|
284
309
|
!safeCount(retainedReceiptCount) ||
|
|
285
310
|
(retainedReceiptCount === 0 && retentionRootDigest !== null) ||
|
|
@@ -290,18 +315,27 @@ export function verifyEvolutionWorkbenchMetricsSnapshot(
|
|
|
290
315
|
if (
|
|
291
316
|
value.revision === 0 &&
|
|
292
317
|
(retainedReceiptCount !== 0 ||
|
|
318
|
+
excludedReceiptCount !== 0 ||
|
|
293
319
|
value.receiptDigests.length !== 0 ||
|
|
294
320
|
value.versions.length !== 0)
|
|
295
321
|
) {
|
|
296
322
|
throw new TypeError("Workbench metrics genesis snapshot is invalid");
|
|
297
323
|
}
|
|
298
324
|
if (
|
|
299
|
-
exactOutcome &&
|
|
325
|
+
(exactCompatibility || exactOutcome) &&
|
|
300
326
|
(typeof value.outcomeHistoryComplete !== "boolean" ||
|
|
301
327
|
(value.revision === 0 && value.outcomeHistoryComplete !== true))
|
|
302
328
|
) {
|
|
303
329
|
throw new TypeError("Workbench metrics outcome coverage is invalid");
|
|
304
330
|
}
|
|
331
|
+
if (
|
|
332
|
+
exactCompatibility &&
|
|
333
|
+
(!safeCount(excludedReceiptCount) ||
|
|
334
|
+
value.receiptCompatibilityPolicy !==
|
|
335
|
+
EVOLUTION_WORKBENCH_RECEIPT_COMPATIBILITY_POLICY)
|
|
336
|
+
) {
|
|
337
|
+
throw new TypeError("Workbench metrics receipt compatibility is invalid");
|
|
338
|
+
}
|
|
305
339
|
for (const receiptDigest of value.receiptDigests)
|
|
306
340
|
digest(receiptDigest, "receipt digest");
|
|
307
341
|
const versionDigests = new Set();
|
|
@@ -378,23 +412,20 @@ export function verifyEvolutionWorkbenchMetricsSnapshot(
|
|
|
378
412
|
}
|
|
379
413
|
}
|
|
380
414
|
if (
|
|
381
|
-
projectedReceiptCount !==
|
|
415
|
+
projectedReceiptCount + excludedReceiptCount !==
|
|
382
416
|
retainedReceiptCount + value.receiptDigests.length
|
|
383
417
|
) {
|
|
384
418
|
throw new Error("Workbench metrics receipt retention total is invalid");
|
|
385
419
|
}
|
|
386
420
|
if (
|
|
387
|
-
(exactOutcome && versionLayout === "legacy") ||
|
|
388
|
-
(!exactOutcome && versionLayout === "outcome")
|
|
421
|
+
((exactCompatibility || exactOutcome) && versionLayout === "legacy") ||
|
|
422
|
+
(!exactCompatibility && !exactOutcome && versionLayout === "outcome")
|
|
389
423
|
) {
|
|
390
424
|
throw new TypeError("Workbench metrics outcome layout is invalid");
|
|
391
425
|
}
|
|
392
426
|
const core = structuredClone(value);
|
|
393
427
|
delete core.snapshotDigest;
|
|
394
|
-
if (
|
|
395
|
-
hash(EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA, core) !==
|
|
396
|
-
value.snapshotDigest
|
|
397
|
-
) {
|
|
428
|
+
if (hash(value.schema, core) !== value.snapshotDigest) {
|
|
398
429
|
throw new Error("Workbench metrics snapshot digest is invalid");
|
|
399
430
|
}
|
|
400
431
|
return freeze(structuredClone(value));
|
|
@@ -422,11 +453,19 @@ function nextSnapshot(previous, source, receipts, retention) {
|
|
|
422
453
|
);
|
|
423
454
|
const outcomeHistoryComplete =
|
|
424
455
|
previous.outcomeHistoryComplete === true || previousReceiptCount === 0;
|
|
456
|
+
let excludedReceiptCount = previous.excludedReceiptCount;
|
|
425
457
|
for (const receipt of receipts) {
|
|
426
458
|
if (seen.has(receipt.receiptDigest)) {
|
|
427
459
|
throw new Error("Workbench metrics source replayed a receipt");
|
|
428
460
|
}
|
|
429
461
|
seen.add(receipt.receiptDigest);
|
|
462
|
+
if (
|
|
463
|
+
!inspectSkillInvocationReceiptCompatibility(receipt)
|
|
464
|
+
.environmentBoundAttributionEligible
|
|
465
|
+
) {
|
|
466
|
+
excludedReceiptCount += 1;
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
430
469
|
for (const contentDigest of receipt.selectedSkillDigests) {
|
|
431
470
|
const current = versions.get(contentDigest) ?? {
|
|
432
471
|
contentDigest,
|
|
@@ -485,6 +524,9 @@ function nextSnapshot(previous, source, receipts, retention) {
|
|
|
485
524
|
retainedReceiptCount: retention.retainedReceiptCount,
|
|
486
525
|
retentionRootDigest: retention.retentionRootDigest,
|
|
487
526
|
outcomeHistoryComplete,
|
|
527
|
+
excludedReceiptCount,
|
|
528
|
+
receiptCompatibilityPolicy:
|
|
529
|
+
EVOLUTION_WORKBENCH_RECEIPT_COMPATIBILITY_POLICY,
|
|
488
530
|
receiptDigests: [...seen].sort(),
|
|
489
531
|
versions: [...versions.values()].sort((left, right) =>
|
|
490
532
|
left.contentDigest.localeCompare(right.contentDigest),
|
|
@@ -596,8 +638,8 @@ export class EvolutionWorkbenchMetricsOutcomeBackfiller {
|
|
|
596
638
|
this.descriptor,
|
|
597
639
|
);
|
|
598
640
|
if (
|
|
599
|
-
previous.
|
|
600
|
-
previous.
|
|
641
|
+
previous.schema === EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA &&
|
|
642
|
+
previous.outcomeHistoryComplete === true
|
|
601
643
|
) {
|
|
602
644
|
return freeze({ status: "already-complete", snapshot: previous });
|
|
603
645
|
}
|
|
@@ -643,7 +685,6 @@ export class EvolutionWorkbenchMetricsOutcomeBackfiller {
|
|
|
643
685
|
const verified = verifySkillInvocationReceipt(receipt);
|
|
644
686
|
if (
|
|
645
687
|
verified.evolutionRunId !== this.descriptor.evolutionRunId ||
|
|
646
|
-
verified.attributionEligible !== true ||
|
|
647
688
|
Date.parse(verified.completedAt) > Date.parse(previous.throughAt)
|
|
648
689
|
) {
|
|
649
690
|
throw new Error("Workbench metrics history lacks exact attribution");
|
|
@@ -692,9 +733,19 @@ export class EvolutionWorkbenchMetricsOutcomeBackfiller {
|
|
|
692
733
|
);
|
|
693
734
|
}
|
|
694
735
|
}
|
|
695
|
-
const
|
|
736
|
+
const eligibleReceipts = receipts.filter(
|
|
737
|
+
(receipt) =>
|
|
738
|
+
inspectSkillInvocationReceiptCompatibility(receipt)
|
|
739
|
+
.environmentBoundAttributionEligible,
|
|
740
|
+
);
|
|
741
|
+
const versions = projectReceiptHistory(eligibleReceipts);
|
|
742
|
+
const reconciliationVersions = projectReceiptHistory(
|
|
743
|
+
previous.schema === LEGACY_EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA
|
|
744
|
+
? receipts
|
|
745
|
+
: eligibleReceipts,
|
|
746
|
+
);
|
|
696
747
|
if (
|
|
697
|
-
canonical(legacyProjection(
|
|
748
|
+
canonical(legacyProjection(reconciliationVersions)) !==
|
|
698
749
|
canonical(legacyProjection(previous.versions))
|
|
699
750
|
) {
|
|
700
751
|
throw new Error("Workbench metrics history does not reconcile");
|
|
@@ -711,6 +762,9 @@ export class EvolutionWorkbenchMetricsOutcomeBackfiller {
|
|
|
711
762
|
retainedReceiptCount: previous.retainedReceiptCount ?? 0,
|
|
712
763
|
retentionRootDigest: previous.retentionRootDigest ?? null,
|
|
713
764
|
outcomeHistoryComplete: true,
|
|
765
|
+
excludedReceiptCount: receipts.length - eligibleReceipts.length,
|
|
766
|
+
receiptCompatibilityPolicy:
|
|
767
|
+
EVOLUTION_WORKBENCH_RECEIPT_COMPATIBILITY_POLICY,
|
|
714
768
|
receiptDigests: previous.receiptDigests,
|
|
715
769
|
versions,
|
|
716
770
|
};
|
|
@@ -809,6 +863,15 @@ export class EvolutionWorkbenchMetricsAggregator {
|
|
|
809
863
|
loaded.snapshot,
|
|
810
864
|
this.descriptor,
|
|
811
865
|
);
|
|
866
|
+
if (
|
|
867
|
+
previous.schema === LEGACY_EVOLUTION_WORKBENCH_METRICS_SNAPSHOT_SCHEMA
|
|
868
|
+
) {
|
|
869
|
+
const error = new Error(
|
|
870
|
+
"Workbench metrics snapshot requires receipt compatibility backfill",
|
|
871
|
+
);
|
|
872
|
+
error.code = "CC_WORKBENCH_METRICS_COMPATIBILITY_BACKFILL_REQUIRED";
|
|
873
|
+
throw error;
|
|
874
|
+
}
|
|
812
875
|
} else {
|
|
813
876
|
throw new Error("Workbench metrics snapshot load is not authoritative");
|
|
814
877
|
}
|
|
@@ -832,10 +895,7 @@ export class EvolutionWorkbenchMetricsAggregator {
|
|
|
832
895
|
}
|
|
833
896
|
const receipts = source.receipts.map((receipt) => {
|
|
834
897
|
const verified = verifySkillInvocationReceipt(receipt);
|
|
835
|
-
if (
|
|
836
|
-
verified.evolutionRunId !== this.descriptor.evolutionRunId ||
|
|
837
|
-
verified.attributionEligible !== true
|
|
838
|
-
) {
|
|
898
|
+
if (verified.evolutionRunId !== this.descriptor.evolutionRunId) {
|
|
839
899
|
throw new Error("Workbench metrics receipt lacks exact attribution");
|
|
840
900
|
}
|
|
841
901
|
return verified;
|