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
|
@@ -1,10 +1,15 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { resolveKnowledgeWikiSourceProvenance } from "./knowledge-wiki-source-provenance.js";
|
|
1
3
|
import {
|
|
4
|
+
EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES,
|
|
2
5
|
EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA,
|
|
3
6
|
isEvolutionLedgerArtifactResolver,
|
|
7
|
+
captureEvolutionLedgerBatchResolver,
|
|
4
8
|
} from "./evolution-artifact-ports.js";
|
|
5
9
|
import {
|
|
6
10
|
EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA,
|
|
7
11
|
EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA,
|
|
12
|
+
EVOLUTION_LEDGER_MAX_EVENTS,
|
|
8
13
|
} from "./evolution-ledger.js";
|
|
9
14
|
import {
|
|
10
15
|
WIKI_REVISION_SCHEMA,
|
|
@@ -15,13 +20,28 @@ import {
|
|
|
15
20
|
|
|
16
21
|
export const WIKI_LEDGER_EVENT_TYPE = "wiki.revision.committed";
|
|
17
22
|
export const WIKI_LEDGER_CONFLICT_CODE = "CC_EVOLUTION_WIKI_REVISION_CONFLICT";
|
|
18
|
-
|
|
23
|
+
import {
|
|
24
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
25
|
+
verifyWikiRevision as verifyRevision,
|
|
26
|
+
verifyWikiRequestTransition as verifyRequestTransition,
|
|
27
|
+
} from "./wiki-revision-protocol.js";
|
|
28
|
+
export { WIKI_LEDGER_CORRUPT_CODE } from "./wiki-revision-protocol.js";
|
|
19
29
|
|
|
20
30
|
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
21
31
|
const REVISION_ID = /^wiki:[a-f0-9]{64}$/u;
|
|
32
|
+
const READERS = new WeakMap();
|
|
33
|
+
|
|
34
|
+
function freeze(value) {
|
|
35
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
36
|
+
Object.freeze(value);
|
|
37
|
+
for (const child of Object.values(value)) freeze(child);
|
|
38
|
+
}
|
|
39
|
+
return value;
|
|
40
|
+
}
|
|
22
41
|
|
|
23
42
|
function requiredString(value, name) {
|
|
24
|
-
if (typeof value !== "string" || value.trim() === "")
|
|
43
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
44
|
+
throw new TypeError(`${name} is required`);
|
|
25
45
|
return value;
|
|
26
46
|
}
|
|
27
47
|
|
|
@@ -33,39 +53,66 @@ function fail(code, message) {
|
|
|
33
53
|
|
|
34
54
|
function captureMethod(owner, name, label) {
|
|
35
55
|
const method = owner?.[name];
|
|
36
|
-
if (typeof method !== "function")
|
|
56
|
+
if (typeof method !== "function")
|
|
57
|
+
throw new TypeError(`${label}.${name} is required`);
|
|
37
58
|
return (...args) => Reflect.apply(method, owner, args);
|
|
38
59
|
}
|
|
39
60
|
|
|
40
61
|
function parseRecord(resolution, descriptor) {
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
62
|
+
if (
|
|
63
|
+
resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
|
|
64
|
+
resolution.authenticated !== true ||
|
|
65
|
+
resolution.found !== true ||
|
|
66
|
+
!DIGEST.test(resolution.digest ?? "") ||
|
|
67
|
+
!DIGEST.test(resolution.receiptDigest ?? "") ||
|
|
68
|
+
!Buffer.isBuffer(resolution.bytes) ||
|
|
69
|
+
resolution.bytes.length > EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES
|
|
70
|
+
) {
|
|
71
|
+
fail(
|
|
72
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
73
|
+
"Wiki artifact resolution is not authenticated and complete",
|
|
74
|
+
);
|
|
45
75
|
}
|
|
46
76
|
let record;
|
|
47
77
|
try {
|
|
48
|
-
record = JSON.parse(
|
|
78
|
+
record = JSON.parse(
|
|
79
|
+
new TextDecoder("utf-8", { fatal: true }).decode(resolution.bytes),
|
|
80
|
+
);
|
|
49
81
|
} catch {
|
|
50
82
|
fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki artifact is not canonical JSON");
|
|
51
83
|
}
|
|
52
84
|
const revision = record?.value;
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
85
|
+
if (
|
|
86
|
+
record?.schema !== EVOLUTION_DURABLE_ARTIFACT_RECORD_SCHEMA ||
|
|
87
|
+
record.tenantId !== descriptor.artifactTenantId ||
|
|
88
|
+
record.audience !== descriptor.audience ||
|
|
89
|
+
record.purpose !== descriptor.purpose ||
|
|
90
|
+
record.retention !== "ledger" ||
|
|
91
|
+
record.type !== "wiki-revision" ||
|
|
92
|
+
revision?.schema !== WIKI_REVISION_SCHEMA ||
|
|
93
|
+
revision.tenantId !== descriptor.tenantId ||
|
|
94
|
+
revision.evolutionRunId !== descriptor.evolutionRunId ||
|
|
95
|
+
revision.state?.schema !== WIKI_STATE_SCHEMA ||
|
|
96
|
+
revision.state.tenantId !== descriptor.tenantId ||
|
|
97
|
+
revision.stateDigest !== digestWikiState(revision.state) ||
|
|
98
|
+
revision.state.revisionId !== revision.revisionId ||
|
|
99
|
+
!REVISION_ID.test(revision.revisionId ?? "")
|
|
100
|
+
) {
|
|
101
|
+
fail(
|
|
102
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
103
|
+
"Wiki artifact record or revision binding is invalid",
|
|
104
|
+
);
|
|
61
105
|
}
|
|
62
|
-
return revision;
|
|
106
|
+
return verifyRevision(revision, descriptor);
|
|
63
107
|
}
|
|
64
108
|
|
|
65
109
|
function normalizeDescriptor(input) {
|
|
66
110
|
return Object.freeze({
|
|
67
111
|
tenantId: requiredString(input?.tenantId, "tenantId"),
|
|
68
|
-
artifactTenantId: requiredString(
|
|
112
|
+
artifactTenantId: requiredString(
|
|
113
|
+
input?.artifactTenantId,
|
|
114
|
+
"artifactTenantId",
|
|
115
|
+
),
|
|
69
116
|
evolutionRunId: requiredString(input?.evolutionRunId, "evolutionRunId"),
|
|
70
117
|
audience: requiredString(input?.audience, "audience"),
|
|
71
118
|
purpose: requiredString(input?.purpose, "purpose"),
|
|
@@ -73,128 +120,741 @@ function normalizeDescriptor(input) {
|
|
|
73
120
|
}
|
|
74
121
|
|
|
75
122
|
export class WikiMaintainerLedgerAdapter {
|
|
76
|
-
|
|
123
|
+
#putCanonical;
|
|
124
|
+
#readLedger;
|
|
125
|
+
#verifyLedger;
|
|
126
|
+
#appendDomainEvent;
|
|
127
|
+
#resolveArtifact;
|
|
128
|
+
#resolveArtifactBatch;
|
|
129
|
+
|
|
130
|
+
constructor({
|
|
131
|
+
descriptor,
|
|
132
|
+
artifactPorts,
|
|
133
|
+
ledger,
|
|
134
|
+
ledgerArtifactResolver,
|
|
135
|
+
} = {}) {
|
|
77
136
|
this.descriptor = normalizeDescriptor(descriptor);
|
|
78
|
-
this
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
137
|
+
this.#putCanonical = captureMethod(
|
|
138
|
+
artifactPorts,
|
|
139
|
+
"putCanonical",
|
|
140
|
+
"artifactPorts",
|
|
141
|
+
);
|
|
142
|
+
this.#readLedger = captureMethod(ledger, "read", "ledger");
|
|
143
|
+
this.#verifyLedger = captureMethod(ledger, "verify", "ledger");
|
|
144
|
+
this.#appendDomainEvent = captureMethod(
|
|
145
|
+
ledger,
|
|
146
|
+
"appendDomainEvent",
|
|
147
|
+
"ledger",
|
|
148
|
+
);
|
|
82
149
|
if (!isEvolutionLedgerArtifactResolver(ledgerArtifactResolver)) {
|
|
83
|
-
throw new TypeError(
|
|
150
|
+
throw new TypeError(
|
|
151
|
+
"a branded EvolutionArtifactPorts ledger resolver is required",
|
|
152
|
+
);
|
|
84
153
|
}
|
|
85
|
-
this
|
|
154
|
+
this.#resolveArtifact = ledgerArtifactResolver;
|
|
155
|
+
this.#resolveArtifactBatch = captureEvolutionLedgerBatchResolver(
|
|
156
|
+
ledgerArtifactResolver,
|
|
157
|
+
);
|
|
86
158
|
Object.freeze(this);
|
|
159
|
+
READERS.set(
|
|
160
|
+
this,
|
|
161
|
+
Object.freeze({
|
|
162
|
+
descriptor: this.descriptor,
|
|
163
|
+
matchesLedger: (candidate) => candidate === ledger,
|
|
164
|
+
loadWiki: () => this.#loadWiki(),
|
|
165
|
+
readRevision: (input) => this.#readRevision(input),
|
|
166
|
+
readKnowledgeProvenance: (input) =>
|
|
167
|
+
this.#readKnowledgeProvenance(input),
|
|
168
|
+
readStateRevision: (input) => this.#readStateRevision(input),
|
|
169
|
+
findStateRevision: (input) => this.#readStateRevision(input, false),
|
|
170
|
+
resolveHistory: (input) => this.#resolveHistory(input),
|
|
171
|
+
resolveAtCheckpoint: (input) => this.#resolveHistory(input, true),
|
|
172
|
+
}),
|
|
173
|
+
);
|
|
87
174
|
}
|
|
88
175
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
176
|
+
#history({
|
|
177
|
+
sourceDigest = null,
|
|
178
|
+
allowed = [],
|
|
179
|
+
checkpoint = null,
|
|
180
|
+
revisionId = null,
|
|
181
|
+
stateRevisionDigest = null,
|
|
182
|
+
} = {}) {
|
|
183
|
+
// read() already authenticates its snapshot. Resolve against that snapshot's
|
|
184
|
+
// identity, then compare the entire event range with a fresh authority head.
|
|
185
|
+
// This avoids a redundant pre-read scan without caching authorization.
|
|
186
|
+
const events = this.#readLedger({ limit: EVOLUTION_LEDGER_MAX_EVENTS });
|
|
187
|
+
if (!Array.isArray(events) || events.length > EVOLUTION_LEDGER_MAX_EVENTS)
|
|
188
|
+
fail(
|
|
189
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
190
|
+
"EvolutionLedger read did not return events",
|
|
191
|
+
);
|
|
192
|
+
const tail = events.at(-1);
|
|
193
|
+
if (checkpoint) {
|
|
194
|
+
const boundary = events[checkpoint.sequence - 1];
|
|
195
|
+
if (
|
|
196
|
+
!boundary ||
|
|
197
|
+
["epoch", "ledgerId", "identityDigest"].some(
|
|
198
|
+
(key) => checkpoint[key] !== boundary[key],
|
|
199
|
+
) ||
|
|
200
|
+
checkpoint.headDigest !== boundary.eventDigest
|
|
201
|
+
) {
|
|
202
|
+
fail(
|
|
203
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
204
|
+
"Wiki checkpoint is not in this authenticated ledger",
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (
|
|
209
|
+
tail &&
|
|
210
|
+
(typeof tail.epoch !== "string" ||
|
|
211
|
+
typeof tail.ledgerId !== "string" ||
|
|
212
|
+
!DIGEST.test(tail.identityDigest ?? "") ||
|
|
213
|
+
!DIGEST.test(tail.eventDigest ?? "") ||
|
|
214
|
+
events.some(
|
|
215
|
+
(event, index) =>
|
|
216
|
+
event.sequence !== index + 1 ||
|
|
217
|
+
event.epoch !== tail.epoch ||
|
|
218
|
+
event.ledgerId !== tail.ledgerId ||
|
|
219
|
+
event.identityDigest !== tail.identityDigest,
|
|
220
|
+
))
|
|
221
|
+
) {
|
|
222
|
+
fail(
|
|
223
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
224
|
+
"Wiki ledger read has incomplete sequence or identity bindings",
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
const matches = events.filter(
|
|
228
|
+
(event) =>
|
|
229
|
+
event.schema === EVOLUTION_LEDGER_DOMAIN_EVENT_SCHEMA &&
|
|
230
|
+
event.type === WIKI_LEDGER_EVENT_TYPE &&
|
|
231
|
+
event.tenantId === this.descriptor.tenantId &&
|
|
232
|
+
event.correlationId === this.descriptor.evolutionRunId,
|
|
233
|
+
);
|
|
234
|
+
let state = createEmptyWikiState(this.descriptor.tenantId);
|
|
235
|
+
let viewState = state;
|
|
236
|
+
let latest = null;
|
|
237
|
+
let selectedRevision = null;
|
|
238
|
+
let source = sourceDigest === digestWikiState(state) ? state : null;
|
|
239
|
+
const successors = [];
|
|
240
|
+
let retainedBytes = 0;
|
|
241
|
+
let batch = [];
|
|
242
|
+
for (const [index, event] of matches.entries()) {
|
|
243
|
+
const previous = latest;
|
|
244
|
+
if (
|
|
245
|
+
!Number.isSafeInteger(event.sequence) ||
|
|
246
|
+
event.sequence <= (previous?.event.sequence ?? 0) ||
|
|
247
|
+
event.artifactTenantId !== this.descriptor.artifactTenantId ||
|
|
248
|
+
event.decision !== "committed" ||
|
|
249
|
+
event.skillName !== null ||
|
|
250
|
+
!Array.isArray(event.sourceRefs) ||
|
|
251
|
+
digestWikiState(event.sourceRefs) !==
|
|
252
|
+
digestWikiState(previous ? [previous.event.subjectRef] : [])
|
|
253
|
+
) {
|
|
254
|
+
fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki ledger event lineage is invalid");
|
|
255
|
+
}
|
|
256
|
+
// Four revisions at most (4 MiB of payload), retained only while this
|
|
257
|
+
// synchronous chunk is checked. Full index readback and fresh authority
|
|
258
|
+
// remain inside each batch; no snapshot survives this history read.
|
|
259
|
+
if (index % 4 === 0)
|
|
260
|
+
batch = this.#resolveArtifactBatch(
|
|
261
|
+
matches.slice(index, index + 4).map((item) => ({
|
|
262
|
+
epoch: tail.epoch,
|
|
263
|
+
ledgerId: tail.ledgerId,
|
|
264
|
+
ref: item.subjectRef,
|
|
265
|
+
tenantId: this.descriptor.artifactTenantId,
|
|
266
|
+
})),
|
|
267
|
+
);
|
|
268
|
+
const revision = this.#resolveEvent(event, tail, batch[index % 4]);
|
|
269
|
+
const inView =
|
|
270
|
+
checkpoint === null || event.sequence <= checkpoint.sequence;
|
|
271
|
+
// Before durable maintenance requests, v1 genesis did not contain that
|
|
272
|
+
// map. Accept only the exact known legacy genesis, never an arbitrary
|
|
273
|
+
// caller-supplied predecessor or a modern revision with missing fields.
|
|
274
|
+
if (
|
|
275
|
+
!previous &&
|
|
276
|
+
!Object.hasOwn(revision, "maintenanceRequestId") &&
|
|
277
|
+
!Object.hasOwn(revision.state, "maintenanceRequests") &&
|
|
278
|
+
revision.priorStateDigest !== digestWikiState(state)
|
|
279
|
+
) {
|
|
280
|
+
const legacyGenesis = {
|
|
281
|
+
...createEmptyWikiState(this.descriptor.tenantId),
|
|
282
|
+
};
|
|
283
|
+
delete legacyGenesis.maintenanceRequests;
|
|
284
|
+
if (revision.priorStateDigest === digestWikiState(legacyGenesis)) {
|
|
285
|
+
state = freeze(legacyGenesis);
|
|
286
|
+
if (inView) {
|
|
287
|
+
viewState = state;
|
|
288
|
+
source = sourceDigest === revision.priorStateDigest ? state : null;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
if (
|
|
293
|
+
revision.revision !== state.revision + 1 ||
|
|
294
|
+
revision.priorStateDigest !== digestWikiState(state) ||
|
|
295
|
+
event.eventId !== `wiki.revision.${revision.revisionId.slice(5)}` ||
|
|
296
|
+
event.timestamp !== revision.effectiveAt
|
|
297
|
+
) {
|
|
298
|
+
fail(
|
|
299
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
300
|
+
"Wiki revision does not extend its authenticated predecessor",
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
verifyRequestTransition(state, revision);
|
|
304
|
+
if (
|
|
305
|
+
revision.revisionId === revisionId ||
|
|
306
|
+
revision.stateDigest === stateRevisionDigest
|
|
307
|
+
) {
|
|
308
|
+
if (selectedRevision)
|
|
309
|
+
fail(WIKI_LEDGER_CORRUPT_CODE, "Wiki revision identity is ambiguous");
|
|
310
|
+
selectedRevision = {
|
|
311
|
+
trusted: true,
|
|
312
|
+
state: revision.state,
|
|
313
|
+
stateDigest: revision.stateDigest,
|
|
314
|
+
revisionId: revision.revisionId,
|
|
315
|
+
checkpoint: {
|
|
316
|
+
epoch: event.epoch,
|
|
317
|
+
ledgerId: event.ledgerId,
|
|
318
|
+
identityDigest: event.identityDigest,
|
|
319
|
+
sequence: event.sequence,
|
|
320
|
+
headDigest: event.eventDigest,
|
|
321
|
+
},
|
|
322
|
+
artifactRef: event.subjectRef,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
if (source && inView) {
|
|
326
|
+
if (
|
|
327
|
+
!revision.maintenanceRequestDigest ||
|
|
328
|
+
revision.maintenanceRequestDigest !== allowed[successors.length]
|
|
329
|
+
) {
|
|
330
|
+
fail(
|
|
331
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
332
|
+
"Wiki has successors outside the authorized maintenance sequence",
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
retainedBytes += Buffer.byteLength(JSON.stringify(revision), "utf8");
|
|
336
|
+
if (retainedBytes > 8 * EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES) {
|
|
337
|
+
fail(
|
|
338
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
339
|
+
"Wiki successor history exceeds its retained byte budget",
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
successors.push({
|
|
343
|
+
revision,
|
|
344
|
+
eventDigest: event.eventDigest,
|
|
345
|
+
artifactRef: event.subjectRef,
|
|
346
|
+
predecessorHead: {
|
|
347
|
+
epoch: event.epoch,
|
|
348
|
+
ledgerId: event.ledgerId,
|
|
349
|
+
identityDigest: event.identityDigest,
|
|
350
|
+
sequence: event.sequence - 1,
|
|
351
|
+
headDigest: event.prevDigest,
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
} else if (inView && sourceDigest === revision.stateDigest) {
|
|
355
|
+
source = revision.state;
|
|
356
|
+
}
|
|
357
|
+
if (inView) viewState = revision.state;
|
|
358
|
+
latest = { event, revision };
|
|
359
|
+
state = revision.state;
|
|
360
|
+
}
|
|
361
|
+
const head = this.#verifyLedger();
|
|
362
|
+
if (
|
|
363
|
+
head.sequence !== events.length ||
|
|
364
|
+
head.headDigest !== (tail?.eventDigest ?? null) ||
|
|
365
|
+
(tail &&
|
|
366
|
+
["identityDigest", "epoch", "ledgerId"].some(
|
|
367
|
+
(key) => tail[key] !== head[key],
|
|
368
|
+
))
|
|
369
|
+
) {
|
|
370
|
+
fail(
|
|
371
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
372
|
+
"Wiki ledger changed while authenticating history",
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
head,
|
|
377
|
+
latest,
|
|
378
|
+
state,
|
|
379
|
+
viewState,
|
|
380
|
+
source,
|
|
381
|
+
successors,
|
|
382
|
+
selectedRevision,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
#readKnowledgeProvenance({
|
|
387
|
+
tenantId,
|
|
388
|
+
revisionId,
|
|
389
|
+
knowledgeId,
|
|
390
|
+
contentDigest,
|
|
391
|
+
} = {}) {
|
|
392
|
+
if (
|
|
393
|
+
tenantId !== this.descriptor.tenantId ||
|
|
394
|
+
!REVISION_ID.test(revisionId ?? "") ||
|
|
395
|
+
typeof knowledgeId !== "string" ||
|
|
396
|
+
!/^[A-Za-z0-9][A-Za-z0-9._:@/-]{0,255}$/u.test(knowledgeId) ||
|
|
397
|
+
!DIGEST.test(contentDigest ?? "")
|
|
398
|
+
)
|
|
399
|
+
throw new TypeError(
|
|
400
|
+
"Wiki Knowledge provenance requires exact source identities",
|
|
401
|
+
);
|
|
402
|
+
const events = this.#readLedger({ limit: EVOLUTION_LEDGER_MAX_EVENTS });
|
|
403
|
+
const tail = Array.isArray(events) ? events.at(-1) : null;
|
|
404
|
+
if (
|
|
405
|
+
!tail ||
|
|
406
|
+
events.length > EVOLUTION_LEDGER_MAX_EVENTS ||
|
|
407
|
+
events.some(
|
|
408
|
+
(event, index) =>
|
|
409
|
+
event.sequence !== index + 1 ||
|
|
410
|
+
["epoch", "ledgerId", "identityDigest"].some(
|
|
411
|
+
(key) => event[key] !== tail[key],
|
|
412
|
+
),
|
|
413
|
+
)
|
|
414
|
+
)
|
|
415
|
+
fail(
|
|
416
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
417
|
+
"Wiki provenance event range is incomplete",
|
|
418
|
+
);
|
|
419
|
+
const selected = events.find(
|
|
420
|
+
(event) =>
|
|
421
|
+
event.eventId === `wiki.revision.${revisionId.slice(5)}` &&
|
|
422
|
+
event.tenantId === tenantId,
|
|
423
|
+
);
|
|
424
|
+
const sources = events.filter(
|
|
425
|
+
(event) =>
|
|
426
|
+
event.type === WIKI_LEDGER_EVENT_TYPE &&
|
|
427
|
+
event.tenantId === tenantId &&
|
|
428
|
+
event.sequence <= (selected?.sequence ?? 0),
|
|
429
|
+
);
|
|
430
|
+
const positions = new Map(
|
|
431
|
+
sources.map((event, index) => [event.sequence, index]),
|
|
432
|
+
);
|
|
433
|
+
// Same bounded four-subject read as normal Wiki history. Retain no proof
|
|
434
|
+
// across calls and never resolve a future revision as an earlier source.
|
|
435
|
+
let batchStart = -1;
|
|
436
|
+
let batch = [];
|
|
437
|
+
const proof = resolveKnowledgeWikiSourceProvenance({
|
|
438
|
+
events,
|
|
439
|
+
descriptor: this.descriptor,
|
|
440
|
+
revisionId,
|
|
441
|
+
knowledge: { knowledgeId, contentDigest },
|
|
442
|
+
resolveSubject: (event) => {
|
|
443
|
+
const position = positions.get(event.sequence);
|
|
444
|
+
const start = position - (position % 4);
|
|
445
|
+
if (start !== batchStart) {
|
|
446
|
+
batch = this.#resolveArtifactBatch(
|
|
447
|
+
sources.slice(start, start + 4).map((item) => ({
|
|
448
|
+
epoch: tail.epoch,
|
|
449
|
+
ledgerId: tail.ledgerId,
|
|
450
|
+
tenantId: this.descriptor.artifactTenantId,
|
|
451
|
+
ref: item.subjectRef,
|
|
452
|
+
})),
|
|
453
|
+
);
|
|
454
|
+
batchStart = start;
|
|
455
|
+
}
|
|
456
|
+
const resolution = batch[position - start];
|
|
457
|
+
if (
|
|
458
|
+
resolution?.schema !== EVOLUTION_ARTIFACT_RESOLUTION_SCHEMA ||
|
|
459
|
+
resolution.authenticated !== true ||
|
|
460
|
+
resolution.found !== true ||
|
|
461
|
+
resolution.ref !== event.subjectRef.ref ||
|
|
462
|
+
resolution.digest !== event.subjectRef.digest ||
|
|
463
|
+
!DIGEST.test(resolution.receiptDigest ?? "") ||
|
|
464
|
+
!Buffer.isBuffer(resolution.bytes) ||
|
|
465
|
+
resolution.bytes.length > EVOLUTION_ARTIFACT_MAX_CANONICAL_BYTES ||
|
|
466
|
+
`sha256:${createHash("sha256").update(resolution.bytes).digest("hex")}` !==
|
|
467
|
+
event.subjectRef.digest
|
|
468
|
+
)
|
|
469
|
+
fail(
|
|
470
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
471
|
+
"Wiki provenance subject is not authenticated and exactly bound",
|
|
472
|
+
);
|
|
473
|
+
return resolution.bytes;
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
const head = this.#verifyLedger();
|
|
477
|
+
if (
|
|
478
|
+
head.sequence !== events.length ||
|
|
479
|
+
head.headDigest !== tail.eventDigest ||
|
|
480
|
+
["epoch", "ledgerId", "identityDigest"].some(
|
|
481
|
+
(key) => head[key] !== tail[key],
|
|
482
|
+
)
|
|
483
|
+
)
|
|
484
|
+
fail(
|
|
485
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
486
|
+
"Wiki ledger changed while authenticating source provenance",
|
|
487
|
+
);
|
|
488
|
+
return freeze({
|
|
489
|
+
authenticated: true,
|
|
490
|
+
tenantId,
|
|
491
|
+
...proof,
|
|
492
|
+
ledgerHead: head,
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Immutable provenance, not an authorization to use an obsolete Wiki as current.
|
|
497
|
+
// Authenticate the full present history, retaining only the selected revision.
|
|
498
|
+
#readRevision({ tenantId, revisionId } = {}) {
|
|
499
|
+
if (
|
|
500
|
+
tenantId !== this.descriptor.tenantId ||
|
|
501
|
+
!REVISION_ID.test(revisionId ?? "")
|
|
502
|
+
)
|
|
503
|
+
throw new TypeError(
|
|
504
|
+
"Wiki provenance requires an exact tenant and revisionId",
|
|
505
|
+
);
|
|
506
|
+
const { head, selectedRevision } = this.#history({ revisionId });
|
|
507
|
+
if (!selectedRevision)
|
|
508
|
+
fail(
|
|
509
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
510
|
+
"Wiki revision is not in authenticated history",
|
|
511
|
+
);
|
|
512
|
+
return freeze({
|
|
513
|
+
authenticated: true,
|
|
514
|
+
tenantId,
|
|
515
|
+
evolutionRunId: this.descriptor.evolutionRunId,
|
|
516
|
+
...selectedRevision,
|
|
517
|
+
ledgerHead: head,
|
|
518
|
+
});
|
|
95
519
|
}
|
|
96
520
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
521
|
+
// Content-addressed original state lookup, without authorizing intervening
|
|
522
|
+
// changes. Effect consumers still replay their exact permitted successors.
|
|
523
|
+
#readStateRevision({ tenantId, stateDigest } = {}, required = true) {
|
|
524
|
+
if (
|
|
525
|
+
tenantId !== this.descriptor.tenantId ||
|
|
526
|
+
!DIGEST.test(stateDigest ?? "")
|
|
527
|
+
)
|
|
528
|
+
throw new TypeError(
|
|
529
|
+
"Wiki source requires an exact tenant and state digest",
|
|
530
|
+
);
|
|
531
|
+
const { head, selectedRevision } = this.#history({
|
|
532
|
+
stateRevisionDigest: stateDigest,
|
|
533
|
+
});
|
|
534
|
+
// A scoped lookup may prove absence only after authenticating the complete
|
|
535
|
+
// run. Corrupt/missing bytes and concurrent ledger changes still throw.
|
|
536
|
+
if (!selectedRevision && !required) return null;
|
|
537
|
+
if (!selectedRevision)
|
|
538
|
+
fail(
|
|
539
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
540
|
+
"Wiki state revision is not in authenticated history",
|
|
541
|
+
);
|
|
542
|
+
return freeze({
|
|
543
|
+
authenticated: true,
|
|
544
|
+
tenantId,
|
|
545
|
+
evolutionRunId: this.descriptor.evolutionRunId,
|
|
546
|
+
...selectedRevision,
|
|
547
|
+
ledgerHead: head,
|
|
104
548
|
});
|
|
105
|
-
|
|
106
|
-
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
#resolveEvent(event, authority, capturedResolution = null) {
|
|
552
|
+
const resolution =
|
|
553
|
+
capturedResolution ??
|
|
554
|
+
this.#resolveArtifact({
|
|
555
|
+
epoch: authority.epoch,
|
|
556
|
+
ledgerId: authority.ledgerId,
|
|
557
|
+
ref: event.subjectRef,
|
|
558
|
+
tenantId: this.descriptor.artifactTenantId,
|
|
559
|
+
});
|
|
560
|
+
if (
|
|
561
|
+
resolution?.ref !== event.subjectRef.ref ||
|
|
562
|
+
resolution.digest !== event.subjectRef.digest
|
|
563
|
+
) {
|
|
564
|
+
fail(
|
|
565
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
566
|
+
"Wiki ledger event resolved a substituted artifact",
|
|
567
|
+
);
|
|
107
568
|
}
|
|
108
569
|
return parseRecord(resolution, this.descriptor);
|
|
109
570
|
}
|
|
110
571
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
572
|
+
loadWiki = () => this.#loadWiki();
|
|
573
|
+
|
|
574
|
+
#loadWiki() {
|
|
575
|
+
const { state } = this.#history();
|
|
576
|
+
return freeze({
|
|
577
|
+
trusted: true,
|
|
578
|
+
state,
|
|
579
|
+
stateDigest: digestWikiState(state),
|
|
580
|
+
});
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
resolveHistory(input) {
|
|
584
|
+
return this.#resolveHistory(input);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
resolveAtCheckpoint(input) {
|
|
588
|
+
return this.#resolveHistory(input, true);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Provenance only: callers must authorize the plan and independently check
|
|
592
|
+
// the successor's actual operation/state, not treat a request digest as an
|
|
593
|
+
// effect receipt. Allowed digests describe an ordered prefix, not a set.
|
|
594
|
+
#resolveHistory(
|
|
595
|
+
{
|
|
596
|
+
tenantId,
|
|
597
|
+
stateDigest,
|
|
598
|
+
allowedMaintenanceRequestDigests = [],
|
|
599
|
+
checkpoint = null,
|
|
600
|
+
} = {},
|
|
601
|
+
historical = false,
|
|
602
|
+
) {
|
|
603
|
+
if (historical) {
|
|
604
|
+
const fields = [
|
|
605
|
+
"epoch",
|
|
606
|
+
"ledgerId",
|
|
607
|
+
"identityDigest",
|
|
608
|
+
"sequence",
|
|
609
|
+
"headDigest",
|
|
610
|
+
];
|
|
611
|
+
if (
|
|
612
|
+
!checkpoint ||
|
|
613
|
+
typeof checkpoint !== "object" ||
|
|
614
|
+
Array.isArray(checkpoint) ||
|
|
615
|
+
Object.keys(checkpoint).length !== fields.length ||
|
|
616
|
+
fields.some((key) => !Object.hasOwn(checkpoint, key)) ||
|
|
617
|
+
typeof checkpoint.epoch !== "string" ||
|
|
618
|
+
typeof checkpoint.ledgerId !== "string" ||
|
|
619
|
+
!DIGEST.test(checkpoint.identityDigest ?? "") ||
|
|
620
|
+
!DIGEST.test(checkpoint.headDigest ?? "") ||
|
|
621
|
+
!Number.isSafeInteger(checkpoint.sequence) ||
|
|
622
|
+
checkpoint.sequence < 1 ||
|
|
623
|
+
checkpoint.sequence > EVOLUTION_LEDGER_MAX_EVENTS
|
|
624
|
+
) {
|
|
625
|
+
throw new TypeError(
|
|
626
|
+
"Wiki historical read requires an exact authenticated checkpoint",
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
checkpoint = Object.freeze({ ...checkpoint });
|
|
630
|
+
} else if (checkpoint !== null) {
|
|
631
|
+
throw new TypeError(
|
|
632
|
+
"current Wiki history cannot be downgraded to a checkpoint view",
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
if (
|
|
636
|
+
tenantId !== this.descriptor.tenantId ||
|
|
637
|
+
!DIGEST.test(stateDigest ?? "") ||
|
|
638
|
+
!Array.isArray(allowedMaintenanceRequestDigests) ||
|
|
639
|
+
allowedMaintenanceRequestDigests.length > 128
|
|
640
|
+
) {
|
|
641
|
+
throw new TypeError(
|
|
642
|
+
"Wiki history requires an exact tenant, baseline, and bounded request sequence",
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
const allowed = [];
|
|
646
|
+
const length = allowedMaintenanceRequestDigests.length;
|
|
647
|
+
for (let index = 0; index < length; index += 1) {
|
|
648
|
+
const value = allowedMaintenanceRequestDigests[index];
|
|
649
|
+
if (!DIGEST.test(value ?? "") || allowed.includes(value)) {
|
|
650
|
+
throw new TypeError(
|
|
651
|
+
"Wiki history request digests must be unique and dense",
|
|
652
|
+
);
|
|
117
653
|
}
|
|
654
|
+
allowed.push(value);
|
|
118
655
|
}
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
656
|
+
const { head, viewState, source, successors } = this.#history({
|
|
657
|
+
sourceDigest: stateDigest,
|
|
658
|
+
allowed,
|
|
659
|
+
checkpoint,
|
|
660
|
+
});
|
|
661
|
+
if (!source) {
|
|
662
|
+
fail(
|
|
663
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
664
|
+
"Wiki baseline is not in authenticated history",
|
|
665
|
+
);
|
|
123
666
|
}
|
|
124
|
-
return {
|
|
667
|
+
return freeze({
|
|
668
|
+
authenticated: true,
|
|
669
|
+
tenantId,
|
|
670
|
+
evolutionRunId: this.descriptor.evolutionRunId,
|
|
671
|
+
source: { trusted: true, state: source, stateDigest },
|
|
672
|
+
current: {
|
|
673
|
+
trusted: true,
|
|
674
|
+
state: viewState,
|
|
675
|
+
stateDigest: digestWikiState(viewState),
|
|
676
|
+
},
|
|
677
|
+
successors,
|
|
678
|
+
ledgerHead: head,
|
|
679
|
+
scope: historical ? "checkpoint" : "current",
|
|
680
|
+
checkpoint,
|
|
681
|
+
});
|
|
125
682
|
}
|
|
126
683
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
684
|
+
commitRevision = ({
|
|
685
|
+
expectedStateDigest,
|
|
686
|
+
revision,
|
|
687
|
+
expectedLedgerHead,
|
|
688
|
+
} = {}) => {
|
|
689
|
+
const headKeys = [
|
|
690
|
+
"epoch",
|
|
691
|
+
"ledgerId",
|
|
692
|
+
"identityDigest",
|
|
693
|
+
"sequence",
|
|
694
|
+
"headDigest",
|
|
695
|
+
];
|
|
696
|
+
if (expectedLedgerHead !== undefined) {
|
|
697
|
+
if (
|
|
698
|
+
!expectedLedgerHead ||
|
|
699
|
+
typeof expectedLedgerHead !== "object" ||
|
|
700
|
+
Array.isArray(expectedLedgerHead) ||
|
|
701
|
+
Object.keys(expectedLedgerHead).length !== headKeys.length ||
|
|
702
|
+
headKeys.some((key) => !Object.hasOwn(expectedLedgerHead, key)) ||
|
|
703
|
+
typeof expectedLedgerHead.epoch !== "string" ||
|
|
704
|
+
typeof expectedLedgerHead.ledgerId !== "string" ||
|
|
705
|
+
!DIGEST.test(expectedLedgerHead.identityDigest ?? "") ||
|
|
706
|
+
!Number.isSafeInteger(expectedLedgerHead.sequence) ||
|
|
707
|
+
expectedLedgerHead.sequence < 0 ||
|
|
708
|
+
(expectedLedgerHead.sequence === 0
|
|
709
|
+
? expectedLedgerHead.headDigest !== null
|
|
710
|
+
: !DIGEST.test(expectedLedgerHead.headDigest ?? ""))
|
|
711
|
+
) {
|
|
712
|
+
throw new TypeError("Wiki expected ledger head is invalid");
|
|
713
|
+
}
|
|
714
|
+
expectedLedgerHead = Object.freeze({ ...expectedLedgerHead });
|
|
715
|
+
}
|
|
716
|
+
if (
|
|
717
|
+
!DIGEST.test(expectedStateDigest ?? "") ||
|
|
718
|
+
revision?.schema !== WIKI_REVISION_SCHEMA ||
|
|
719
|
+
revision.tenantId !== this.descriptor.tenantId ||
|
|
720
|
+
revision.evolutionRunId !== this.descriptor.evolutionRunId ||
|
|
721
|
+
revision.stateDigest !== digestWikiState(revision.state) ||
|
|
722
|
+
revision.state.revisionId !== revision.revisionId ||
|
|
723
|
+
!REVISION_ID.test(revision.revisionId ?? "")
|
|
724
|
+
) {
|
|
138
725
|
throw new TypeError("Wiki revision commit request is invalid");
|
|
139
726
|
}
|
|
140
|
-
|
|
141
|
-
|
|
727
|
+
// Own the revision before handing it to any persistence callback.
|
|
728
|
+
revision = freeze(
|
|
729
|
+
structuredClone(verifyRevision(revision, this.descriptor)),
|
|
730
|
+
);
|
|
731
|
+
const { head, latest, state: currentState } = this.#history();
|
|
732
|
+
if (
|
|
733
|
+
expectedLedgerHead &&
|
|
734
|
+
headKeys.some((key) => expectedLedgerHead[key] !== head[key])
|
|
735
|
+
) {
|
|
736
|
+
fail(
|
|
737
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
738
|
+
"Wiki authorization ledger head changed before revision commit",
|
|
739
|
+
);
|
|
740
|
+
}
|
|
142
741
|
const currentDigest = digestWikiState(currentState);
|
|
143
742
|
if (currentDigest !== expectedStateDigest) {
|
|
144
|
-
if (
|
|
145
|
-
|
|
146
|
-
|
|
743
|
+
if (
|
|
744
|
+
latest?.revision.revisionId === revision.revisionId &&
|
|
745
|
+
currentDigest === revision.stateDigest
|
|
746
|
+
) {
|
|
747
|
+
return Object.freeze({
|
|
748
|
+
committed: true,
|
|
749
|
+
recovered: true,
|
|
750
|
+
revisionId: revision.revisionId,
|
|
751
|
+
stateDigest: revision.stateDigest,
|
|
752
|
+
evolutionRunId: this.descriptor.evolutionRunId,
|
|
753
|
+
});
|
|
147
754
|
}
|
|
148
|
-
fail(
|
|
755
|
+
fail(
|
|
756
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
757
|
+
"Wiki state changed before revision commit",
|
|
758
|
+
);
|
|
149
759
|
}
|
|
150
|
-
if (
|
|
151
|
-
|
|
760
|
+
if (
|
|
761
|
+
revision.revision !== currentState.revision + 1 ||
|
|
762
|
+
revision.priorStateDigest !== currentDigest
|
|
763
|
+
) {
|
|
764
|
+
fail(
|
|
765
|
+
WIKI_LEDGER_CONFLICT_CODE,
|
|
766
|
+
"Wiki revision does not extend the current state",
|
|
767
|
+
);
|
|
152
768
|
}
|
|
153
|
-
|
|
154
|
-
const published = this
|
|
769
|
+
verifyRequestTransition(currentState, revision);
|
|
770
|
+
const published = this.#putCanonical("wiki-revision", revision, {
|
|
155
771
|
audience: this.descriptor.audience,
|
|
156
772
|
purpose: this.descriptor.purpose,
|
|
157
773
|
retention: "ledger",
|
|
158
774
|
});
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
775
|
+
if (
|
|
776
|
+
!published?.ref ||
|
|
777
|
+
published.receipt?.persisted !== true ||
|
|
778
|
+
published.receipt?.readbackVerified !== true ||
|
|
779
|
+
published.receipt?.integrityVerified !== true ||
|
|
780
|
+
published.receipt?.retention !== "ledger"
|
|
781
|
+
) {
|
|
782
|
+
fail(
|
|
783
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
784
|
+
"Wiki revision artifact was not durably read back",
|
|
785
|
+
);
|
|
162
786
|
}
|
|
163
787
|
const eventId = `wiki.revision.${revision.revisionId.slice("wiki:".length)}`;
|
|
164
|
-
const receipt = this
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
788
|
+
const receipt = this.#appendDomainEvent(
|
|
789
|
+
{
|
|
790
|
+
artifactTenantId: this.descriptor.artifactTenantId,
|
|
791
|
+
correlationId: this.descriptor.evolutionRunId,
|
|
792
|
+
decision: "committed",
|
|
793
|
+
eventId,
|
|
794
|
+
reason: `wiki revision ${revision.revision} committed`,
|
|
795
|
+
skillName: null,
|
|
796
|
+
sourceRefs: latest ? [latest.event.subjectRef] : [],
|
|
797
|
+
subjectRef: published.ref,
|
|
798
|
+
tenantId: this.descriptor.tenantId,
|
|
799
|
+
timestamp: revision.effectiveAt,
|
|
800
|
+
type: WIKI_LEDGER_EVENT_TYPE,
|
|
801
|
+
},
|
|
802
|
+
{ expectedHeadDigest: head.headDigest, expectedSequence: head.sequence },
|
|
803
|
+
);
|
|
804
|
+
if (
|
|
805
|
+
receipt?.authenticated !== true ||
|
|
806
|
+
receipt?.committed !== true ||
|
|
807
|
+
receipt?.durable !== true ||
|
|
808
|
+
receipt.eventId !== eventId ||
|
|
809
|
+
!DIGEST.test(receipt.receiptDigest ?? "")
|
|
810
|
+
) {
|
|
811
|
+
fail(
|
|
812
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
813
|
+
"Wiki ledger did not confirm a durable authenticated append",
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
const stored = this.#history().latest;
|
|
817
|
+
if (
|
|
818
|
+
stored?.revision.revisionId !== revision.revisionId ||
|
|
819
|
+
stored.revision.stateDigest !== revision.stateDigest
|
|
820
|
+
) {
|
|
821
|
+
fail(
|
|
822
|
+
WIKI_LEDGER_CORRUPT_CODE,
|
|
823
|
+
"Wiki revision readback differs after ledger commit",
|
|
824
|
+
);
|
|
825
|
+
}
|
|
826
|
+
return Object.freeze({
|
|
827
|
+
committed: true,
|
|
828
|
+
recovered: false,
|
|
829
|
+
revisionId: revision.revisionId,
|
|
830
|
+
stateDigest: revision.stateDigest,
|
|
831
|
+
evolutionRunId: this.descriptor.evolutionRunId,
|
|
832
|
+
ledgerReceiptDigest: receipt.receiptDigest,
|
|
833
|
+
});
|
|
188
834
|
};
|
|
189
835
|
|
|
190
836
|
maintainerPorts({ resolveEvidence, derive } = {}) {
|
|
191
837
|
if (typeof resolveEvidence !== "function" || typeof derive !== "function") {
|
|
192
838
|
throw new TypeError("resolveEvidence and derive ports are required");
|
|
193
839
|
}
|
|
194
|
-
return Object.freeze({
|
|
840
|
+
return Object.freeze({
|
|
841
|
+
loadWiki: () => this.#loadWiki(),
|
|
842
|
+
commitRevision: this.commitRevision,
|
|
843
|
+
resolveEvidence,
|
|
844
|
+
derive,
|
|
845
|
+
});
|
|
195
846
|
}
|
|
196
847
|
}
|
|
197
848
|
|
|
849
|
+
export function captureWikiRevisionReader(adapter) {
|
|
850
|
+
const reader = READERS.get(adapter);
|
|
851
|
+
if (!reader)
|
|
852
|
+
throw new TypeError(
|
|
853
|
+
"a branded WikiMaintainerLedgerAdapter reader is required",
|
|
854
|
+
);
|
|
855
|
+
return reader;
|
|
856
|
+
}
|
|
857
|
+
|
|
198
858
|
export function createWikiMaintainerLedgerAdapter(options) {
|
|
199
859
|
return new WikiMaintainerLedgerAdapter(options);
|
|
200
860
|
}
|