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
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
EVOLUTION_ARTIFACT_STORE_FAILED_CODE,
|
|
13
13
|
EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
|
|
14
14
|
EvolutionArtifactPorts,
|
|
15
|
+
captureEvolutionLedgerBatchResolver,
|
|
15
16
|
} from "./evolution-artifact-ports.js";
|
|
16
17
|
import {
|
|
17
18
|
EVOLUTION_ARTIFACT_REF_SCHEMA,
|
|
@@ -35,18 +36,43 @@ import {
|
|
|
35
36
|
SKILL_RELEASE_LEDGER_PROJECTION_SCHEMA,
|
|
36
37
|
SKILL_RELEASE_STATE_LEDGER_MIGRATION_SCHEMA,
|
|
37
38
|
SKILL_RELEASE_STATE_MIGRATION_RECEIPT_SCHEMA,
|
|
39
|
+
verifySkillRelease,
|
|
38
40
|
verifySkillReleaseState,
|
|
39
41
|
verifySkillReleaseStateMigrationPlan,
|
|
40
42
|
} from "./skill-release-registry.js";
|
|
43
|
+
import {
|
|
44
|
+
GOVERNED_KNOWLEDGE_DEPENDENCY_PREPARED_EVENT_TYPE,
|
|
45
|
+
verifyGovernedKnowledgeDependencyPrepared,
|
|
46
|
+
} from "./governed-knowledge-dependency-ledger-executor.js";
|
|
47
|
+
import {
|
|
48
|
+
WIKI_LEDGER_EVENT_TYPE,
|
|
49
|
+
WikiMaintainerLedgerAdapter,
|
|
50
|
+
captureWikiRevisionReader,
|
|
51
|
+
} from "./wiki-maintainer-ledger-adapter.js";
|
|
41
52
|
|
|
42
53
|
export const EVOLUTION_LEDGER_PORTS_INVALID_CODE =
|
|
43
54
|
"CC_EVOLUTION_LEDGER_PORTS_INVALID";
|
|
55
|
+
const RELEASE_OPERATION_READERS = new WeakMap();
|
|
56
|
+
|
|
57
|
+
// This read-only recovery surface is minted only alongside real Ledger ports.
|
|
58
|
+
// Matching JSON, inherited methods or a caller-supplied query function cannot
|
|
59
|
+
// establish that a release operation actually committed.
|
|
60
|
+
export function captureSkillReleaseOperationReader(transactionLedger) {
|
|
61
|
+
const reader = RELEASE_OPERATION_READERS.get(transactionLedger);
|
|
62
|
+
if (!reader)
|
|
63
|
+
throw new TypeError("a branded release transaction ledger is required");
|
|
64
|
+
return reader;
|
|
65
|
+
}
|
|
44
66
|
export const EVOLUTION_LEDGER_PORTS_COLLISION_CODE =
|
|
45
67
|
"CC_EVOLUTION_LEDGER_PORTS_COLLISION";
|
|
46
68
|
export const EVOLUTION_LEDGER_PORTS_CORRUPT_CODE =
|
|
47
69
|
"CC_EVOLUTION_LEDGER_PORTS_CORRUPT";
|
|
48
70
|
export const EVOLUTION_LEDGER_PORTS_UNAVAILABLE_CODE =
|
|
49
71
|
"CC_EVOLUTION_LEDGER_PORTS_UNAVAILABLE";
|
|
72
|
+
export const EVOLUTION_LEDGER_CANDIDATE_REVOKED_CODE =
|
|
73
|
+
"CC_EVOLUTION_LEDGER_CANDIDATE_REVOKED";
|
|
74
|
+
export const EVOLUTION_LEDGER_SOURCE_REVOKED_CODE =
|
|
75
|
+
"CC_EVOLUTION_LEDGER_SOURCE_REVOKED";
|
|
50
76
|
export const EVOLUTION_ARTIFACT_DURABILITY_BINDING_SCHEMA =
|
|
51
77
|
"chainlesschain.evolution-artifact-durability-binding/v1";
|
|
52
78
|
export const EVOLUTION_ARTIFACT_DURABILITY_RETAIN_REQUEST_SCHEMA =
|
|
@@ -1127,6 +1153,7 @@ class EvolutionLedgerDomainPorts {
|
|
|
1127
1153
|
#appendDomainEvent;
|
|
1128
1154
|
#artifactPut;
|
|
1129
1155
|
#artifactResolve;
|
|
1156
|
+
#artifactResolveBatch;
|
|
1130
1157
|
#artifactTenantId;
|
|
1131
1158
|
#audience;
|
|
1132
1159
|
#durabilityAuthority;
|
|
@@ -1134,6 +1161,7 @@ class EvolutionLedgerDomainPorts {
|
|
|
1134
1161
|
#durabilityRetain;
|
|
1135
1162
|
#ledgerQuery;
|
|
1136
1163
|
#ledgerRead;
|
|
1164
|
+
#ledgerVerify;
|
|
1137
1165
|
#ledgerVerifyReceipt;
|
|
1138
1166
|
#purpose;
|
|
1139
1167
|
|
|
@@ -1161,6 +1189,9 @@ class EvolutionLedgerDomainPorts {
|
|
|
1161
1189
|
this.#ledgerRead = Object.freeze(
|
|
1162
1190
|
EvolutionLedger.prototype.read.bind(ledger),
|
|
1163
1191
|
);
|
|
1192
|
+
this.#ledgerVerify = Object.freeze(
|
|
1193
|
+
EvolutionLedger.prototype.verify.bind(ledger),
|
|
1194
|
+
);
|
|
1164
1195
|
this.#ledgerVerifyReceipt = Object.freeze(
|
|
1165
1196
|
EvolutionLedger.prototype.verifyReceipt.bind(ledger),
|
|
1166
1197
|
);
|
|
@@ -1172,6 +1203,9 @@ class EvolutionLedgerDomainPorts {
|
|
|
1172
1203
|
artifactPorts,
|
|
1173
1204
|
Object.freeze({ purpose: this.#purpose }),
|
|
1174
1205
|
);
|
|
1206
|
+
this.#artifactResolveBatch = captureEvolutionLedgerBatchResolver(
|
|
1207
|
+
this.#artifactResolve,
|
|
1208
|
+
);
|
|
1175
1209
|
Object.freeze(this);
|
|
1176
1210
|
}
|
|
1177
1211
|
|
|
@@ -1452,26 +1486,32 @@ class EvolutionLedgerDomainPorts {
|
|
|
1452
1486
|
return ref;
|
|
1453
1487
|
}
|
|
1454
1488
|
|
|
1455
|
-
#resolveSubject(
|
|
1489
|
+
#resolveSubject(
|
|
1490
|
+
event,
|
|
1491
|
+
expectedType,
|
|
1492
|
+
expectedAudience = null,
|
|
1493
|
+
capturedResolution = null,
|
|
1494
|
+
) {
|
|
1456
1495
|
const ref = normalizeArtifactRef(
|
|
1457
1496
|
event.subjectRef,
|
|
1458
1497
|
"domain event subjectRef",
|
|
1459
1498
|
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
1460
1499
|
);
|
|
1461
1500
|
const durable = this.#resolveDurably(ref, expectedType);
|
|
1462
|
-
let resolution =
|
|
1501
|
+
let resolution = capturedResolution;
|
|
1463
1502
|
try {
|
|
1464
|
-
resolution
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1503
|
+
if (resolution === null)
|
|
1504
|
+
resolution = assertSynchronous(
|
|
1505
|
+
this.#artifactResolve(
|
|
1506
|
+
deepFreeze({
|
|
1507
|
+
epoch: event.epoch,
|
|
1508
|
+
ledgerId: event.ledgerId,
|
|
1509
|
+
ref,
|
|
1510
|
+
tenantId: this.#artifactTenantId,
|
|
1511
|
+
}),
|
|
1512
|
+
),
|
|
1513
|
+
"artifact resolver result",
|
|
1514
|
+
);
|
|
1475
1515
|
} catch {
|
|
1476
1516
|
// A removed/corrupt local cache is recoverable only through the trusted
|
|
1477
1517
|
// durability authority's exact canonical-byte replica above.
|
|
@@ -1698,7 +1738,40 @@ class EvolutionLedgerDomainPorts {
|
|
|
1698
1738
|
}
|
|
1699
1739
|
|
|
1700
1740
|
#snapshot() {
|
|
1701
|
-
|
|
1741
|
+
const snapshot = this.#indexSnapshot(this.#events());
|
|
1742
|
+
const types = new Set([
|
|
1743
|
+
EVENT_TYPES.prepare,
|
|
1744
|
+
EVENT_TYPES.finalize,
|
|
1745
|
+
EVENT_TYPES.migration,
|
|
1746
|
+
EVENT_TYPES.audit,
|
|
1747
|
+
]);
|
|
1748
|
+
const subjects = new Map();
|
|
1749
|
+
for (const event of snapshot.events) {
|
|
1750
|
+
if (types.has(event.type)) subjects.set(event.subjectRef.ref, event);
|
|
1751
|
+
// Bound retained byte buffers independently of total ledger size. Larger
|
|
1752
|
+
// histories keep the existing individually verified streaming path.
|
|
1753
|
+
if (subjects.size > 16) return snapshot;
|
|
1754
|
+
}
|
|
1755
|
+
if (subjects.size) {
|
|
1756
|
+
const events = [...subjects.values()];
|
|
1757
|
+
try {
|
|
1758
|
+
const results = this.#artifactResolveBatch(
|
|
1759
|
+
events.map((event) => ({
|
|
1760
|
+
epoch: event.epoch,
|
|
1761
|
+
ledgerId: event.ledgerId,
|
|
1762
|
+
ref: event.subjectRef,
|
|
1763
|
+
tenantId: this.#artifactTenantId,
|
|
1764
|
+
})),
|
|
1765
|
+
);
|
|
1766
|
+
snapshot.localResolutions = new Map(
|
|
1767
|
+
events.map((event, index) => [event.subjectRef.ref, results[index]]),
|
|
1768
|
+
);
|
|
1769
|
+
} catch {
|
|
1770
|
+
// As on individual reads, a missing local cache may recover only from
|
|
1771
|
+
// the independently authenticated exact-byte durability authority.
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
return snapshot;
|
|
1702
1775
|
}
|
|
1703
1776
|
|
|
1704
1777
|
#snapshotWithVerifiedEvent(snapshot, verification) {
|
|
@@ -1743,7 +1816,12 @@ class EvolutionLedgerDomainPorts {
|
|
|
1743
1816
|
const cacheKey = `${expectedType}\0${expectedAudience ?? ""}\0${ref.ref}\0${ref.digest}`;
|
|
1744
1817
|
let record = snapshot.subjects.get(cacheKey);
|
|
1745
1818
|
if (!record) {
|
|
1746
|
-
record = this.#resolveSubject(
|
|
1819
|
+
record = this.#resolveSubject(
|
|
1820
|
+
event,
|
|
1821
|
+
expectedType,
|
|
1822
|
+
expectedAudience,
|
|
1823
|
+
snapshot.localResolutions?.get(ref.ref) ?? null,
|
|
1824
|
+
);
|
|
1747
1825
|
snapshot.subjects.set(cacheKey, record);
|
|
1748
1826
|
}
|
|
1749
1827
|
return record;
|
|
@@ -2274,7 +2352,7 @@ class EvolutionLedgerDomainPorts {
|
|
|
2274
2352
|
return { existing: null, lineages, prepared };
|
|
2275
2353
|
}
|
|
2276
2354
|
|
|
2277
|
-
migrate(input) {
|
|
2355
|
+
migrate(input, releases) {
|
|
2278
2356
|
const migration = normalizeStateMigration(input);
|
|
2279
2357
|
const transactionId = migration.plan.stateMigrationDigest;
|
|
2280
2358
|
const eventId = deterministicEventId("migration", { transactionId });
|
|
@@ -2310,6 +2388,29 @@ class EvolutionLedgerDomainPorts {
|
|
|
2310
2388
|
"release state migration requires an empty Skill ledger lineage",
|
|
2311
2389
|
);
|
|
2312
2390
|
}
|
|
2391
|
+
if (releases !== undefined) {
|
|
2392
|
+
assertAllExactRecord(
|
|
2393
|
+
releases,
|
|
2394
|
+
new Set(["active", "lastKnownGood"]),
|
|
2395
|
+
"migration release evidence",
|
|
2396
|
+
);
|
|
2397
|
+
}
|
|
2398
|
+
for (const [key, releaseDigest] of [
|
|
2399
|
+
["active", migration.plan.activeReleaseDigest],
|
|
2400
|
+
["lastKnownGood", migration.plan.lastKnownGoodReleaseDigest],
|
|
2401
|
+
]) {
|
|
2402
|
+
this.#assertReleaseNotRevoked(
|
|
2403
|
+
snapshot,
|
|
2404
|
+
{
|
|
2405
|
+
tenantId: migration.plan.tenantId,
|
|
2406
|
+
skillName: migration.plan.skillName,
|
|
2407
|
+
audience: this.#audience,
|
|
2408
|
+
releaseDigest,
|
|
2409
|
+
candidateId: null,
|
|
2410
|
+
},
|
|
2411
|
+
releases?.[key],
|
|
2412
|
+
);
|
|
2413
|
+
}
|
|
2313
2414
|
const subjectRef = this.#putSubject(
|
|
2314
2415
|
ARTIFACT_TYPES.migration,
|
|
2315
2416
|
migration,
|
|
@@ -2367,65 +2468,365 @@ class EvolutionLedgerDomainPorts {
|
|
|
2367
2468
|
);
|
|
2368
2469
|
}
|
|
2369
2470
|
|
|
2370
|
-
|
|
2471
|
+
*#knowledgeRevocations(snapshot, tenantId, audience) {
|
|
2472
|
+
// A prepared revocation is already a durable admission fence. Waiting for
|
|
2473
|
+
// every dependency effect to settle would allow promotion while offline
|
|
2474
|
+
// recovery, active rollback or another dependency is still outstanding.
|
|
2475
|
+
// Scan all streams/devices in this tenant; a new controller cannot opt out.
|
|
2476
|
+
for (const event of snapshot.events) {
|
|
2477
|
+
if (
|
|
2478
|
+
event.type !== GOVERNED_KNOWLEDGE_DEPENDENCY_PREPARED_EVENT_TYPE ||
|
|
2479
|
+
event.tenantId !== tenantId
|
|
2480
|
+
)
|
|
2481
|
+
continue;
|
|
2482
|
+
if (
|
|
2483
|
+
event.schema !== EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA ||
|
|
2484
|
+
event.artifactTenantId !== this.#artifactTenantId ||
|
|
2485
|
+
event.decision !== "prepared" ||
|
|
2486
|
+
!Array.isArray(event.sourceRefs) ||
|
|
2487
|
+
event.sourceRefs.length !== 0
|
|
2488
|
+
) {
|
|
2489
|
+
throw portsError(
|
|
2490
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2491
|
+
"candidate revocation event binding is invalid",
|
|
2492
|
+
);
|
|
2493
|
+
}
|
|
2494
|
+
const ref = normalizeArtifactRef(
|
|
2495
|
+
event.subjectRef,
|
|
2496
|
+
"candidate revocation subjectRef",
|
|
2497
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2498
|
+
);
|
|
2499
|
+
// Knowledge records use their own durable ArtifactStore, not the release
|
|
2500
|
+
// replica. Missing or corrupt retained bytes must fail closed, never be
|
|
2501
|
+
// interpreted as the absence of a revocation.
|
|
2502
|
+
const resolution = assertSynchronous(
|
|
2503
|
+
this.#artifactResolve(
|
|
2504
|
+
deepFreeze({
|
|
2505
|
+
epoch: event.epoch,
|
|
2506
|
+
ledgerId: event.ledgerId,
|
|
2507
|
+
ref,
|
|
2508
|
+
tenantId: this.#artifactTenantId,
|
|
2509
|
+
}),
|
|
2510
|
+
),
|
|
2511
|
+
"candidate revocation artifact resolution",
|
|
2512
|
+
);
|
|
2513
|
+
assertAllExactRecord(
|
|
2514
|
+
resolution,
|
|
2515
|
+
LEDGER_RESOLUTION_KEYS,
|
|
2516
|
+
"candidate revocation artifact resolution",
|
|
2517
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2518
|
+
);
|
|
2519
|
+
if (
|
|
2520
|
+
resolution.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
|
|
2521
|
+
resolution.authenticated !== true ||
|
|
2522
|
+
resolution.found !== true ||
|
|
2523
|
+
resolution.ref !== ref.ref ||
|
|
2524
|
+
resolution.digest !== ref.digest
|
|
2525
|
+
) {
|
|
2526
|
+
throw portsError(
|
|
2527
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2528
|
+
"candidate revocation artifact is not authenticated and exactly bound",
|
|
2529
|
+
);
|
|
2530
|
+
}
|
|
2531
|
+
digest(
|
|
2532
|
+
resolution.receiptDigest,
|
|
2533
|
+
"candidate revocation artifact receiptDigest",
|
|
2534
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2535
|
+
);
|
|
2536
|
+
const bytes = copyBytes(resolution.bytes);
|
|
2537
|
+
if (sha256(bytes) !== ref.digest) {
|
|
2538
|
+
throw portsError(
|
|
2539
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2540
|
+
"candidate revocation artifact digest mismatch",
|
|
2541
|
+
);
|
|
2542
|
+
}
|
|
2543
|
+
const json = bufferToString(bytes, "utf8");
|
|
2544
|
+
let record;
|
|
2545
|
+
try {
|
|
2546
|
+
record = JSON.parse(json);
|
|
2547
|
+
} catch (cause) {
|
|
2548
|
+
throw portsError(
|
|
2549
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2550
|
+
"candidate revocation artifact is not JSON",
|
|
2551
|
+
{ cause },
|
|
2552
|
+
);
|
|
2553
|
+
}
|
|
2554
|
+
assertAllExactRecord(
|
|
2555
|
+
record,
|
|
2556
|
+
ARTIFACT_RECORD_KEYS,
|
|
2557
|
+
"candidate revocation artifact",
|
|
2558
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2559
|
+
);
|
|
2560
|
+
if (
|
|
2561
|
+
canonicalJson(record) !== json ||
|
|
2562
|
+
record.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
|
|
2563
|
+
record.tenantId !== this.#artifactTenantId ||
|
|
2564
|
+
record.type !== "governed-knowledge-dependency-operation" ||
|
|
2565
|
+
record.retention !== "ledger" ||
|
|
2566
|
+
record.purpose !== this.#purpose ||
|
|
2567
|
+
record.audience !== audience
|
|
2568
|
+
) {
|
|
2569
|
+
throw portsError(
|
|
2570
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2571
|
+
"candidate revocation artifact boundary is invalid",
|
|
2572
|
+
);
|
|
2573
|
+
}
|
|
2574
|
+
const prepared = verifyGovernedKnowledgeDependencyPrepared(record.value, {
|
|
2575
|
+
tenantId: event.tenantId,
|
|
2576
|
+
deviceId: record.value?.deviceId,
|
|
2577
|
+
});
|
|
2578
|
+
if (
|
|
2579
|
+
event.eventId !==
|
|
2580
|
+
`${GOVERNED_KNOWLEDGE_DEPENDENCY_PREPARED_EVENT_TYPE}.${prepared.operationDigest.slice(7)}`
|
|
2581
|
+
) {
|
|
2582
|
+
throw portsError(
|
|
2583
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2584
|
+
"candidate revocation event does not bind its prepared operation",
|
|
2585
|
+
);
|
|
2586
|
+
}
|
|
2587
|
+
yield { event, prepared };
|
|
2588
|
+
}
|
|
2589
|
+
}
|
|
2590
|
+
|
|
2591
|
+
#assertReleaseNotRevoked(snapshot, binding, targetInput) {
|
|
2592
|
+
const assertCandidate = (prepared, candidateId) => {
|
|
2593
|
+
if (
|
|
2594
|
+
prepared.knowledge.dependencies.some(
|
|
2595
|
+
(dependency) =>
|
|
2596
|
+
dependency.kind === "candidate" &&
|
|
2597
|
+
dependency.digest === candidateId &&
|
|
2598
|
+
["reject-candidate", "quarantine"].includes(dependency.disposition),
|
|
2599
|
+
)
|
|
2600
|
+
) {
|
|
2601
|
+
throw portsError(
|
|
2602
|
+
EVOLUTION_LEDGER_CANDIDATE_REVOKED_CODE,
|
|
2603
|
+
"candidate activation is blocked by a durable knowledge revocation",
|
|
2604
|
+
{
|
|
2605
|
+
candidateId,
|
|
2606
|
+
operationDigest: prepared.operationDigest,
|
|
2607
|
+
},
|
|
2608
|
+
);
|
|
2609
|
+
}
|
|
2610
|
+
};
|
|
2611
|
+
let target = null;
|
|
2612
|
+
const readTarget = () => {
|
|
2613
|
+
if (target) return target;
|
|
2614
|
+
let verified;
|
|
2615
|
+
try {
|
|
2616
|
+
verified = verifySkillRelease(targetInput);
|
|
2617
|
+
} catch (cause) {
|
|
2618
|
+
throw portsError(
|
|
2619
|
+
EVOLUTION_LEDGER_PORTS_INVALID_CODE,
|
|
2620
|
+
"release admission requires verified immutable target evidence",
|
|
2621
|
+
{ cause },
|
|
2622
|
+
);
|
|
2623
|
+
}
|
|
2624
|
+
if (
|
|
2625
|
+
verified.releaseDigest !== binding.releaseDigest ||
|
|
2626
|
+
verified.tenantId !== binding.tenantId ||
|
|
2627
|
+
verified.skillName !== binding.skillName ||
|
|
2628
|
+
(binding.candidateId !== null &&
|
|
2629
|
+
verified.candidateId !== binding.candidateId)
|
|
2630
|
+
) {
|
|
2631
|
+
throw portsError(
|
|
2632
|
+
EVOLUTION_LEDGER_PORTS_INVALID_CODE,
|
|
2633
|
+
"release admission evidence differs from the intended target",
|
|
2634
|
+
);
|
|
2635
|
+
}
|
|
2636
|
+
target = verified;
|
|
2637
|
+
return target;
|
|
2638
|
+
};
|
|
2639
|
+
// Stream authenticated revocations: do not retain every full Knowledge
|
|
2640
|
+
// artifact in memory or reuse authorization evidence across attempts.
|
|
2641
|
+
for (const { prepared } of this.#knowledgeRevocations(
|
|
2642
|
+
snapshot,
|
|
2643
|
+
binding.tenantId,
|
|
2644
|
+
binding.audience,
|
|
2645
|
+
)) {
|
|
2646
|
+
assertCandidate(prepared, binding.candidateId);
|
|
2647
|
+
readTarget();
|
|
2648
|
+
assertCandidate(prepared, target.candidateId);
|
|
2649
|
+
const knowledge = prepared.knowledge;
|
|
2650
|
+
const wiki = this.#releaseWikiProvenance(
|
|
2651
|
+
snapshot,
|
|
2652
|
+
binding,
|
|
2653
|
+
target,
|
|
2654
|
+
knowledge,
|
|
2655
|
+
);
|
|
2656
|
+
const sourceRef = `knowledge://${encodeURIComponent(binding.tenantId)}/${encodeURIComponent(knowledge.knowledgeId)}`;
|
|
2657
|
+
const revokedRelease = knowledge.dependencies.some(
|
|
2658
|
+
(dependency) =>
|
|
2659
|
+
dependency.kind === "active-skill" &&
|
|
2660
|
+
dependency.digest === target.releaseDigest,
|
|
2661
|
+
);
|
|
2662
|
+
if (
|
|
2663
|
+
revokedRelease ||
|
|
2664
|
+
wiki?.unsafePatternIds.length ||
|
|
2665
|
+
target.candidate.sourceEvidenceRefs.some(
|
|
2666
|
+
(item) =>
|
|
2667
|
+
item.ref === sourceRef || item.digest === knowledge.contentDigest,
|
|
2668
|
+
)
|
|
2669
|
+
) {
|
|
2670
|
+
throw portsError(
|
|
2671
|
+
EVOLUTION_LEDGER_SOURCE_REVOKED_CODE,
|
|
2672
|
+
"release activation references a durably revoked Knowledge source or release",
|
|
2673
|
+
{
|
|
2674
|
+
candidateId: target.candidateId,
|
|
2675
|
+
releaseDigest: target.releaseDigest,
|
|
2676
|
+
operationDigest: prepared.operationDigest,
|
|
2677
|
+
},
|
|
2678
|
+
);
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
// Bare legacy calls remain compatible only before any Knowledge revocation.
|
|
2682
|
+
// Once a fence exists, missing provenance must not mean unrelated/safe.
|
|
2683
|
+
if (targetInput !== undefined) readTarget();
|
|
2684
|
+
}
|
|
2685
|
+
|
|
2686
|
+
#releaseWikiProvenance(snapshot, binding, target, knowledge) {
|
|
2687
|
+
if (target.candidate.derivationMode === "wiki") {
|
|
2688
|
+
// Discover the original run on the same authenticated ledger. Neither a
|
|
2689
|
+
// configurable reader nor a self-reported safe subset establishes origin.
|
|
2690
|
+
const event = snapshot.byEventId.get(
|
|
2691
|
+
`wiki.revision.${target.candidate.wikiRevision.slice(5)}`,
|
|
2692
|
+
);
|
|
2693
|
+
if (
|
|
2694
|
+
!event ||
|
|
2695
|
+
event.type !== WIKI_LEDGER_EVENT_TYPE ||
|
|
2696
|
+
event.tenantId !== binding.tenantId ||
|
|
2697
|
+
event.artifactTenantId !== this.#artifactTenantId
|
|
2698
|
+
) {
|
|
2699
|
+
throw portsError(
|
|
2700
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
2701
|
+
"release admission cannot authenticate its original Wiki revision",
|
|
2702
|
+
);
|
|
2703
|
+
}
|
|
2704
|
+
const readOnly = () => {
|
|
2705
|
+
throw new TypeError("admission Wiki reader is read-only");
|
|
2706
|
+
};
|
|
2707
|
+
const adapter = new WikiMaintainerLedgerAdapter({
|
|
2708
|
+
descriptor: {
|
|
2709
|
+
tenantId: binding.tenantId,
|
|
2710
|
+
artifactTenantId: this.#artifactTenantId,
|
|
2711
|
+
evolutionRunId: event.correlationId,
|
|
2712
|
+
audience: binding.audience,
|
|
2713
|
+
purpose: this.#purpose,
|
|
2714
|
+
},
|
|
2715
|
+
artifactPorts: { putCanonical: readOnly },
|
|
2716
|
+
ledger: {
|
|
2717
|
+
read: this.#ledgerRead,
|
|
2718
|
+
verify: this.#ledgerVerify,
|
|
2719
|
+
appendDomainEvent: readOnly,
|
|
2720
|
+
},
|
|
2721
|
+
ledgerArtifactResolver: this.#artifactResolve,
|
|
2722
|
+
});
|
|
2723
|
+
const revision = captureWikiRevisionReader(
|
|
2724
|
+
adapter,
|
|
2725
|
+
).readKnowledgeProvenance({
|
|
2726
|
+
tenantId: binding.tenantId,
|
|
2727
|
+
revisionId: target.candidate.wikiRevision,
|
|
2728
|
+
knowledgeId: knowledge.knowledgeId,
|
|
2729
|
+
contentDigest: knowledge.contentDigest,
|
|
2730
|
+
});
|
|
2731
|
+
const tail = snapshot.events.at(-1);
|
|
2732
|
+
if (
|
|
2733
|
+
revision.ledgerHead.sequence !== tail.sequence ||
|
|
2734
|
+
revision.ledgerHead.headDigest !== tail.eventDigest ||
|
|
2735
|
+
["epoch", "ledgerId", "identityDigest"].some(
|
|
2736
|
+
(key) => revision.ledgerHead[key] !== tail[key],
|
|
2737
|
+
)
|
|
2738
|
+
) {
|
|
2739
|
+
throw portsError(
|
|
2740
|
+
EVOLUTION_LEDGER_PORTS_UNAVAILABLE_CODE,
|
|
2741
|
+
"ledger changed while checking immutable Wiki provenance",
|
|
2742
|
+
);
|
|
2743
|
+
}
|
|
2744
|
+
return revision;
|
|
2745
|
+
}
|
|
2746
|
+
return null;
|
|
2747
|
+
}
|
|
2748
|
+
|
|
2749
|
+
prepare(input, targetRelease) {
|
|
2371
2750
|
const intent = normalizeIntent(input);
|
|
2372
2751
|
this.#assertAudience(intent.mutationRequest.audience, "intent audience");
|
|
2373
2752
|
const eventId = deterministicEventId("prepare", {
|
|
2374
2753
|
transactionId: intent.transactionId,
|
|
2375
2754
|
});
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2755
|
+
for (let attempt = 0; attempt < MAX_FINALIZE_RETRIES; attempt += 1) {
|
|
2756
|
+
const snapshot = this.#snapshot();
|
|
2757
|
+
const existing = snapshot.byEventId.get(eventId);
|
|
2758
|
+
if (existing) {
|
|
2759
|
+
return this.#prepareProjection(
|
|
2760
|
+
this.#prepareFromSnapshot(snapshot, existing, {
|
|
2761
|
+
authorityReceiptDigest: intent.authorityReceiptDigest,
|
|
2762
|
+
intentDigest: intent.intentDigest,
|
|
2763
|
+
transactionId: intent.transactionId,
|
|
2764
|
+
}),
|
|
2765
|
+
);
|
|
2766
|
+
}
|
|
2767
|
+
const audit = this.#auditFromSnapshot(snapshot, intent.authorityReceipt);
|
|
2768
|
+
this.#assertReleaseNotRevoked(
|
|
2769
|
+
snapshot,
|
|
2770
|
+
{
|
|
2771
|
+
tenantId: intent.mutationRequest.tenantId,
|
|
2772
|
+
skillName: intent.skillName,
|
|
2773
|
+
audience: intent.mutationRequest.audience,
|
|
2774
|
+
releaseDigest: intent.targetReleaseDigest,
|
|
2775
|
+
candidateId: intent.candidateId,
|
|
2776
|
+
},
|
|
2777
|
+
targetRelease,
|
|
2778
|
+
);
|
|
2779
|
+
const subjectRef = this.#putSubject(
|
|
2780
|
+
ARTIFACT_TYPES.prepare,
|
|
2781
|
+
intent,
|
|
2782
|
+
intent.intentDigest,
|
|
2783
|
+
intent.mutationRequest.audience,
|
|
2784
|
+
);
|
|
2785
|
+
const eventInput = {
|
|
2786
|
+
artifactTenantId: this.#artifactTenantId,
|
|
2787
|
+
correlationId: intent.transactionId,
|
|
2788
|
+
decision: "prepared",
|
|
2789
|
+
eventId,
|
|
2790
|
+
reason: intent.intentDigest,
|
|
2791
|
+
skillName: intent.skillName,
|
|
2792
|
+
sourceRefs: [audit.event.subjectRef],
|
|
2793
|
+
subjectRef,
|
|
2794
|
+
tenantId: intent.mutationRequest.tenantId,
|
|
2795
|
+
type: EVENT_TYPES.prepare,
|
|
2796
|
+
};
|
|
2797
|
+
let persistedSnapshot;
|
|
2798
|
+
try {
|
|
2799
|
+
const previous = snapshot.events.at(-1) || null;
|
|
2800
|
+
const verification = this.#verifiedAppend(eventInput, {
|
|
2801
|
+
expectedHeadDigest: previous?.eventDigest ?? null,
|
|
2802
|
+
expectedSequence: previous?.sequence ?? 0,
|
|
2803
|
+
});
|
|
2804
|
+
persistedSnapshot =
|
|
2805
|
+
this.#snapshotWithVerifiedEvent(snapshot, verification) ||
|
|
2806
|
+
this.#snapshot();
|
|
2807
|
+
} catch (cause) {
|
|
2808
|
+
if (isHeadConflict(cause)) continue;
|
|
2809
|
+
if (!isCommitUnknown(cause) && !isEventConflict(cause)) throw cause;
|
|
2810
|
+
persistedSnapshot = this.#snapshot();
|
|
2811
|
+
}
|
|
2812
|
+
const persisted = persistedSnapshot.byEventId.get(eventId);
|
|
2813
|
+
if (!persisted) {
|
|
2814
|
+
throw portsError(
|
|
2815
|
+
EVOLUTION_LEDGER_PORTS_UNAVAILABLE_CODE,
|
|
2816
|
+
"release prepare append did not converge to a queryable event",
|
|
2817
|
+
);
|
|
2818
|
+
}
|
|
2379
2819
|
return this.#prepareProjection(
|
|
2380
|
-
this.#prepareFromSnapshot(
|
|
2820
|
+
this.#prepareFromSnapshot(persistedSnapshot, persisted, {
|
|
2381
2821
|
authorityReceiptDigest: intent.authorityReceiptDigest,
|
|
2382
2822
|
intentDigest: intent.intentDigest,
|
|
2383
2823
|
transactionId: intent.transactionId,
|
|
2384
2824
|
}),
|
|
2385
2825
|
);
|
|
2386
2826
|
}
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
intent,
|
|
2391
|
-
intent.intentDigest,
|
|
2392
|
-
intent.mutationRequest.audience,
|
|
2393
|
-
);
|
|
2394
|
-
const eventInput = {
|
|
2395
|
-
artifactTenantId: this.#artifactTenantId,
|
|
2396
|
-
correlationId: intent.transactionId,
|
|
2397
|
-
decision: "prepared",
|
|
2398
|
-
eventId,
|
|
2399
|
-
reason: intent.intentDigest,
|
|
2400
|
-
skillName: intent.skillName,
|
|
2401
|
-
sourceRefs: [audit.event.subjectRef],
|
|
2402
|
-
subjectRef,
|
|
2403
|
-
tenantId: intent.mutationRequest.tenantId,
|
|
2404
|
-
type: EVENT_TYPES.prepare,
|
|
2405
|
-
};
|
|
2406
|
-
let persistedSnapshot;
|
|
2407
|
-
try {
|
|
2408
|
-
const verification = this.#verifiedAppend(eventInput);
|
|
2409
|
-
persistedSnapshot =
|
|
2410
|
-
this.#snapshotWithVerifiedEvent(snapshot, verification) ||
|
|
2411
|
-
this.#snapshot();
|
|
2412
|
-
} catch (cause) {
|
|
2413
|
-
if (!isCommitUnknown(cause) && !isEventConflict(cause)) throw cause;
|
|
2414
|
-
persistedSnapshot = this.#snapshot();
|
|
2415
|
-
}
|
|
2416
|
-
const persisted = persistedSnapshot.byEventId.get(eventId);
|
|
2417
|
-
if (!persisted) {
|
|
2418
|
-
throw portsError(
|
|
2419
|
-
EVOLUTION_LEDGER_PORTS_UNAVAILABLE_CODE,
|
|
2420
|
-
"release prepare append did not converge to a queryable event",
|
|
2421
|
-
);
|
|
2422
|
-
}
|
|
2423
|
-
return this.#prepareProjection(
|
|
2424
|
-
this.#prepareFromSnapshot(persistedSnapshot, persisted, {
|
|
2425
|
-
authorityReceiptDigest: intent.authorityReceiptDigest,
|
|
2426
|
-
intentDigest: intent.intentDigest,
|
|
2427
|
-
transactionId: intent.transactionId,
|
|
2428
|
-
}),
|
|
2827
|
+
throw portsError(
|
|
2828
|
+
EVOLUTION_LEDGER_PORTS_UNAVAILABLE_CODE,
|
|
2829
|
+
"release prepare could not acquire a stable ledger head",
|
|
2429
2830
|
);
|
|
2430
2831
|
}
|
|
2431
2832
|
|
|
@@ -2560,6 +2961,513 @@ class EvolutionLedgerDomainPorts {
|
|
|
2560
2961
|
return this.#committedProjection(finalized, lineages);
|
|
2561
2962
|
}
|
|
2562
2963
|
|
|
2964
|
+
resolveReleaseOperation(inputValue) {
|
|
2965
|
+
return this.#resolveRelease(inputValue, false);
|
|
2966
|
+
}
|
|
2967
|
+
|
|
2968
|
+
resolveReleaseOrigin(inputValue) {
|
|
2969
|
+
return this.#resolveRelease(inputValue, true);
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2972
|
+
readReleaseHistory(inputValue) {
|
|
2973
|
+
return this.#resolveRelease(inputValue, false, true);
|
|
2974
|
+
}
|
|
2975
|
+
|
|
2976
|
+
resolveKnowledgeRevocation(inputValue) {
|
|
2977
|
+
if (this.#audience === null)
|
|
2978
|
+
throw new TypeError(
|
|
2979
|
+
"Knowledge revocation proof requires audience-bound ledger ports",
|
|
2980
|
+
);
|
|
2981
|
+
const input = frozenCanonicalClone(inputValue);
|
|
2982
|
+
assertAllExactRecord(
|
|
2983
|
+
input,
|
|
2984
|
+
new Set(["tenantId", "operationDigest", "context"]),
|
|
2985
|
+
"Knowledge revocation query",
|
|
2986
|
+
);
|
|
2987
|
+
const tenantId = identifier(input.tenantId, "tenantId");
|
|
2988
|
+
const operationDigest = digest(input.operationDigest, "operationDigest");
|
|
2989
|
+
const keys = [
|
|
2990
|
+
"epoch",
|
|
2991
|
+
"ledgerId",
|
|
2992
|
+
"identityDigest",
|
|
2993
|
+
"sequence",
|
|
2994
|
+
"headDigest",
|
|
2995
|
+
];
|
|
2996
|
+
assertAllExactRecord(
|
|
2997
|
+
input.context,
|
|
2998
|
+
new Set(["mode", "checkpoint"]),
|
|
2999
|
+
"Knowledge revocation context",
|
|
3000
|
+
);
|
|
3001
|
+
assertAllExactRecord(
|
|
3002
|
+
input.context.checkpoint,
|
|
3003
|
+
new Set(keys),
|
|
3004
|
+
"Knowledge revocation checkpoint",
|
|
3005
|
+
);
|
|
3006
|
+
const head = this.#ledgerVerify();
|
|
3007
|
+
if (
|
|
3008
|
+
input.context.mode !== "current" ||
|
|
3009
|
+
keys.some((key) => input.context.checkpoint[key] !== head[key])
|
|
3010
|
+
)
|
|
3011
|
+
throw portsError(
|
|
3012
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3013
|
+
"Knowledge revocation requires the current authenticated head",
|
|
3014
|
+
);
|
|
3015
|
+
const snapshot = this.#snapshot();
|
|
3016
|
+
if (
|
|
3017
|
+
snapshot.events.length !== head.sequence ||
|
|
3018
|
+
(snapshot.events.at(-1)?.eventDigest ?? null) !== head.headDigest
|
|
3019
|
+
)
|
|
3020
|
+
throw portsError(
|
|
3021
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3022
|
+
"Knowledge revocation snapshot changed",
|
|
3023
|
+
);
|
|
3024
|
+
let fence = null;
|
|
3025
|
+
for (const entry of this.#knowledgeRevocations(
|
|
3026
|
+
snapshot,
|
|
3027
|
+
tenantId,
|
|
3028
|
+
this.#audience,
|
|
3029
|
+
)) {
|
|
3030
|
+
if (entry.prepared.operationDigest !== operationDigest) continue;
|
|
3031
|
+
fence = {
|
|
3032
|
+
record: entry.prepared,
|
|
3033
|
+
sequence: entry.event.sequence,
|
|
3034
|
+
evidence: {
|
|
3035
|
+
timestamp: entry.event.timestamp,
|
|
3036
|
+
signature: entry.event.signature,
|
|
3037
|
+
eventDigest: entry.event.eventDigest,
|
|
3038
|
+
},
|
|
3039
|
+
};
|
|
3040
|
+
}
|
|
3041
|
+
const fresh = this.#ledgerVerify();
|
|
3042
|
+
if (keys.some((key) => fresh[key] !== head[key]))
|
|
3043
|
+
throw portsError(
|
|
3044
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3045
|
+
"Knowledge revocation changed during verification",
|
|
3046
|
+
);
|
|
3047
|
+
return deepFreeze({
|
|
3048
|
+
authenticated: true,
|
|
3049
|
+
durable: true,
|
|
3050
|
+
tenantId,
|
|
3051
|
+
operationDigest,
|
|
3052
|
+
checkpoint: { ...input.context.checkpoint },
|
|
3053
|
+
fence,
|
|
3054
|
+
});
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
resolveCandidateRevocation(inputValue) {
|
|
3058
|
+
return this.#resolveCandidateDisposition(inputValue, "reject-candidate");
|
|
3059
|
+
}
|
|
3060
|
+
|
|
3061
|
+
resolveCandidateQuarantine(inputValue) {
|
|
3062
|
+
return this.#resolveCandidateDisposition(inputValue, "quarantine");
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
#resolveCandidateDisposition(inputValue, disposition) {
|
|
3066
|
+
if (this.#audience === null)
|
|
3067
|
+
throw new TypeError(
|
|
3068
|
+
"candidate revocation proof requires audience-bound ledger ports",
|
|
3069
|
+
);
|
|
3070
|
+
const input = frozenCanonicalClone(inputValue);
|
|
3071
|
+
assertAllExactRecord(
|
|
3072
|
+
input,
|
|
3073
|
+
new Set([
|
|
3074
|
+
"tenantId",
|
|
3075
|
+
"skillName",
|
|
3076
|
+
"candidateId",
|
|
3077
|
+
"operationDigest",
|
|
3078
|
+
"context",
|
|
3079
|
+
]),
|
|
3080
|
+
"candidate revocation query",
|
|
3081
|
+
);
|
|
3082
|
+
const tenantId = identifier(input.tenantId, "tenantId");
|
|
3083
|
+
const name = skillName(input.skillName, "skillName");
|
|
3084
|
+
const candidateId = digest(input.candidateId, "candidateId");
|
|
3085
|
+
const operationDigest = digest(input.operationDigest, "operationDigest");
|
|
3086
|
+
const keys = [
|
|
3087
|
+
"epoch",
|
|
3088
|
+
"ledgerId",
|
|
3089
|
+
"identityDigest",
|
|
3090
|
+
"sequence",
|
|
3091
|
+
"headDigest",
|
|
3092
|
+
];
|
|
3093
|
+
assertAllExactRecord(
|
|
3094
|
+
input.context,
|
|
3095
|
+
new Set(["mode", "checkpoint"]),
|
|
3096
|
+
"candidate revocation context",
|
|
3097
|
+
);
|
|
3098
|
+
assertAllExactRecord(
|
|
3099
|
+
input.context.checkpoint,
|
|
3100
|
+
new Set(keys),
|
|
3101
|
+
"candidate revocation checkpoint",
|
|
3102
|
+
);
|
|
3103
|
+
if (input.context.mode !== "current")
|
|
3104
|
+
throw new TypeError("candidate revocation requires a current context");
|
|
3105
|
+
const head = this.#ledgerVerify();
|
|
3106
|
+
if (keys.some((key) => input.context.checkpoint[key] !== head[key])) {
|
|
3107
|
+
throw portsError(
|
|
3108
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3109
|
+
"candidate revocation checkpoint is stale",
|
|
3110
|
+
);
|
|
3111
|
+
}
|
|
3112
|
+
const snapshot = this.#snapshot();
|
|
3113
|
+
if (
|
|
3114
|
+
snapshot.events.length !== head.sequence ||
|
|
3115
|
+
(snapshot.events.at(-1)?.eventDigest ?? null) !== head.headDigest
|
|
3116
|
+
) {
|
|
3117
|
+
throw portsError(
|
|
3118
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3119
|
+
"candidate revocation snapshot changed",
|
|
3120
|
+
);
|
|
3121
|
+
}
|
|
3122
|
+
let fence = null;
|
|
3123
|
+
// This is the exact same authenticated parser as mandatory prepare, not a
|
|
3124
|
+
// separate provider's assertion that admission has supposedly been denied.
|
|
3125
|
+
for (const entry of this.#knowledgeRevocations(
|
|
3126
|
+
snapshot,
|
|
3127
|
+
tenantId,
|
|
3128
|
+
this.#audience,
|
|
3129
|
+
)) {
|
|
3130
|
+
if (entry.prepared.operationDigest !== operationDigest) continue;
|
|
3131
|
+
const dependency = entry.prepared.knowledge.dependencies.find(
|
|
3132
|
+
(item) =>
|
|
3133
|
+
item.kind === "candidate" &&
|
|
3134
|
+
item.digest === candidateId &&
|
|
3135
|
+
item.disposition === disposition,
|
|
3136
|
+
);
|
|
3137
|
+
if (dependency) fence = entry;
|
|
3138
|
+
}
|
|
3139
|
+
const cache = new Map();
|
|
3140
|
+
const lineages = this.#lineages(snapshot, cache);
|
|
3141
|
+
const history = [];
|
|
3142
|
+
const pendingTransactions = [];
|
|
3143
|
+
for (const event of snapshot.events) {
|
|
3144
|
+
if (event.type !== EVENT_TYPES.prepare || event.tenantId !== tenantId)
|
|
3145
|
+
continue;
|
|
3146
|
+
const entry =
|
|
3147
|
+
cache.get(event.eventId) ?? this.#prepareFromSnapshot(snapshot, event);
|
|
3148
|
+
const intent = entry.intent;
|
|
3149
|
+
if (intent.candidateId === candidateId && intent.skillName !== name) {
|
|
3150
|
+
throw portsError(
|
|
3151
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3152
|
+
"candidate history belongs to another Skill",
|
|
3153
|
+
);
|
|
3154
|
+
}
|
|
3155
|
+
if (intent.skillName !== name) continue;
|
|
3156
|
+
const finalized = lineages.byTransaction.get(intent.transactionId);
|
|
3157
|
+
if (!finalized) pendingTransactions.push(intent.transactionId);
|
|
3158
|
+
if (intent.candidateId !== candidateId) continue;
|
|
3159
|
+
history.push({
|
|
3160
|
+
transactionId: intent.transactionId,
|
|
3161
|
+
releaseDigest: intent.targetReleaseDigest,
|
|
3162
|
+
preparationSequence: event.sequence,
|
|
3163
|
+
committed: Boolean(finalized),
|
|
3164
|
+
});
|
|
3165
|
+
}
|
|
3166
|
+
const groupKey = `${tenantId}\0${name}`;
|
|
3167
|
+
const latest = lineages.groups.get(groupKey)?.at(-1);
|
|
3168
|
+
const migrated = lineages.migrations.get(groupKey);
|
|
3169
|
+
const current = latest
|
|
3170
|
+
? {
|
|
3171
|
+
releaseDigest: latest.prepared.intent.targetReleaseDigest,
|
|
3172
|
+
revision: latest.finalization.revision,
|
|
3173
|
+
stateDigest: latest.finalization.stateDigest,
|
|
3174
|
+
projection: this.#committedProjection(latest, lineages),
|
|
3175
|
+
}
|
|
3176
|
+
: migrated
|
|
3177
|
+
? {
|
|
3178
|
+
releaseDigest: migrated.migration.state.activeReleaseDigest,
|
|
3179
|
+
revision: migrated.migration.state.revision,
|
|
3180
|
+
stateDigest: migrated.migration.state.stateDigest,
|
|
3181
|
+
projection: this.#migrationProjection(migrated, true),
|
|
3182
|
+
}
|
|
3183
|
+
: null;
|
|
3184
|
+
const fresh = this.#ledgerVerify();
|
|
3185
|
+
if (keys.some((key) => fresh[key] !== head[key])) {
|
|
3186
|
+
throw portsError(
|
|
3187
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3188
|
+
"candidate revocation ledger changed during verification",
|
|
3189
|
+
);
|
|
3190
|
+
}
|
|
3191
|
+
return deepFreeze({
|
|
3192
|
+
authenticated: true,
|
|
3193
|
+
durable: true,
|
|
3194
|
+
tenantId,
|
|
3195
|
+
skillName: name,
|
|
3196
|
+
candidateId,
|
|
3197
|
+
operationDigest,
|
|
3198
|
+
checkpoint: { ...input.context.checkpoint },
|
|
3199
|
+
fence: fence
|
|
3200
|
+
? {
|
|
3201
|
+
record: fence.prepared,
|
|
3202
|
+
sequence: fence.event.sequence,
|
|
3203
|
+
evidence: {
|
|
3204
|
+
timestamp: fence.event.timestamp,
|
|
3205
|
+
signature: fence.event.signature,
|
|
3206
|
+
eventDigest: fence.event.eventDigest,
|
|
3207
|
+
},
|
|
3208
|
+
}
|
|
3209
|
+
: null,
|
|
3210
|
+
pendingTransactions,
|
|
3211
|
+
history,
|
|
3212
|
+
current,
|
|
3213
|
+
});
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
#resolveRelease(inputValue, origin, history = false) {
|
|
3217
|
+
const input = frozenCanonicalClone(inputValue);
|
|
3218
|
+
assertAllExactRecord(
|
|
3219
|
+
input,
|
|
3220
|
+
new Set([
|
|
3221
|
+
"tenantId",
|
|
3222
|
+
"skillName",
|
|
3223
|
+
...(history ? [] : [origin ? "releaseDigest" : "operationId"]),
|
|
3224
|
+
"context",
|
|
3225
|
+
]),
|
|
3226
|
+
"release operation query",
|
|
3227
|
+
);
|
|
3228
|
+
const tenantId = identifier(input.tenantId, "tenantId");
|
|
3229
|
+
const name = skillName(input.skillName, "skillName");
|
|
3230
|
+
const operationId =
|
|
3231
|
+
origin || history ? null : identifier(input.operationId, "operationId");
|
|
3232
|
+
const releaseDigest = origin
|
|
3233
|
+
? digest(
|
|
3234
|
+
input.releaseDigest,
|
|
3235
|
+
"releaseDigest",
|
|
3236
|
+
EVOLUTION_LEDGER_PORTS_INVALID_CODE,
|
|
3237
|
+
)
|
|
3238
|
+
: null;
|
|
3239
|
+
const context = input.context;
|
|
3240
|
+
assertAllExactRecord(
|
|
3241
|
+
context,
|
|
3242
|
+
new Set(["mode", "checkpoint"]),
|
|
3243
|
+
"release operation context",
|
|
3244
|
+
);
|
|
3245
|
+
const keys = [
|
|
3246
|
+
"epoch",
|
|
3247
|
+
"ledgerId",
|
|
3248
|
+
"identityDigest",
|
|
3249
|
+
"sequence",
|
|
3250
|
+
"headDigest",
|
|
3251
|
+
];
|
|
3252
|
+
assertAllExactRecord(
|
|
3253
|
+
context.checkpoint,
|
|
3254
|
+
new Set(keys),
|
|
3255
|
+
"release operation checkpoint",
|
|
3256
|
+
);
|
|
3257
|
+
if (!["current", "checkpoint"].includes(context.mode))
|
|
3258
|
+
throw new TypeError("invalid release operation mode");
|
|
3259
|
+
const snapshot = this.#snapshot();
|
|
3260
|
+
const tail = snapshot.events.at(-1);
|
|
3261
|
+
const head = tail
|
|
3262
|
+
? { ...tail, headDigest: tail.eventDigest }
|
|
3263
|
+
: this.#ledgerVerify();
|
|
3264
|
+
if (
|
|
3265
|
+
snapshot.events.length !== head.sequence ||
|
|
3266
|
+
snapshot.events.some((event) =>
|
|
3267
|
+
["epoch", "ledgerId", "identityDigest"].some(
|
|
3268
|
+
(key) => event[key] !== head[key],
|
|
3269
|
+
),
|
|
3270
|
+
)
|
|
3271
|
+
)
|
|
3272
|
+
throw portsError(
|
|
3273
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3274
|
+
"release operation snapshot is not the full current ledger",
|
|
3275
|
+
);
|
|
3276
|
+
const checkpoint = context.checkpoint;
|
|
3277
|
+
const historical =
|
|
3278
|
+
checkpoint.sequence === 0
|
|
3279
|
+
? null
|
|
3280
|
+
: snapshot.bySequence.get(checkpoint.sequence);
|
|
3281
|
+
if (
|
|
3282
|
+
!Number.isSafeInteger(checkpoint.sequence) ||
|
|
3283
|
+
checkpoint.sequence < 0 ||
|
|
3284
|
+
checkpoint.sequence > head.sequence ||
|
|
3285
|
+
["epoch", "ledgerId", "identityDigest"].some(
|
|
3286
|
+
(key) => checkpoint[key] !== head[key],
|
|
3287
|
+
) ||
|
|
3288
|
+
checkpoint.headDigest !== (historical?.eventDigest ?? null) ||
|
|
3289
|
+
(context.mode === "current" &&
|
|
3290
|
+
keys.some((key) => checkpoint[key] !== head[key]))
|
|
3291
|
+
) {
|
|
3292
|
+
throw portsError(
|
|
3293
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3294
|
+
"release operation checkpoint differs from the authenticated ledger",
|
|
3295
|
+
);
|
|
3296
|
+
}
|
|
3297
|
+
// Authenticate the whole present lineage even for a historical query, then
|
|
3298
|
+
// derive the exact as-of prefix. A later finalize cannot prove an earlier ack.
|
|
3299
|
+
const prepareCache = new Map();
|
|
3300
|
+
const presentLineages = this.#lineages(snapshot, prepareCache);
|
|
3301
|
+
const prefix = this.#indexSnapshot(
|
|
3302
|
+
snapshot.events.slice(0, checkpoint.sequence),
|
|
3303
|
+
snapshot.subjects,
|
|
3304
|
+
);
|
|
3305
|
+
// Reuse only work authenticated in THIS read, and only when all release
|
|
3306
|
+
// events and their consumed authority precede the requested checkpoint.
|
|
3307
|
+
// Unrelated later Wiki/journal events do not change the release lineage.
|
|
3308
|
+
// A later prepare/finalize/migration still forces exact prefix replay.
|
|
3309
|
+
const unchangedReleaseHistory =
|
|
3310
|
+
!snapshot.events
|
|
3311
|
+
.slice(checkpoint.sequence)
|
|
3312
|
+
.some((event) =>
|
|
3313
|
+
[
|
|
3314
|
+
EVENT_TYPES.prepare,
|
|
3315
|
+
EVENT_TYPES.finalize,
|
|
3316
|
+
EVENT_TYPES.migration,
|
|
3317
|
+
].includes(event.type),
|
|
3318
|
+
) &&
|
|
3319
|
+
[...prepareCache.values()].every((entry) =>
|
|
3320
|
+
prefix.byEventId.has(entry.consumeAudit.event.eventId),
|
|
3321
|
+
);
|
|
3322
|
+
const lineages = unchangedReleaseHistory
|
|
3323
|
+
? presentLineages
|
|
3324
|
+
: this.#lineages(prefix);
|
|
3325
|
+
const prepared = [];
|
|
3326
|
+
for (const event of prefix.events) {
|
|
3327
|
+
if (event.type !== EVENT_TYPES.prepare) continue;
|
|
3328
|
+
const cached = prepareCache.get(event.eventId);
|
|
3329
|
+
const entry =
|
|
3330
|
+
cached && prefix.byEventId.has(cached.consumeAudit.event.eventId)
|
|
3331
|
+
? cached
|
|
3332
|
+
: this.#prepareFromSnapshot(prefix, event);
|
|
3333
|
+
if (
|
|
3334
|
+
entry.intent.mutationRequest.tenantId === tenantId &&
|
|
3335
|
+
entry.intent.skillName === name &&
|
|
3336
|
+
(history ||
|
|
3337
|
+
(origin
|
|
3338
|
+
? entry.intent.operation === "promote" &&
|
|
3339
|
+
entry.intent.targetReleaseDigest === releaseDigest
|
|
3340
|
+
: entry.intent.operationId === operationId))
|
|
3341
|
+
)
|
|
3342
|
+
prepared.push(entry);
|
|
3343
|
+
}
|
|
3344
|
+
if (!history && prepared.length > 1)
|
|
3345
|
+
throw portsError(
|
|
3346
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3347
|
+
"release operation has multiple transaction intents",
|
|
3348
|
+
);
|
|
3349
|
+
if (history && prepared.length > 10_000)
|
|
3350
|
+
throw portsError(
|
|
3351
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3352
|
+
"release history exceeds its bounded budget",
|
|
3353
|
+
);
|
|
3354
|
+
if (
|
|
3355
|
+
history &&
|
|
3356
|
+
new Set(prepared.map((entry) => entry.intent.operationId)).size !==
|
|
3357
|
+
prepared.length
|
|
3358
|
+
)
|
|
3359
|
+
throw portsError(
|
|
3360
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3361
|
+
"release operation has multiple transaction intents",
|
|
3362
|
+
);
|
|
3363
|
+
const groupKey = `${tenantId}\0${name}`;
|
|
3364
|
+
const baseline = lineages.migrations.get(groupKey)?.migration.state;
|
|
3365
|
+
let previous = baseline
|
|
3366
|
+
? {
|
|
3367
|
+
revision: baseline.revision,
|
|
3368
|
+
stateDigest: baseline.stateDigest,
|
|
3369
|
+
activeReleaseDigest: baseline.activeReleaseDigest,
|
|
3370
|
+
lastKnownGoodReleaseDigest: baseline.lastKnownGoodReleaseDigest,
|
|
3371
|
+
}
|
|
3372
|
+
: {
|
|
3373
|
+
revision: 0,
|
|
3374
|
+
stateDigest: null,
|
|
3375
|
+
activeReleaseDigest: null,
|
|
3376
|
+
lastKnownGoodReleaseDigest: null,
|
|
3377
|
+
};
|
|
3378
|
+
const predecessors = new Map([[previous.revision, previous]]);
|
|
3379
|
+
for (const prior of lineages.groups.get(groupKey) ?? []) {
|
|
3380
|
+
const intent = prior.prepared.intent;
|
|
3381
|
+
if (
|
|
3382
|
+
intent.operation === "rollback" &&
|
|
3383
|
+
intent.targetReleaseDigest !== previous.lastKnownGoodReleaseDigest
|
|
3384
|
+
)
|
|
3385
|
+
throw portsError(
|
|
3386
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3387
|
+
"historical rollback does not target the last-known-good release",
|
|
3388
|
+
);
|
|
3389
|
+
previous = {
|
|
3390
|
+
revision: prior.finalization.revision,
|
|
3391
|
+
stateDigest: prior.finalization.stateDigest,
|
|
3392
|
+
activeReleaseDigest: intent.targetReleaseDigest,
|
|
3393
|
+
lastKnownGoodReleaseDigest:
|
|
3394
|
+
intent.operation === "promote"
|
|
3395
|
+
? (previous.activeReleaseDigest ?? intent.targetReleaseDigest)
|
|
3396
|
+
: intent.targetReleaseDigest,
|
|
3397
|
+
};
|
|
3398
|
+
predecessors.set(previous.revision, previous);
|
|
3399
|
+
}
|
|
3400
|
+
const results = prepared.map((entry) => {
|
|
3401
|
+
const previous = predecessors.get(entry.intent.expectedRevision);
|
|
3402
|
+
if (
|
|
3403
|
+
!previous ||
|
|
3404
|
+
previous.revision !== entry.intent.expectedRevision ||
|
|
3405
|
+
previous.stateDigest !== entry.intent.previousStateDigest
|
|
3406
|
+
)
|
|
3407
|
+
throw portsError(
|
|
3408
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3409
|
+
"release operation has no exact predecessor",
|
|
3410
|
+
);
|
|
3411
|
+
const finalized = lineages.byTransaction.get(entry.intent.transactionId);
|
|
3412
|
+
return {
|
|
3413
|
+
intent: entry.intent,
|
|
3414
|
+
previous,
|
|
3415
|
+
preparationCheckpoint: {
|
|
3416
|
+
epoch: entry.event.epoch,
|
|
3417
|
+
ledgerId: entry.event.ledgerId,
|
|
3418
|
+
identityDigest: entry.event.identityDigest,
|
|
3419
|
+
sequence: entry.event.sequence,
|
|
3420
|
+
headDigest: entry.event.eventDigest,
|
|
3421
|
+
},
|
|
3422
|
+
projection: finalized
|
|
3423
|
+
? this.#committedProjection(finalized, lineages)
|
|
3424
|
+
: this.#prepareProjection(entry),
|
|
3425
|
+
finalizationEvidence: finalized
|
|
3426
|
+
? {
|
|
3427
|
+
timestamp: finalized.event.timestamp,
|
|
3428
|
+
signature: finalized.event.signature,
|
|
3429
|
+
eventDigest: finalized.event.eventDigest,
|
|
3430
|
+
}
|
|
3431
|
+
: null,
|
|
3432
|
+
};
|
|
3433
|
+
});
|
|
3434
|
+
const result = results[0] ?? null;
|
|
3435
|
+
const fresh = this.#ledgerVerify();
|
|
3436
|
+
if (keys.some((key) => fresh[key] !== head[key]))
|
|
3437
|
+
throw portsError(
|
|
3438
|
+
EVOLUTION_LEDGER_PORTS_CORRUPT_CODE,
|
|
3439
|
+
"release operation ledger changed during verification",
|
|
3440
|
+
);
|
|
3441
|
+
if (history) {
|
|
3442
|
+
const migration = lineages.migrations.get(`${tenantId}\0${name}`);
|
|
3443
|
+
return deepFreeze({
|
|
3444
|
+
authenticated: true,
|
|
3445
|
+
durable: true,
|
|
3446
|
+
tenantId,
|
|
3447
|
+
skillName: name,
|
|
3448
|
+
checkpoint: { ...checkpoint },
|
|
3449
|
+
migration: migration
|
|
3450
|
+
? {
|
|
3451
|
+
value: migration.migration,
|
|
3452
|
+
artifactRef: migration.event.subjectRef,
|
|
3453
|
+
sequence: migration.event.sequence,
|
|
3454
|
+
eventDigest: migration.event.eventDigest,
|
|
3455
|
+
}
|
|
3456
|
+
: null,
|
|
3457
|
+
operations: results,
|
|
3458
|
+
});
|
|
3459
|
+
}
|
|
3460
|
+
return deepFreeze({
|
|
3461
|
+
authenticated: true,
|
|
3462
|
+
durable: true,
|
|
3463
|
+
tenantId,
|
|
3464
|
+
skillName: name,
|
|
3465
|
+
operationId: origin ? (result?.intent.operationId ?? null) : operationId,
|
|
3466
|
+
checkpoint: { ...checkpoint },
|
|
3467
|
+
result,
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
3470
|
+
|
|
2563
3471
|
appendAudit(input) {
|
|
2564
3472
|
const value = frozenCanonicalClone(input);
|
|
2565
3473
|
const audit = verifySkillMutationAuditEvent(value);
|
|
@@ -3009,16 +3917,69 @@ export function createEvolutionLedgerPorts(options = {}) {
|
|
|
3009
3917
|
)
|
|
3010
3918
|
: "evolution-ledger",
|
|
3011
3919
|
});
|
|
3012
|
-
const prepare = Object.freeze((input) =>
|
|
3920
|
+
const prepare = Object.freeze((input, targetRelease) =>
|
|
3921
|
+
adapter.prepare(input, targetRelease),
|
|
3922
|
+
);
|
|
3013
3923
|
const finalize = Object.freeze((input) => adapter.finalize(input));
|
|
3014
|
-
const migrate = Object.freeze((input) =>
|
|
3924
|
+
const migrate = Object.freeze((input, releases) =>
|
|
3925
|
+
adapter.migrate(input, releases),
|
|
3926
|
+
);
|
|
3015
3927
|
const query = Object.freeze((transactionId) => adapter.query(transactionId));
|
|
3016
3928
|
const append = Object.freeze((event) => adapter.appendAudit(event));
|
|
3017
3929
|
const claim = Object.freeze((nonce) => adapter.claimNonce(nonce));
|
|
3930
|
+
const transactionLedger = Object.freeze({
|
|
3931
|
+
finalize,
|
|
3932
|
+
migrate,
|
|
3933
|
+
prepare,
|
|
3934
|
+
query,
|
|
3935
|
+
});
|
|
3936
|
+
const readCurrentHead = ledger.verify.bind(ledger);
|
|
3937
|
+
RELEASE_OPERATION_READERS.set(
|
|
3938
|
+
transactionLedger,
|
|
3939
|
+
Object.freeze({
|
|
3940
|
+
currentContext: Object.freeze(() => {
|
|
3941
|
+
const head = readCurrentHead();
|
|
3942
|
+
return deepFreeze({
|
|
3943
|
+
mode: "current",
|
|
3944
|
+
checkpoint: Object.fromEntries(
|
|
3945
|
+
[
|
|
3946
|
+
"epoch",
|
|
3947
|
+
"ledgerId",
|
|
3948
|
+
"identityDigest",
|
|
3949
|
+
"sequence",
|
|
3950
|
+
"headDigest",
|
|
3951
|
+
].map((key) => [key, head[key]]),
|
|
3952
|
+
),
|
|
3953
|
+
});
|
|
3954
|
+
}),
|
|
3955
|
+
matchesWikiAdapter: Object.freeze((wikiAdapter) =>
|
|
3956
|
+
captureWikiRevisionReader(wikiAdapter).matchesLedger(ledger),
|
|
3957
|
+
),
|
|
3958
|
+
matchesLedger: Object.freeze((value) => value === ledger),
|
|
3959
|
+
resolveOperation: Object.freeze((input) =>
|
|
3960
|
+
adapter.resolveReleaseOperation(input),
|
|
3961
|
+
),
|
|
3962
|
+
resolveReleaseOrigin: Object.freeze((input) =>
|
|
3963
|
+
adapter.resolveReleaseOrigin(input),
|
|
3964
|
+
),
|
|
3965
|
+
readReleaseHistory: Object.freeze((input) =>
|
|
3966
|
+
adapter.readReleaseHistory(input),
|
|
3967
|
+
),
|
|
3968
|
+
resolveCandidateRevocation: Object.freeze((input) =>
|
|
3969
|
+
adapter.resolveCandidateRevocation(input),
|
|
3970
|
+
),
|
|
3971
|
+
resolveCandidateQuarantine: Object.freeze((input) =>
|
|
3972
|
+
adapter.resolveCandidateQuarantine(input),
|
|
3973
|
+
),
|
|
3974
|
+
resolveKnowledgeRevocation: Object.freeze((input) =>
|
|
3975
|
+
adapter.resolveKnowledgeRevocation(input),
|
|
3976
|
+
),
|
|
3977
|
+
}),
|
|
3978
|
+
);
|
|
3018
3979
|
return Object.freeze({
|
|
3019
3980
|
auditSink: Object.freeze({ append }),
|
|
3020
3981
|
nonceStore: Object.freeze({ claim }),
|
|
3021
|
-
transactionLedger
|
|
3982
|
+
transactionLedger,
|
|
3022
3983
|
});
|
|
3023
3984
|
}
|
|
3024
3985
|
|