chainlesschain 0.166.21 → 0.166.24
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 +67 -9
- package/package.json +4 -3
- package/src/assets/web-panel/assets/{AIOps-BjMnsUci.js → AIOps-DR-MWcZc.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DdYFP03A.js → ActionButton-DT8B7sEb.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Bb8TuuK_.js → Analytics-asjh3dQJ.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Kn3TIOtk.js → AppLayout-DivQ491i.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-4IxpqI_b.js → Artifacts-DPH2uUmy.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BOV2caqU.js → Audit-Bp2nLyc-.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-B86k-ay4.js → BackgroundAgents-CHS28khl.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-C5_ie1e3.js → Backup-CKeaFSfz.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-xpwg6QCW.js → BaseInput-CxwM9BAH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CVZOcZau.js → Chat-DYLDwaCv.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-D8fPYhUu.js → ChatBubbleRenderer-DdBJDBP0.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-MKTq3zdP.js → Checkbox-uYTWOB8j.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-JUk3wzep.js → Codegen-CvYa_dwT.js} +1 -1
- package/src/assets/web-panel/assets/{Col-JPvTA0kC.js → Col-CanMAX4m.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Tqgl87NQ.js → Community-B4WaDtHw.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BuAFYBmN.js → Compact-K93Uof_3.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CXS9WIPZ.js → Compliance-CKeDLgUW.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Ds2bFHrr.js → Cowork-P93grAeB.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-C_dV_OeW.js → Cron-BSHnMtDn.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BsO6tIRo.js → Crosschain-epAOpUVJ.js} +1 -1
- package/src/assets/web-panel/assets/{DID-rNOFqBac.js → DID-ByjXfP7t.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-C2fcKKVY.js → Dashboard-QztTU8tb.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Y7Ndr0X_.js → Dropdown-DhUc9yhN.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DcP_uPmL.js → EmailListRenderer-C2sLhJJN.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Cwn3gDzk.js → FamilyGuardDashboard-CdfbWNDn.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-ClQuOsqb.js → Federation-CcF_R7NW.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DfwtmlcK.js → FormItemContext-Cm_X2IBk.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-zNZhtbC5.js → GenericCardRenderer-DUi4NWlb.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BZmdW-G5.js → Git-4Sq5FjBt.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CqBk4lEn.js → Governance-Dx2_v4V6.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Dbmt3ZXk.js → Inference-7Vr1xekR.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-hMTH6qf3.js → KnowledgeGraph-Cnd2XOzf.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CkiYgiW2.js → Logs-B66QPVf-.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BL1FElXg.js → MarkdownRenderer-PLsEvhly.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CbB6wfin.js → Marketplace-BMIK9BmC.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BSwiFtte.js → McpTools-BDbyp3J_.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-B03PeHrz.js → Memory-CJdzfZGi.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CRGrnd-X.js → MobileBridge-C2TH5Y3-.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CE_5v2kO.js → MobileProjects-D1dYXkvV.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-Dp11QVx1.js → Mtc-B-4A1I1j.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CYu-3JBu.js → MtcAudit-Bgcc9UOl.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-CGyJ0Xl3.js → Multisig-DqOe-etP.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CoWi_ov1.js → NLProgramming-7VnhzE_6.js} +1 -1
- package/src/assets/web-panel/assets/Notes-BxawpeUQ.js +7 -0
- package/src/assets/web-panel/assets/{NotificationSettings-DX4I2b4W.js → NotificationSettings-Cr08G2aE.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Ce8bEGlK.js +1 -0
- package/src/assets/web-panel/assets/{Organization-oopLO_tk.js → Organization-BC7lveGv.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BFVvjMyf.js → Overflow-CakOW-G0.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CBy5t-Tk.js → P2P-Cf8CaOBZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser--YWJNsu6.js → PdhVaultBrowser-Dc7b98W9.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-C2dZ8scb.js → Permissions-DGJyMEfS.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-Bs3l7Hlx.js → PersonalDataHub-DNIwSdwu.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-DEBWbZuD.js → Pipeline-5B1S12wa.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CjHBb6NU.js → Privacy-CMB6Ke5t.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-D2WipUz5.js → ProjectInit-D5PqTFiT.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-B6WfnrGB.js → ProjectSettings-CbKNdSjV.js} +2 -2
- package/src/assets/web-panel/assets/Projects-ccXaHzYL.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CCv5M_Dv.js → Providers-CJF5_-Gs.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CGthxU54.js → QrScannerModal-CT6iEAdi.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CnPmXPFb.js → QuickAsk-Ci0h9mJ_.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Df_tGEa9.js → Recommend-Da5mobZu.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Z58N0Loe.js → RemoteSession-BaCY8eey.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CZTBQ2Vt.js → Reputation-CaITfTsI.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CdK3YpCQ.js → Row-DtUDamyP.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CFMVT5sb.js → RssFeed-DX27gFpg.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DrF8RIvD.js → Search-DFL69osN.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Ddk2f2DM.js → Security-BqGeoWv-.js} +3 -3
- package/src/assets/web-panel/assets/{Services-CCuK-VOo.js → Services-3z1WnEAc.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DxCpHzeM.js → Skeleton-C_OJQQ9Z.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-t2oTDgcv.js → Skills-BY7aT6Mo.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Df63M9_R.js → Sla-BZv7DSaD.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-6lJKLhCn.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-COd_tgPp.js → SyncSettings-B6D7STlI.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-CzDCcrik.js → Tasks-Co_FCZAO.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D-vfxTGA.js → Templates-CnY-9fgz.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BlpT_Gxc.js → Tenant-B71yXfZ8.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-D5rq52Hg.js → Terminal-Dd_P7awo.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DdoMndkK.js → TimelineRenderer-CvIEMyli.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BhgBsI6g.js → Tokens-DknFBGOi.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DwwzoikZ.js → Trigger-D_4nJONB.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-HkTpzXFb.js → Trust-BNl21fa7.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-D9nk6Ehe.js → UkeySign-CFrCI7uK.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BKk0rfoy.js → VideoEditing-BVfY6JLg.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-IVWIU_Lq.js → Wallet-Cj9CAK0J.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CFTCpfsG.js → WebAuthn-DcqZlzA3.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Dnf4Obif.js → WorkflowEditor-Dfr_dMld.js} +1 -1
- package/src/assets/web-panel/assets/{chat-D2snERdj.js → chat-Yv6UF0AD.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DKEjK1N1.js → colors-CDW_-1fs.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BEDLwQdt.js → compact-item-BYOQvd-6.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DA9iW1a0.js → createContext-BCGO0BiP.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-H-kXSuf-.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-5l2xEcY9.js → hasIn-DY-70cfQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7_W_rYd.js → index-366wfQBU.js} +1 -1
- package/src/assets/web-panel/assets/index-B0o4MeNK.js +1 -0
- package/src/assets/web-panel/assets/{index-CxEtQYdi.js → index-B9ZogJJM.js} +1 -1
- package/src/assets/web-panel/assets/{index-B00GeekA.js → index-B9m5QAMg.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7sKbM5s.js → index-BBs2mv5M.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX1x4AFn.js → index-BFv1hzF6.js} +1 -1
- package/src/assets/web-panel/assets/index-BVafOL_I.js +1 -0
- package/src/assets/web-panel/assets/{index-DU2TXJu-.js → index-BXlEx4UH.js} +1 -1
- package/src/assets/web-panel/assets/{index-e-e40id6.js → index-BayRTE5w.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXet1xol.js → index-Bb9nyts1.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7z4zB_a.js → index-Bf_Va0S-.js} +1 -1
- package/src/assets/web-panel/assets/{index-fccZmC_h.js → index-Br3wQLVY.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bqc8tdIF.js → index-BvK4fjkk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BO9dQjpt.js → index-C40UdtlS.js} +1 -1
- package/src/assets/web-panel/assets/{index-Csfb-7hw.js → index-C4UJA2ju.js} +1 -1
- package/src/assets/web-panel/assets/{index-Td8ZwyoC.js → index-CB_Iw73G.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZ5lY2zx.js → index-CCwWp3mT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpqtbXdE.js → index-CFa2fPCk.js} +1 -1
- package/src/assets/web-panel/assets/{index-NJieh3T1.js → index-CIyHxV4u.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbkghqn_.js → index-CUP-A2_h.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqwPFbOb.js → index-CUo27q9J.js} +3 -3
- package/src/assets/web-panel/assets/{index-B4QYBliR.js → index-CaT8trvf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BgfImyZI.js → index-CnZNbcux.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbd7eEex.js → index-Cy2NE6AO.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbTPvp2_.js → index-CzeEEazr.js} +1 -1
- package/src/assets/web-panel/assets/{index-5pW4t1iD.js → index-D--TEyDj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dg2a9owQ.js → index-DCtsjhhT.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_eCoZgW.js → index-DLOf7BSz.js} +1 -1
- package/src/assets/web-panel/assets/{index-7P1b8HZo.js → index-DM5c4pc-.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRPrHE7h.js → index-DRFC2Qt0.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bq5P3piS.js → index-DT_qVaaV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CjWltbi_.js → index-DUDoRk9r.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkMKuqUs.js → index-Dg-AQYDf.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLoalqRX.js → index-DuIPq5MX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGlotREA.js → index-NYVBUAVN.js} +1 -1
- package/src/assets/web-panel/assets/{index-yYEQXYaU.js → index-NaCESahy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmruhzFi.js → index-RjIMPG0u.js} +1 -1
- package/src/assets/web-panel/assets/{index-fgYk0QXO.js → index-Y9akzgFO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvV03Ayk.js → index-hZ0Eyrrw.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CPrcB1TC.js → initDefaultProps-CG99CcR4.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BQ7mWRh_.js → motion-Z7MH0_0G.js} +1 -1
- package/src/assets/web-panel/assets/{move-CzOEq99p.js → move-BX67lOdq.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BlQI5jrw.js → mtc-parser-CmAbG1fE.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DlW4gxmv.js → omit-DiU5tI1_.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BBYms5nP.js → pickAttrs-BGfvLrYL.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-az2MPJ_7.js → placementArrow-CggLEgaJ.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D1-ibEol.js → responsiveObserve-t3nlghPZ.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DHGqa4GA.js → slide-BkV4dL9s.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CYGDo6lD.js → statusUtils-qec1PUoC.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Cl2EM9K6.js → styleChecker-ChjX6T8D.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DdYhzuv1.js → useFlexGapSupport-B1jLoZcM.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DWumPuBW.js → useFs-C3X53s4E.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DxAO-Aqi.js → usePersonalDataHub-DOvbbnkZ.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CplsQf_N.js → vnode-Ie0TEVFT.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Cw5HXNSG.js → zoom-CRUMVS8l.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 +18 -1
- package/src/commands/evolution-benchmark.js +72 -0
- package/src/commands/evolution.js +2 -0
- package/src/commands/governed-skill-marketplace.js +142 -0
- package/src/commands/marketplace.js +4 -1
- package/src/commands/serve.js +41 -0
- package/src/commands/skill.js +3 -0
- package/src/data/changelog.json +39 -0
- package/src/gateways/ws/ws-agent-handler.js +59 -2
- package/src/gateways/ws/ws-server.js +2 -0
- package/src/harness/golden-transcript.js +1 -0
- package/src/harness/prompt-compressor.js +51 -5
- package/src/harness/provider-backed-compaction.js +28 -1
- package/src/harness/remote-session-registry.js +15 -3
- package/src/index.js +30 -4
- package/src/lazy-dispatch.js +15 -1
- package/src/lib/advisor-runtime.js +55 -2
- package/src/lib/app-server/cli-agent-kernel-adapter.js +4 -0
- package/src/lib/app-server/graph-runtime.js +32 -0
- package/src/lib/app-server/server.js +45 -1
- package/src/lib/app-server/websocket-transport.js +23 -0
- package/src/lib/autonomous-agent.js +63 -13
- package/src/lib/cowork/ab-comparator-cli.js +4 -3
- package/src/lib/cowork/debate-review-cli.js +4 -3
- package/src/lib/cowork/decision-kb-cli.js +5 -0
- package/src/lib/cowork-adapter.js +38 -16
- package/src/lib/evolution/agent-evolution-ingress.js +95 -15
- package/src/lib/evolution/agent-evolution-runtime-composition.js +82 -0
- package/src/lib/evolution/agent-evolution-session-lifecycle.js +46 -0
- package/src/lib/evolution/agent-model-projection.js +217 -0
- package/src/lib/evolution/bounded-descriptor-read.js +29 -0
- package/src/lib/evolution/controlled-skill-pilot-ledger-adapter.js +551 -0
- package/src/lib/evolution/controlled-skill-production-pilot.js +308 -18
- package/src/lib/evolution/evidence-backed-wiki-maintainer.js +10 -1
- package/src/lib/evolution/evidence-json-text.js +236 -0
- package/src/lib/evolution/evolution-artifact-ports.js +202 -21
- package/src/lib/evolution/evolution-deployment-loader.js +369 -0
- package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +373 -0
- package/src/lib/evolution/evolution-eval-gate.js +14 -1
- package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +14 -0
- package/src/lib/evolution/evolution-eval-process-supervisor.js +607 -0
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +14 -1
- package/src/lib/evolution/evolution-evidence-projector.js +240 -37
- package/src/lib/evolution/evolution-file-witness.js +153 -30
- package/src/lib/evolution/evolution-ledger-ports.js +1027 -66
- package/src/lib/evolution/evolution-ledger.js +66 -2
- package/src/lib/evolution/evolution-raw-crypto-shred.js +29 -15
- package/src/lib/evolution/evolution-raw-deletion-ledger-adapter.js +865 -0
- package/src/lib/evolution/evolution-release-train-domain-stages.js +769 -0
- package/src/lib/evolution/evolution-release-train-ledger-adapter.js +335 -0
- package/src/lib/evolution/evolution-release-train-stage-output-ledger-adapter.js +333 -0
- package/src/lib/evolution/evolution-release-train.js +586 -0
- package/src/lib/evolution/evolution-workbench-batch-executor.js +101 -144
- package/src/lib/evolution/evolution-workbench-control-ports.js +203 -0
- package/src/lib/evolution/evolution-workbench-file-resources.js +403 -0
- package/src/lib/evolution/evolution-workbench-projection.js +152 -25
- package/src/lib/evolution/evolution-workbench-registry-source.js +482 -0
- package/src/lib/evolution/evolution-workbench-review-ledger-adapter.js +823 -0
- package/src/lib/evolution/evolution-workbench-review-protocol.js +157 -0
- package/src/lib/evolution/evolution-workbench-rollback-authorization.js +57 -0
- package/src/lib/evolution/evolution-workbench-rollback-ledger-adapter.js +1016 -0
- package/src/lib/evolution/evolution-workbench-runtime.js +133 -0
- package/src/lib/evolution/evolution-workbench-version-control.js +70 -36
- package/src/lib/evolution/evolvable-artifact-ledger-adapter.js +736 -0
- package/src/lib/evolution/governed-knowledge-artifact-lifecycle.js +364 -0
- package/src/lib/evolution/governed-knowledge-candidate-rejection.js +343 -0
- package/src/lib/evolution/governed-knowledge-dependency-authority.js +227 -44
- package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +95 -83
- package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +29 -2
- package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +31 -3
- package/src/lib/evolution/governed-knowledge-record.js +148 -0
- package/src/lib/evolution/governed-knowledge-revocation-record.js +135 -0
- package/src/lib/evolution/governed-knowledge-skill-rollback.js +475 -0
- package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +92 -6
- package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +57 -4
- package/src/lib/evolution/governed-knowledge-sync.js +332 -99
- package/src/lib/evolution/governed-knowledge-wiki-tombstone.js +462 -0
- package/src/lib/evolution/governed-skill-marketplace-badge.js +208 -0
- package/src/lib/evolution/governed-skill-marketplace-candidate.js +330 -0
- package/src/lib/evolution/governed-skill-marketplace-cli-host.js +308 -0
- package/src/lib/evolution/governed-skill-marketplace-ledger-adapter.js +420 -0
- package/src/lib/evolution/governed-skill-marketplace.js +288 -5
- package/src/lib/evolution/governed-wiki-pruning-journal.js +302 -0
- package/src/lib/evolution/governed-wiki-pruning-ledger-adapter.js +459 -0
- package/src/lib/evolution/governed-wiki-pruning-maintenance.js +576 -0
- package/src/lib/evolution/governed-wiki-pruning-plan-authority.js +169 -0
- package/src/lib/evolution/governed-wiki-pruning-raw-shred.js +207 -0
- package/src/lib/evolution/governed-wiki-pruning-retrieval.js +587 -0
- package/src/lib/evolution/governed-wiki-pruning-runtime.js +153 -0
- package/src/lib/evolution/governed-wiki-pruning-skill-rollback.js +360 -0
- package/src/lib/evolution/governed-wiki-pruning.js +322 -143
- package/src/lib/evolution/independent-skill-revocation-source.js +231 -0
- package/src/lib/evolution/knowledge-wiki-source-admission.js +124 -0
- package/src/lib/evolution/knowledge-wiki-source-provenance.js +359 -0
- package/src/lib/evolution/progressive-canary-external-watchdog.js +578 -0
- package/src/lib/evolution/progressive-canary-traffic-worker.js +628 -0
- package/src/lib/evolution/progressive-canary-watchdog-file-store.js +285 -0
- package/src/lib/evolution/progressive-canary-watchdog-node-pki.js +265 -0
- package/src/lib/evolution/skill-candidate-registry.js +22 -0
- package/src/lib/evolution/skill-promotion-controller.js +25 -0
- package/src/lib/evolution/skill-promotion-review-ledger-adapter.js +100 -0
- package/src/lib/evolution/skill-registry-transition-ledger-adapter.js +131 -2
- package/src/lib/evolution/skill-release-registry.js +25 -4
- package/src/lib/evolution/skill-retrieval-revocation-authority.js +361 -0
- package/src/lib/evolution/skill-retrieval-revocation-ledger-adapter.js +346 -0
- package/src/lib/evolution/skill-revocation-propagation.js +467 -0
- package/src/lib/evolution/skill-target-matrix-eval.js +162 -11
- package/src/lib/evolution/skill-wiki-reconciliation.js +985 -0
- package/src/lib/evolution/skill-writer-inventory-manifest.js +15 -12
- package/src/lib/evolution/statistical-progressive-canary.js +845 -0
- package/src/lib/evolution/structured-memory-agent-control-plane.js +120 -0
- package/src/lib/evolution/structured-memory-authority-ledger-adapter.js +5 -1
- package/src/lib/evolution/structured-memory-promotion-receipt-writer.js +126 -0
- package/src/lib/evolution/wiki-informed-skill-proposer.js +127 -21
- package/src/lib/evolution/wiki-maintainer-ledger-adapter.js +760 -100
- package/src/lib/evolution/wiki-revision-protocol.js +120 -0
- package/src/lib/evolution/wiki-skill-proposal-ledger-adapter.js +307 -0
- package/src/lib/evolution/wiki-target-tombstone-revision.js +101 -0
- package/src/lib/evolution/wikiskill-benchmark-cli-host.js +178 -0
- package/src/lib/evolution/wikiskill-benchmark-execution-host.js +702 -0
- package/src/lib/evolution/wikiskill-benchmark-ledger-adapter.js +613 -0
- package/src/lib/evolution/wikiskill-benchmark.js +574 -0
- package/src/lib/goal-assess.js +17 -10
- package/src/lib/interactive-planner.js +9 -1
- package/src/lib/iteration-budget.js +16 -2
- package/src/lib/micro-compact.js +4 -1
- package/src/lib/model-failure-policy.js +21 -0
- package/src/lib/process-execution-broker/index.js +1 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +33 -15
- package/src/lib/read-file-page.js +191 -0
- package/src/lib/runnable-provider.js +2 -1
- package/src/lib/session-host-lease.js +11 -16
- package/src/lib/skill-retrieval-router.js +22 -1
- package/src/repl/agent-repl.js +127 -33
- package/src/runtime/agent-core.js +224 -80
- package/src/runtime/agent-runtime.js +43 -0
- package/src/runtime/coding-agent-contract-shared.cjs +7 -1
- package/src/runtime/fallback-model.js +143 -62
- package/src/runtime/headless-runner.js +54 -10
- package/src/runtime/headless-stream.js +53 -6
- package/src/runtime/runtime-factory.js +41 -2
- package/src/assets/web-panel/assets/Notes-CgU9DDo9.js +0 -7
- package/src/assets/web-panel/assets/OrderTableRenderer-CwHc15Zs.js +0 -1
- package/src/assets/web-panel/assets/Projects-FF_thRi6.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-l7ox6KuX.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DyhgpXPf.js +0 -1
- package/src/assets/web-panel/assets/index-Ck1jhFE0.js +0 -1
- package/src/assets/web-panel/assets/index-c8jJEHVs.js +0 -1
|
@@ -0,0 +1,823 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { types } from "node:util";
|
|
3
|
+
import {
|
|
4
|
+
EvolutionArtifactPorts,
|
|
5
|
+
EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
|
|
6
|
+
isEvolutionLedgerArtifactResolver,
|
|
7
|
+
} from "./evolution-artifact-ports.js";
|
|
8
|
+
import {
|
|
9
|
+
EvolutionLedger,
|
|
10
|
+
EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA,
|
|
11
|
+
EVOLUTION_LEDGER_MAX_EVENTS,
|
|
12
|
+
EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA,
|
|
13
|
+
} from "./evolution-ledger.js";
|
|
14
|
+
import { SkillPromotionReviewLedgerAdapter } from "./skill-promotion-review-ledger-adapter.js";
|
|
15
|
+
import { EvolutionRunLedgerAdapter } from "./evolution-run-ledger-adapter.js";
|
|
16
|
+
import { EvolutionWorkbenchBatchExecutor } from "./evolution-workbench-batch-executor.js";
|
|
17
|
+
import { captureWorkbenchRegistrySource } from "./evolution-workbench-registry-source.js";
|
|
18
|
+
import {
|
|
19
|
+
buildEvolutionWorkbenchProjection,
|
|
20
|
+
filterEvolutionWorkbenchProjection,
|
|
21
|
+
isEvolutionWorkbenchDataSource,
|
|
22
|
+
createEvolutionWorkbenchDataSource,
|
|
23
|
+
} from "./evolution-workbench-projection.js";
|
|
24
|
+
import {
|
|
25
|
+
verifyWorkbenchBatchPlan,
|
|
26
|
+
buildWorkbenchBatchItemRequest,
|
|
27
|
+
verifyWorkbenchHumanDecisionResponse,
|
|
28
|
+
buildWorkbenchExecutionItem,
|
|
29
|
+
} from "./evolution-workbench-review-protocol.js";
|
|
30
|
+
import {
|
|
31
|
+
capturePruningData as capture,
|
|
32
|
+
pruningCanonical as canonical,
|
|
33
|
+
} from "./governed-wiki-pruning-journal.js";
|
|
34
|
+
|
|
35
|
+
export const WORKBENCH_REVIEW_PREPARATION_SCHEMA =
|
|
36
|
+
"chainlesschain.evolution-workbench-review-preparation/v1";
|
|
37
|
+
export const WORKBENCH_REVIEW_SETTLEMENT_SCHEMA =
|
|
38
|
+
"chainlesschain.evolution-workbench-review-settlement/v1";
|
|
39
|
+
const TYPES = Object.freeze({
|
|
40
|
+
projection: [
|
|
41
|
+
"evolution-workbench-projection",
|
|
42
|
+
"evolution.workbench.projection.retained",
|
|
43
|
+
],
|
|
44
|
+
prepared: [
|
|
45
|
+
"evolution-workbench-review-preparation",
|
|
46
|
+
"evolution.workbench.review.prepared",
|
|
47
|
+
],
|
|
48
|
+
committed: [
|
|
49
|
+
"evolution-workbench-review-settlement",
|
|
50
|
+
"evolution.workbench.review.committed",
|
|
51
|
+
],
|
|
52
|
+
});
|
|
53
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
54
|
+
const PROJECTION_READERS = new WeakSet();
|
|
55
|
+
const ADAPTER_PROJECTION_READERS = new WeakMap();
|
|
56
|
+
export function captureWorkbenchProjectionReader(value) {
|
|
57
|
+
if (!PROJECTION_READERS.has(value))
|
|
58
|
+
throw new TypeError(
|
|
59
|
+
"a genuine Workbench retained projection reader is required",
|
|
60
|
+
);
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
const same = (a, b) => canonical(a) === canonical(b);
|
|
64
|
+
const compare = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
65
|
+
const sortedRefs = (refs) =>
|
|
66
|
+
[...refs].sort(
|
|
67
|
+
(a, b) => compare(a.ref, b.ref) || compare(a.digest, b.digest),
|
|
68
|
+
);
|
|
69
|
+
function fail(message) {
|
|
70
|
+
const error = new Error(message);
|
|
71
|
+
error.code = "CC_EVOLUTION_WORKBENCH_REVIEW_LEDGER_INVALID";
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
function method(owner, name) {
|
|
75
|
+
if (!owner || types.isProxy(owner))
|
|
76
|
+
throw new TypeError(`${name} fixed port is required`);
|
|
77
|
+
const fn = Object.getOwnPropertyDescriptor(owner, name)?.value;
|
|
78
|
+
if (typeof fn !== "function" || types.isProxy(fn))
|
|
79
|
+
throw new TypeError(`${name} fixed own method is required`);
|
|
80
|
+
return fn.bind(owner);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// All effects and recovery evidence use the same real ArtifactPorts/Ledger.
|
|
84
|
+
// Deployment owns the human provider and BOTH current signature verifiers.
|
|
85
|
+
// No default identity, signer, test key, in-memory journal or success fallback.
|
|
86
|
+
export class EvolutionWorkbenchReviewLedgerAdapter {
|
|
87
|
+
#ledger;
|
|
88
|
+
#put;
|
|
89
|
+
#resolve;
|
|
90
|
+
#source;
|
|
91
|
+
#review;
|
|
92
|
+
#requestHuman;
|
|
93
|
+
#verifyHuman;
|
|
94
|
+
#now;
|
|
95
|
+
constructor({
|
|
96
|
+
descriptor,
|
|
97
|
+
artifactPorts,
|
|
98
|
+
ledger,
|
|
99
|
+
ledgerArtifactResolver,
|
|
100
|
+
projectionSource,
|
|
101
|
+
decisionVerifier,
|
|
102
|
+
humanDecisionProvider,
|
|
103
|
+
humanDecisionVerifier,
|
|
104
|
+
now = Date.now,
|
|
105
|
+
} = {}) {
|
|
106
|
+
const d = capture(descriptor);
|
|
107
|
+
for (const key of [
|
|
108
|
+
"tenantId",
|
|
109
|
+
"artifactTenantId",
|
|
110
|
+
"streamId",
|
|
111
|
+
"runId",
|
|
112
|
+
"skillName",
|
|
113
|
+
"audience",
|
|
114
|
+
])
|
|
115
|
+
if (
|
|
116
|
+
typeof d[key] !== "string" ||
|
|
117
|
+
!/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u.test(d[key])
|
|
118
|
+
)
|
|
119
|
+
throw new TypeError(`Workbench ${key} is invalid`);
|
|
120
|
+
if (d.purpose !== "evolution-ledger")
|
|
121
|
+
throw new TypeError("Workbench requires evolution-ledger purpose");
|
|
122
|
+
if (
|
|
123
|
+
types.isProxy(ledger) ||
|
|
124
|
+
types.isProxy(artifactPorts) ||
|
|
125
|
+
!(ledger instanceof EvolutionLedger) ||
|
|
126
|
+
!(artifactPorts instanceof EvolutionArtifactPorts) ||
|
|
127
|
+
!isEvolutionLedgerArtifactResolver(ledgerArtifactResolver)
|
|
128
|
+
)
|
|
129
|
+
throw new TypeError(
|
|
130
|
+
"Workbench requires actual Ledger and ArtifactPorts with a branded resolver",
|
|
131
|
+
);
|
|
132
|
+
if (
|
|
133
|
+
!isEvolutionWorkbenchDataSource(projectionSource) ||
|
|
134
|
+
projectionSource.tenantId !== d.tenantId ||
|
|
135
|
+
projectionSource.runId !== d.runId ||
|
|
136
|
+
projectionSource.skillName !== d.skillName
|
|
137
|
+
)
|
|
138
|
+
throw new TypeError(
|
|
139
|
+
"Workbench requires a same-scope branded projection source",
|
|
140
|
+
);
|
|
141
|
+
if (typeof now !== "function" || types.isProxy(now))
|
|
142
|
+
throw new TypeError("Workbench clock is required");
|
|
143
|
+
this.descriptor = d;
|
|
144
|
+
// Capture concrete implementations; caller-shaped Ledger methods cannot
|
|
145
|
+
// manufacture recovery evidence or broaden the read to another backend.
|
|
146
|
+
this.#ledger = Object.freeze({
|
|
147
|
+
read: () =>
|
|
148
|
+
EvolutionLedger.prototype.read.call(ledger, {
|
|
149
|
+
limit: EVOLUTION_LEDGER_MAX_EVENTS,
|
|
150
|
+
}),
|
|
151
|
+
verify: EvolutionLedger.prototype.verify.bind(ledger),
|
|
152
|
+
appendDomainEvent:
|
|
153
|
+
EvolutionLedger.prototype.appendDomainEvent.bind(ledger),
|
|
154
|
+
});
|
|
155
|
+
this.#put =
|
|
156
|
+
EvolutionArtifactPorts.prototype.putCanonical.bind(artifactPorts);
|
|
157
|
+
this.#resolve = ledgerArtifactResolver;
|
|
158
|
+
this.#source = projectionSource;
|
|
159
|
+
this.#requestHuman = method(humanDecisionProvider, "request");
|
|
160
|
+
this.#verifyHuman = method(humanDecisionVerifier, "verify");
|
|
161
|
+
this.#now = now;
|
|
162
|
+
this.#review = new SkillPromotionReviewLedgerAdapter({
|
|
163
|
+
descriptor: d,
|
|
164
|
+
artifactPorts: { putCanonical: this.#put },
|
|
165
|
+
ledger: this.#ledger,
|
|
166
|
+
ledgerArtifactResolver,
|
|
167
|
+
decisionVerifier: { verify: method(decisionVerifier, "verify") },
|
|
168
|
+
now,
|
|
169
|
+
});
|
|
170
|
+
const reader = Object.freeze({
|
|
171
|
+
descriptor: d,
|
|
172
|
+
matchesLedger: (value) => value === ledger,
|
|
173
|
+
read: ({ tenantId, projectionDigest }) => {
|
|
174
|
+
if (tenantId !== d.tenantId)
|
|
175
|
+
fail("Workbench projection tenant differs");
|
|
176
|
+
const entry = this.#projection(projectionDigest);
|
|
177
|
+
return capture({
|
|
178
|
+
projection: entry.value,
|
|
179
|
+
artifactRef: entry.event.subjectRef,
|
|
180
|
+
sequence: entry.event.sequence,
|
|
181
|
+
eventDigest: entry.event.eventDigest,
|
|
182
|
+
});
|
|
183
|
+
},
|
|
184
|
+
readReview: (packetDigest) => this.#review.readReview(packetDigest),
|
|
185
|
+
});
|
|
186
|
+
PROJECTION_READERS.add(reader);
|
|
187
|
+
ADAPTER_PROJECTION_READERS.set(this, reader);
|
|
188
|
+
Object.freeze(this);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
createProjectionReader() {
|
|
192
|
+
return ADAPTER_PROJECTION_READERS.get(this);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
#stable(head) {
|
|
196
|
+
if (this.#ledger.verify().headDigest !== head.headDigest)
|
|
197
|
+
fail(
|
|
198
|
+
"Workbench Ledger changed during authentication; retry from durable state",
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
#scope(value) {
|
|
202
|
+
if (
|
|
203
|
+
value?.tenantId !== this.descriptor.tenantId ||
|
|
204
|
+
value.runId !== this.descriptor.runId ||
|
|
205
|
+
value.skillName !== this.descriptor.skillName
|
|
206
|
+
)
|
|
207
|
+
fail("Workbench record crossed its tenant/run/Skill scope");
|
|
208
|
+
return value;
|
|
209
|
+
}
|
|
210
|
+
#records() {
|
|
211
|
+
const head = this.#ledger.verify();
|
|
212
|
+
const events = this.#ledger.read();
|
|
213
|
+
if (events.length !== head.sequence)
|
|
214
|
+
fail("Workbench Ledger history is incomplete");
|
|
215
|
+
const eventTypes = new Set(Object.values(TYPES).map(([, type]) => type));
|
|
216
|
+
const selected = events.filter(
|
|
217
|
+
(event) =>
|
|
218
|
+
event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
|
|
219
|
+
eventTypes.has(event.type) &&
|
|
220
|
+
event.tenantId === this.descriptor.tenantId &&
|
|
221
|
+
event.correlationId === this.descriptor.streamId,
|
|
222
|
+
);
|
|
223
|
+
if (selected.length > 10_000)
|
|
224
|
+
fail("Workbench review history exceeds its bounded capacity");
|
|
225
|
+
const result = selected.map((event) => {
|
|
226
|
+
const type = Object.values(TYPES).find(
|
|
227
|
+
([, value]) => value === event.type,
|
|
228
|
+
)[0];
|
|
229
|
+
if (
|
|
230
|
+
event.artifactTenantId !== this.descriptor.artifactTenantId ||
|
|
231
|
+
event.skillName !== this.descriptor.skillName ||
|
|
232
|
+
event.decision !== "committed" ||
|
|
233
|
+
event.reason !== type
|
|
234
|
+
)
|
|
235
|
+
fail("Workbench event durable scope is invalid");
|
|
236
|
+
const resolved = this.#resolve({
|
|
237
|
+
epoch: head.epoch,
|
|
238
|
+
ledgerId: head.ledgerId,
|
|
239
|
+
tenantId: this.descriptor.artifactTenantId,
|
|
240
|
+
ref: event.subjectRef,
|
|
241
|
+
});
|
|
242
|
+
if (
|
|
243
|
+
resolved?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
|
|
244
|
+
resolved.authenticated !== true ||
|
|
245
|
+
resolved.found !== true ||
|
|
246
|
+
resolved.ref !== event.subjectRef.ref ||
|
|
247
|
+
resolved.digest !== event.subjectRef.digest ||
|
|
248
|
+
!Buffer.isBuffer(resolved.bytes) ||
|
|
249
|
+
resolved.bytes.length > 1024 * 1024 ||
|
|
250
|
+
`sha256:${createHash("sha256").update(resolved.bytes).digest("hex")}` !==
|
|
251
|
+
event.subjectRef.digest
|
|
252
|
+
)
|
|
253
|
+
fail("Workbench artifact resolution was substituted");
|
|
254
|
+
const record = capture(JSON.parse(resolved.bytes.toString("utf8")));
|
|
255
|
+
if (
|
|
256
|
+
canonical(record) !== resolved.bytes.toString("utf8") ||
|
|
257
|
+
record.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
|
|
258
|
+
record.tenantId !== this.descriptor.artifactTenantId ||
|
|
259
|
+
record.type !== type ||
|
|
260
|
+
record.audience !== this.descriptor.audience ||
|
|
261
|
+
record.purpose !== this.descriptor.purpose ||
|
|
262
|
+
record.retention !== "ledger"
|
|
263
|
+
)
|
|
264
|
+
fail("Workbench artifact durable binding is invalid");
|
|
265
|
+
const value = this.#scope(record.value);
|
|
266
|
+
const kind = Object.keys(TYPES).find((name) => TYPES[name][0] === type);
|
|
267
|
+
const key =
|
|
268
|
+
kind === "projection"
|
|
269
|
+
? value.projectionDigest
|
|
270
|
+
: kind === "prepared"
|
|
271
|
+
? value.request?.requestDigest
|
|
272
|
+
: value.requestDigest;
|
|
273
|
+
if (
|
|
274
|
+
!DIGEST.test(key ?? "") ||
|
|
275
|
+
event.eventId !== `${event.type}.${key.slice(7)}` ||
|
|
276
|
+
event.sourceRefs.length !== (kind === "projection" ? 0 : 2) ||
|
|
277
|
+
(kind === "prepared" &&
|
|
278
|
+
value.schema !== WORKBENCH_REVIEW_PREPARATION_SCHEMA) ||
|
|
279
|
+
(kind === "committed" &&
|
|
280
|
+
value.schema !== WORKBENCH_REVIEW_SETTLEMENT_SCHEMA)
|
|
281
|
+
)
|
|
282
|
+
fail("Workbench event identity or schema is invalid");
|
|
283
|
+
return { event, value };
|
|
284
|
+
});
|
|
285
|
+
this.#stable(head);
|
|
286
|
+
return { head, records: result };
|
|
287
|
+
}
|
|
288
|
+
#find(kind, key, snapshot = this.#records()) {
|
|
289
|
+
if (!DIGEST.test(key ?? "")) fail("Workbench record key is invalid");
|
|
290
|
+
const eventId = `${TYPES[kind][1]}.${key.slice(7)}`;
|
|
291
|
+
const matches = snapshot.records.filter(
|
|
292
|
+
({ event }) => event.eventId === eventId,
|
|
293
|
+
);
|
|
294
|
+
if (matches.length > 1) fail("Workbench record has duplicate events");
|
|
295
|
+
if (matches[0] && matches[0].event.type !== TYPES[kind][1])
|
|
296
|
+
fail("Workbench event type was substituted");
|
|
297
|
+
return matches[0] ?? null;
|
|
298
|
+
}
|
|
299
|
+
#projection(projectionDigest, snapshot = this.#records()) {
|
|
300
|
+
const entry = this.#find("projection", projectionDigest, snapshot);
|
|
301
|
+
if (
|
|
302
|
+
!entry ||
|
|
303
|
+
entry.value.projectionDigest !== projectionDigest ||
|
|
304
|
+
entry.event.sourceRefs.length !== 0
|
|
305
|
+
)
|
|
306
|
+
fail("Workbench retained source projection is missing or substituted");
|
|
307
|
+
filterEvolutionWorkbenchProjection(entry.value, { limit: 1 });
|
|
308
|
+
return entry;
|
|
309
|
+
}
|
|
310
|
+
#append(kind, key, value, sourceRefs, head) {
|
|
311
|
+
sourceRefs = sortedRefs(sourceRefs);
|
|
312
|
+
const [type, eventType] = TYPES[kind];
|
|
313
|
+
const eventId = `${eventType}.${key.slice(7)}`;
|
|
314
|
+
const check = () => {
|
|
315
|
+
const entry = this.#find(kind, key);
|
|
316
|
+
if (
|
|
317
|
+
!entry ||
|
|
318
|
+
!same(entry.value, value) ||
|
|
319
|
+
!same(entry.event.sourceRefs, sourceRefs)
|
|
320
|
+
)
|
|
321
|
+
fail(
|
|
322
|
+
"Workbench durable record is absent or conflicts with this request",
|
|
323
|
+
);
|
|
324
|
+
return entry;
|
|
325
|
+
};
|
|
326
|
+
this.#stable(head);
|
|
327
|
+
const published = this.#put(type, value, {
|
|
328
|
+
audience: this.descriptor.audience,
|
|
329
|
+
purpose: this.descriptor.purpose,
|
|
330
|
+
retention: "ledger",
|
|
331
|
+
});
|
|
332
|
+
if (
|
|
333
|
+
published?.receipt?.persisted !== true ||
|
|
334
|
+
published.receipt.readbackVerified !== true ||
|
|
335
|
+
published.receipt.integrityVerified !== true ||
|
|
336
|
+
published.receipt.retention !== "ledger"
|
|
337
|
+
)
|
|
338
|
+
fail("Workbench record was not durably retained");
|
|
339
|
+
try {
|
|
340
|
+
const receipt = this.#ledger.appendDomainEvent(
|
|
341
|
+
{
|
|
342
|
+
artifactTenantId: this.descriptor.artifactTenantId,
|
|
343
|
+
correlationId: this.descriptor.streamId,
|
|
344
|
+
decision: "committed",
|
|
345
|
+
eventId,
|
|
346
|
+
reason: type,
|
|
347
|
+
skillName: this.descriptor.skillName,
|
|
348
|
+
sourceRefs,
|
|
349
|
+
subjectRef: published.ref,
|
|
350
|
+
tenantId: this.descriptor.tenantId,
|
|
351
|
+
timestamp: new Date(Number(this.#now())).toISOString(),
|
|
352
|
+
type: eventType,
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
expectedHeadDigest: head.headDigest,
|
|
356
|
+
expectedSequence: head.sequence,
|
|
357
|
+
},
|
|
358
|
+
);
|
|
359
|
+
if (
|
|
360
|
+
receipt?.authenticated !== true ||
|
|
361
|
+
receipt.durable !== true ||
|
|
362
|
+
receipt.eventId !== eventId
|
|
363
|
+
)
|
|
364
|
+
fail("Workbench Ledger append was not durable");
|
|
365
|
+
} catch (cause) {
|
|
366
|
+
// A lost acknowledgement is recoverable only from exact authenticated
|
|
367
|
+
// bytes; a failed CAS or conflicting response is never an empty success.
|
|
368
|
+
try {
|
|
369
|
+
return check();
|
|
370
|
+
} catch {
|
|
371
|
+
throw cause;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return check();
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async loadCurrentProjection() {
|
|
378
|
+
const head = this.#ledger.verify();
|
|
379
|
+
const result = await buildEvolutionWorkbenchProjection(this.#source, {
|
|
380
|
+
observedAt: new Date(Number(this.#now())).toISOString(),
|
|
381
|
+
});
|
|
382
|
+
this.#stable(head);
|
|
383
|
+
return capture(this.#scope(result));
|
|
384
|
+
}
|
|
385
|
+
async retainProjection({ tenantId, projection: input }) {
|
|
386
|
+
if (tenantId !== this.descriptor.tenantId)
|
|
387
|
+
fail("Workbench projection tenant differs");
|
|
388
|
+
const projection = this.#scope(capture(input));
|
|
389
|
+
filterEvolutionWorkbenchProjection(projection, { limit: 1 });
|
|
390
|
+
const snapshot = this.#records();
|
|
391
|
+
const existing = this.#find(
|
|
392
|
+
"projection",
|
|
393
|
+
projection.projectionDigest,
|
|
394
|
+
snapshot,
|
|
395
|
+
);
|
|
396
|
+
if (existing) {
|
|
397
|
+
if (
|
|
398
|
+
!same(
|
|
399
|
+
this.#projection(projection.projectionDigest, snapshot).value,
|
|
400
|
+
projection,
|
|
401
|
+
)
|
|
402
|
+
)
|
|
403
|
+
fail("Workbench retained projection differs");
|
|
404
|
+
} else {
|
|
405
|
+
const rebuilt = await buildEvolutionWorkbenchProjection(this.#source, {
|
|
406
|
+
observedAt: projection.observedAt,
|
|
407
|
+
});
|
|
408
|
+
if (!same(rebuilt, projection))
|
|
409
|
+
fail("Workbench projection differs from its authenticated source");
|
|
410
|
+
this.#stable(snapshot.head);
|
|
411
|
+
this.#append(
|
|
412
|
+
"projection",
|
|
413
|
+
projection.projectionDigest,
|
|
414
|
+
projection,
|
|
415
|
+
[],
|
|
416
|
+
snapshot.head,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
authenticated: true,
|
|
421
|
+
durable: true,
|
|
422
|
+
projectionDigest: projection.projectionDigest,
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
async #context(input) {
|
|
427
|
+
const { plan: rawPlan, request: rawRequest } = capture(input);
|
|
428
|
+
const plan = this.#scope(
|
|
429
|
+
verifyWorkbenchBatchPlan(rawPlan, this.descriptor.tenantId),
|
|
430
|
+
);
|
|
431
|
+
const snapshot = this.#records();
|
|
432
|
+
const projection = this.#projection(plan.sourceProjectionDigest, snapshot);
|
|
433
|
+
verifyWorkbenchBatchPlan(plan, this.descriptor.tenantId, projection.value);
|
|
434
|
+
const review = await this.#review.readReview(rawRequest.packetDigest);
|
|
435
|
+
const request = buildWorkbenchBatchItemRequest(plan, review.packet);
|
|
436
|
+
const candidate = projection.value.candidates.find(
|
|
437
|
+
(entry) => entry.packetDigest === request.packetDigest,
|
|
438
|
+
);
|
|
439
|
+
if (
|
|
440
|
+
!same(request, rawRequest) ||
|
|
441
|
+
candidate?.candidateId !== review.packet.candidateId ||
|
|
442
|
+
candidate?.candidateContentDigest !==
|
|
443
|
+
review.packet.candidateContentDigest ||
|
|
444
|
+
review.packetSequence >= projection.event.sequence
|
|
445
|
+
)
|
|
446
|
+
fail(
|
|
447
|
+
"Workbench review request differs from its retained projection or actual packet",
|
|
448
|
+
);
|
|
449
|
+
this.#stable(snapshot.head);
|
|
450
|
+
return { plan, request, review, projection, snapshot };
|
|
451
|
+
}
|
|
452
|
+
async #state(context, historicalPreparation = false) {
|
|
453
|
+
const { plan, request, review, projection, snapshot } = context;
|
|
454
|
+
const prepared = this.#find("prepared", request.requestDigest, snapshot);
|
|
455
|
+
const committed = this.#find("committed", request.requestDigest, snapshot);
|
|
456
|
+
if (!prepared) {
|
|
457
|
+
if (committed) fail("Workbench settlement has no preparation");
|
|
458
|
+
return null;
|
|
459
|
+
}
|
|
460
|
+
const response = prepared.value.response;
|
|
461
|
+
const expected = {
|
|
462
|
+
schema: WORKBENCH_REVIEW_PREPARATION_SCHEMA,
|
|
463
|
+
tenantId: plan.tenantId,
|
|
464
|
+
runId: plan.runId,
|
|
465
|
+
skillName: plan.skillName,
|
|
466
|
+
plan,
|
|
467
|
+
request,
|
|
468
|
+
response,
|
|
469
|
+
};
|
|
470
|
+
if (
|
|
471
|
+
!same(prepared.value, expected) ||
|
|
472
|
+
!same(
|
|
473
|
+
prepared.event.sourceRefs,
|
|
474
|
+
sortedRefs([projection.event.subjectRef, review.packetRef]),
|
|
475
|
+
) ||
|
|
476
|
+
prepared.event.sequence <= projection.event.sequence
|
|
477
|
+
)
|
|
478
|
+
fail("Workbench preparation binding is invalid");
|
|
479
|
+
if (
|
|
480
|
+
review.decision &&
|
|
481
|
+
(!same(review.decision, response.decision) ||
|
|
482
|
+
review.decisionSequence <= prepared.event.sequence)
|
|
483
|
+
)
|
|
484
|
+
fail("Workbench actual review decision conflicts with its preparation");
|
|
485
|
+
verifyWorkbenchHumanDecisionResponse(
|
|
486
|
+
response,
|
|
487
|
+
request,
|
|
488
|
+
review.packet,
|
|
489
|
+
review.decision
|
|
490
|
+
? Date.parse(response.decision.decidedAt)
|
|
491
|
+
: historicalPreparation
|
|
492
|
+
? Date.parse(prepared.event.timestamp)
|
|
493
|
+
: Number(this.#now()),
|
|
494
|
+
);
|
|
495
|
+
if ((await this.#verifyHuman({ request, response })) !== true)
|
|
496
|
+
fail("Workbench human decision signature verification failed");
|
|
497
|
+
this.#stable(snapshot.head);
|
|
498
|
+
const item = buildWorkbenchExecutionItem(request, response);
|
|
499
|
+
if (committed) {
|
|
500
|
+
const expectedSettlement = this.#settlement(
|
|
501
|
+
plan,
|
|
502
|
+
request,
|
|
503
|
+
response,
|
|
504
|
+
item,
|
|
505
|
+
);
|
|
506
|
+
if (
|
|
507
|
+
!review.decision ||
|
|
508
|
+
!same(committed.value, expectedSettlement) ||
|
|
509
|
+
committed.event.sequence <= review.decisionSequence ||
|
|
510
|
+
!same(
|
|
511
|
+
committed.event.sourceRefs,
|
|
512
|
+
sortedRefs([prepared.event.subjectRef, review.decisionRef]),
|
|
513
|
+
)
|
|
514
|
+
)
|
|
515
|
+
fail("Workbench settlement has no exact authenticated review effect");
|
|
516
|
+
}
|
|
517
|
+
return capture({
|
|
518
|
+
status: committed
|
|
519
|
+
? "committed"
|
|
520
|
+
: review.decision
|
|
521
|
+
? "applied"
|
|
522
|
+
: "prepared",
|
|
523
|
+
response,
|
|
524
|
+
item,
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
#settlement(plan, request, response, item) {
|
|
528
|
+
return capture({
|
|
529
|
+
schema: WORKBENCH_REVIEW_SETTLEMENT_SCHEMA,
|
|
530
|
+
tenantId: plan.tenantId,
|
|
531
|
+
runId: plan.runId,
|
|
532
|
+
skillName: plan.skillName,
|
|
533
|
+
planDigest: plan.planDigest,
|
|
534
|
+
requestDigest: request.requestDigest,
|
|
535
|
+
responseDigest: response.responseDigest,
|
|
536
|
+
item,
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
async loadExecutionItem(input) {
|
|
540
|
+
return this.#state(await this.#context(input));
|
|
541
|
+
}
|
|
542
|
+
async prepareDecision(input) {
|
|
543
|
+
const { response: rawResponse, ...binding } = capture(input);
|
|
544
|
+
const context = await this.#context(binding);
|
|
545
|
+
const existing = await this.#state(context);
|
|
546
|
+
const { plan, request, review, projection, snapshot } = context;
|
|
547
|
+
if (existing) {
|
|
548
|
+
if (!same(existing.response, rawResponse))
|
|
549
|
+
fail("Workbench human response conflicts with prepared decision");
|
|
550
|
+
} else {
|
|
551
|
+
if (review.decision)
|
|
552
|
+
fail("Workbench packet already has a decision outside this request");
|
|
553
|
+
const response = verifyWorkbenchHumanDecisionResponse(
|
|
554
|
+
rawResponse,
|
|
555
|
+
request,
|
|
556
|
+
review.packet,
|
|
557
|
+
Number(this.#now()),
|
|
558
|
+
);
|
|
559
|
+
if ((await this.#verifyHuman({ request, response })) !== true)
|
|
560
|
+
fail("Workbench human decision signature verification failed");
|
|
561
|
+
this.#stable(snapshot.head);
|
|
562
|
+
this.#append(
|
|
563
|
+
"prepared",
|
|
564
|
+
request.requestDigest,
|
|
565
|
+
capture({
|
|
566
|
+
schema: WORKBENCH_REVIEW_PREPARATION_SCHEMA,
|
|
567
|
+
tenantId: plan.tenantId,
|
|
568
|
+
runId: plan.runId,
|
|
569
|
+
skillName: plan.skillName,
|
|
570
|
+
plan,
|
|
571
|
+
request,
|
|
572
|
+
response,
|
|
573
|
+
}),
|
|
574
|
+
[projection.event.subjectRef, review.packetRef],
|
|
575
|
+
snapshot.head,
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
return {
|
|
579
|
+
authenticated: true,
|
|
580
|
+
durable: true,
|
|
581
|
+
responseDigest: rawResponse.responseDigest,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
async retainDecision(input) {
|
|
585
|
+
const data = capture(input);
|
|
586
|
+
const state = await this.loadExecutionItem({
|
|
587
|
+
plan: data.plan,
|
|
588
|
+
request: data.request,
|
|
589
|
+
});
|
|
590
|
+
if (
|
|
591
|
+
!state ||
|
|
592
|
+
!same(state.response, data.response) ||
|
|
593
|
+
!same(state.response.decision, data.decision) ||
|
|
594
|
+
data.packetDigest !== data.request.packetDigest
|
|
595
|
+
)
|
|
596
|
+
fail("Workbench decision has no exact durable preparation");
|
|
597
|
+
if (state.status === "prepared")
|
|
598
|
+
await this.#review.retainDecision({
|
|
599
|
+
packetDigest: data.packetDigest,
|
|
600
|
+
decision: data.decision,
|
|
601
|
+
});
|
|
602
|
+
const readback = await this.loadExecutionItem({
|
|
603
|
+
plan: data.plan,
|
|
604
|
+
request: data.request,
|
|
605
|
+
});
|
|
606
|
+
if (!readback || readback.status === "prepared")
|
|
607
|
+
fail("Workbench actual review effect is missing");
|
|
608
|
+
return { persisted: true, receiptDigest: data.decision.receiptDigest };
|
|
609
|
+
}
|
|
610
|
+
async commitExecutionItem(input) {
|
|
611
|
+
const data = capture(input);
|
|
612
|
+
const context = await this.#context({
|
|
613
|
+
plan: data.plan,
|
|
614
|
+
request: data.request,
|
|
615
|
+
});
|
|
616
|
+
const state = await this.#state(context);
|
|
617
|
+
if (
|
|
618
|
+
!state ||
|
|
619
|
+
state.status === "prepared" ||
|
|
620
|
+
!same(state.response, data.response) ||
|
|
621
|
+
!same(state.item, data.item)
|
|
622
|
+
)
|
|
623
|
+
fail("Workbench execution has no exact authenticated review effect");
|
|
624
|
+
if (state.status !== "committed") {
|
|
625
|
+
const prepared = this.#find(
|
|
626
|
+
"prepared",
|
|
627
|
+
data.request.requestDigest,
|
|
628
|
+
context.snapshot,
|
|
629
|
+
);
|
|
630
|
+
this.#append(
|
|
631
|
+
"committed",
|
|
632
|
+
data.request.requestDigest,
|
|
633
|
+
this.#settlement(data.plan, data.request, data.response, data.item),
|
|
634
|
+
[prepared.event.subjectRef, context.review.decisionRef],
|
|
635
|
+
context.snapshot.head,
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
const readback = await this.loadExecutionItem({
|
|
639
|
+
plan: data.plan,
|
|
640
|
+
request: data.request,
|
|
641
|
+
});
|
|
642
|
+
if (readback?.status !== "committed")
|
|
643
|
+
fail("Workbench settlement readback is missing");
|
|
644
|
+
return {
|
|
645
|
+
authenticated: true,
|
|
646
|
+
durable: true,
|
|
647
|
+
itemDigest: readback.item.itemDigest,
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
createExecutor() {
|
|
651
|
+
return new EvolutionWorkbenchBatchExecutor({
|
|
652
|
+
tenantId: this.descriptor.tenantId,
|
|
653
|
+
now: this.#now,
|
|
654
|
+
ports: {
|
|
655
|
+
loadProjection: async ({ tenantId, projectionDigest }) => {
|
|
656
|
+
if (tenantId !== this.descriptor.tenantId)
|
|
657
|
+
fail("Workbench projection tenant differs");
|
|
658
|
+
return this.#projection(projectionDigest).value;
|
|
659
|
+
},
|
|
660
|
+
resolvePacket: async ({ tenantId, packetDigest }) => {
|
|
661
|
+
if (tenantId !== this.descriptor.tenantId)
|
|
662
|
+
fail("Workbench packet tenant differs");
|
|
663
|
+
return (await this.#review.readReview(packetDigest)).packet;
|
|
664
|
+
},
|
|
665
|
+
requestHumanDecision: this.#requestHuman,
|
|
666
|
+
verifyHumanDecision: this.#verifyHuman,
|
|
667
|
+
loadExecutionItem: this.loadExecutionItem.bind(this),
|
|
668
|
+
prepareDecision: this.prepareDecision.bind(this),
|
|
669
|
+
retainDecision: this.retainDecision.bind(this),
|
|
670
|
+
commitExecutionItem: this.commitExecutionItem.bind(this),
|
|
671
|
+
},
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
// Startup may finish accounting for an existing effect, but must not issue
|
|
675
|
+
// new decisions or ask a human to continue an unfinished batch.
|
|
676
|
+
async reconcileCommitted() {
|
|
677
|
+
const snapshot = this.#records();
|
|
678
|
+
const applied = [];
|
|
679
|
+
const deferredRequestDigests = [];
|
|
680
|
+
for (const { event, value } of snapshot.records) {
|
|
681
|
+
if (
|
|
682
|
+
event.type === TYPES.committed[1] &&
|
|
683
|
+
!this.#find("prepared", value.requestDigest, snapshot)
|
|
684
|
+
)
|
|
685
|
+
fail("Workbench settlement has no preparation");
|
|
686
|
+
if (event.type !== TYPES.prepared[1]) continue;
|
|
687
|
+
const context = await this.#context({
|
|
688
|
+
plan: value.plan,
|
|
689
|
+
request: value.request,
|
|
690
|
+
});
|
|
691
|
+
// Audit a pending signature at its real durable preparation time; this
|
|
692
|
+
// never makes that signature valid for a new effect at the current time.
|
|
693
|
+
const state = await this.#state(context, true);
|
|
694
|
+
if (!state) fail("Workbench recovery preparation is missing");
|
|
695
|
+
if (state.status === "applied")
|
|
696
|
+
applied.push({
|
|
697
|
+
plan: value.plan,
|
|
698
|
+
request: value.request,
|
|
699
|
+
response: state.response,
|
|
700
|
+
item: state.item,
|
|
701
|
+
});
|
|
702
|
+
if (state.status === "prepared")
|
|
703
|
+
deferredRequestDigests.push(value.request.requestDigest);
|
|
704
|
+
}
|
|
705
|
+
this.#stable(snapshot.head);
|
|
706
|
+
const settledItems = [];
|
|
707
|
+
for (const item of applied) {
|
|
708
|
+
await this.commitExecutionItem(item);
|
|
709
|
+
settledItems.push(item.item);
|
|
710
|
+
}
|
|
711
|
+
return capture({ settledItems, deferredRequestDigests });
|
|
712
|
+
}
|
|
713
|
+
async resume() {
|
|
714
|
+
const snapshot = this.#records();
|
|
715
|
+
const plans = new Map();
|
|
716
|
+
for (const { event, value } of snapshot.records)
|
|
717
|
+
if (
|
|
718
|
+
event.type === TYPES.committed[1] &&
|
|
719
|
+
!this.#find("prepared", value.requestDigest, snapshot)
|
|
720
|
+
)
|
|
721
|
+
fail("Workbench settlement has no preparation");
|
|
722
|
+
for (const { event, value } of snapshot.records)
|
|
723
|
+
if (event.type === TYPES.prepared[1]) {
|
|
724
|
+
const plan = this.#scope(
|
|
725
|
+
verifyWorkbenchBatchPlan(value.plan, this.descriptor.tenantId),
|
|
726
|
+
);
|
|
727
|
+
const context = await this.#context({ plan, request: value.request });
|
|
728
|
+
const state = await this.#state(context);
|
|
729
|
+
if (!state) fail("Workbench recovery preparation is missing");
|
|
730
|
+
plans.set(plan.planDigest, plan);
|
|
731
|
+
}
|
|
732
|
+
this.#stable(snapshot.head);
|
|
733
|
+
const result = [];
|
|
734
|
+
const executor = this.createExecutor();
|
|
735
|
+
for (const plan of plans.values()) {
|
|
736
|
+
let incomplete = false;
|
|
737
|
+
for (const packetDigest of plan.packetDigests) {
|
|
738
|
+
const { packet } = await this.#review.readReview(packetDigest);
|
|
739
|
+
const request = buildWorkbenchBatchItemRequest(plan, packet);
|
|
740
|
+
const state = await this.loadExecutionItem({ plan, request });
|
|
741
|
+
if (state?.status !== "committed") incomplete = true;
|
|
742
|
+
}
|
|
743
|
+
if (incomplete) result.push(await executor.execute(plan));
|
|
744
|
+
}
|
|
745
|
+
return Object.freeze(result);
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
// Deployment assembly: Run and Review readers cannot be replaced with caller
|
|
750
|
+
// summaries. The genuine Registry source owns current state/workflow readers;
|
|
751
|
+
// outcome/Pilot authorities still belong to deployment. This supplies the real
|
|
752
|
+
// review leg, not identity or Registry rollback powers.
|
|
753
|
+
export function createEvolutionWorkbenchReviewRuntime(options = {}) {
|
|
754
|
+
const {
|
|
755
|
+
descriptor,
|
|
756
|
+
ledger,
|
|
757
|
+
artifactPorts,
|
|
758
|
+
ledgerArtifactResolver,
|
|
759
|
+
decisionVerifier,
|
|
760
|
+
registrySource,
|
|
761
|
+
invocationReceiptSource = null,
|
|
762
|
+
pilotSource = null,
|
|
763
|
+
now = Date.now,
|
|
764
|
+
} = options;
|
|
765
|
+
const capturedRegistry = captureWorkbenchRegistrySource(registrySource);
|
|
766
|
+
if (
|
|
767
|
+
!capturedRegistry.matchesLedger(ledger) ||
|
|
768
|
+
canonical(capturedRegistry.descriptor) !== canonical(descriptor) ||
|
|
769
|
+
Object.hasOwn(options, "transitionAdapter")
|
|
770
|
+
)
|
|
771
|
+
throw new TypeError(
|
|
772
|
+
"Workbench review runtime requires its own exact Registry source and no replacement transition adapter",
|
|
773
|
+
);
|
|
774
|
+
const fixedLedger = Object.freeze({
|
|
775
|
+
read: () =>
|
|
776
|
+
EvolutionLedger.prototype.read.call(ledger, {
|
|
777
|
+
limit: EVOLUTION_LEDGER_MAX_EVENTS,
|
|
778
|
+
}),
|
|
779
|
+
verify: EvolutionLedger.prototype.verify.bind(ledger),
|
|
780
|
+
appendDomainEvent: EvolutionLedger.prototype.appendDomainEvent.bind(ledger),
|
|
781
|
+
});
|
|
782
|
+
const shared = {
|
|
783
|
+
descriptor,
|
|
784
|
+
ledger: fixedLedger,
|
|
785
|
+
artifactPorts: {
|
|
786
|
+
putCanonical:
|
|
787
|
+
EvolutionArtifactPorts.prototype.putCanonical.bind(artifactPorts),
|
|
788
|
+
},
|
|
789
|
+
ledgerArtifactResolver,
|
|
790
|
+
now,
|
|
791
|
+
};
|
|
792
|
+
const runAdapter = new EvolutionRunLedgerAdapter(shared);
|
|
793
|
+
const reviewAdapter = new SkillPromotionReviewLedgerAdapter({
|
|
794
|
+
...shared,
|
|
795
|
+
decisionVerifier: { verify: method(decisionVerifier, "verify") },
|
|
796
|
+
});
|
|
797
|
+
const projectionSource = createEvolutionWorkbenchDataSource({
|
|
798
|
+
tenantId: descriptor.tenantId,
|
|
799
|
+
runId: descriptor.runId,
|
|
800
|
+
skillName: descriptor.skillName,
|
|
801
|
+
runAdapter,
|
|
802
|
+
reviewAdapter,
|
|
803
|
+
registrySource: capturedRegistry,
|
|
804
|
+
invocationReceiptSource,
|
|
805
|
+
pilotSource,
|
|
806
|
+
});
|
|
807
|
+
const adapter = new EvolutionWorkbenchReviewLedgerAdapter({
|
|
808
|
+
...options,
|
|
809
|
+
projectionSource,
|
|
810
|
+
});
|
|
811
|
+
return Object.freeze({
|
|
812
|
+
projectionLoader: Object.freeze({
|
|
813
|
+
load: adapter.loadCurrentProjection.bind(adapter),
|
|
814
|
+
}),
|
|
815
|
+
projectionAuthority: Object.freeze({
|
|
816
|
+
retain: adapter.retainProjection.bind(adapter),
|
|
817
|
+
}),
|
|
818
|
+
batchExecutor: adapter.createExecutor(),
|
|
819
|
+
projectionReader: adapter.createProjectionReader(),
|
|
820
|
+
reconcileCommitted: adapter.reconcileCommitted.bind(adapter),
|
|
821
|
+
resume: adapter.resume.bind(adapter),
|
|
822
|
+
});
|
|
823
|
+
}
|