chainlesschain 0.166.21 → 0.166.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -9
- package/package.json +4 -3
- package/src/assets/web-panel/assets/{AIOps-BjMnsUci.js → AIOps-DR-MWcZc.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DdYFP03A.js → ActionButton-DT8B7sEb.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-Bb8TuuK_.js → Analytics-asjh3dQJ.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Kn3TIOtk.js → AppLayout-DivQ491i.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-4IxpqI_b.js → Artifacts-DPH2uUmy.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-BOV2caqU.js → Audit-Bp2nLyc-.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-B86k-ay4.js → BackgroundAgents-CHS28khl.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-C5_ie1e3.js → Backup-CKeaFSfz.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-xpwg6QCW.js → BaseInput-CxwM9BAH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CVZOcZau.js → Chat-DYLDwaCv.js} +4 -4
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-D8fPYhUu.js → ChatBubbleRenderer-DdBJDBP0.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-MKTq3zdP.js → Checkbox-uYTWOB8j.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-JUk3wzep.js → Codegen-CvYa_dwT.js} +1 -1
- package/src/assets/web-panel/assets/{Col-JPvTA0kC.js → Col-CanMAX4m.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Tqgl87NQ.js → Community-B4WaDtHw.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BuAFYBmN.js → Compact-K93Uof_3.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CXS9WIPZ.js → Compliance-CKeDLgUW.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-Ds2bFHrr.js → Cowork-P93grAeB.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-C_dV_OeW.js → Cron-BSHnMtDn.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BsO6tIRo.js → Crosschain-epAOpUVJ.js} +1 -1
- package/src/assets/web-panel/assets/{DID-rNOFqBac.js → DID-ByjXfP7t.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-C2fcKKVY.js → Dashboard-QztTU8tb.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-Y7Ndr0X_.js → Dropdown-DhUc9yhN.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DcP_uPmL.js → EmailListRenderer-C2sLhJJN.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-Cwn3gDzk.js → FamilyGuardDashboard-CdfbWNDn.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-ClQuOsqb.js → Federation-CcF_R7NW.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DfwtmlcK.js → FormItemContext-Cm_X2IBk.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-zNZhtbC5.js → GenericCardRenderer-DUi4NWlb.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BZmdW-G5.js → Git-4Sq5FjBt.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CqBk4lEn.js → Governance-Dx2_v4V6.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-Dbmt3ZXk.js → Inference-7Vr1xekR.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-hMTH6qf3.js → KnowledgeGraph-Cnd2XOzf.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-CkiYgiW2.js → Logs-B66QPVf-.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-BL1FElXg.js → MarkdownRenderer-PLsEvhly.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CbB6wfin.js → Marketplace-BMIK9BmC.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BSwiFtte.js → McpTools-BDbyp3J_.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-B03PeHrz.js → Memory-CJdzfZGi.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CRGrnd-X.js → MobileBridge-C2TH5Y3-.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CE_5v2kO.js → MobileProjects-D1dYXkvV.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-Dp11QVx1.js → Mtc-B-4A1I1j.js} +4 -4
- package/src/assets/web-panel/assets/{MtcAudit-CYu-3JBu.js → MtcAudit-Bgcc9UOl.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-CGyJ0Xl3.js → Multisig-DqOe-etP.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CoWi_ov1.js → NLProgramming-7VnhzE_6.js} +1 -1
- package/src/assets/web-panel/assets/Notes-BxawpeUQ.js +7 -0
- package/src/assets/web-panel/assets/{NotificationSettings-DX4I2b4W.js → NotificationSettings-Cr08G2aE.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Ce8bEGlK.js +1 -0
- package/src/assets/web-panel/assets/{Organization-oopLO_tk.js → Organization-BC7lveGv.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BFVvjMyf.js → Overflow-CakOW-G0.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-CBy5t-Tk.js → P2P-Cf8CaOBZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser--YWJNsu6.js → PdhVaultBrowser-Dc7b98W9.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-C2dZ8scb.js → Permissions-DGJyMEfS.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-Bs3l7Hlx.js → PersonalDataHub-DNIwSdwu.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-DEBWbZuD.js → Pipeline-5B1S12wa.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-CjHBb6NU.js → Privacy-CMB6Ke5t.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-D2WipUz5.js → ProjectInit-D5PqTFiT.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-B6WfnrGB.js → ProjectSettings-CbKNdSjV.js} +2 -2
- package/src/assets/web-panel/assets/Projects-ccXaHzYL.js +1 -0
- package/src/assets/web-panel/assets/{Providers-CCv5M_Dv.js → Providers-CJF5_-Gs.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-CGthxU54.js → QrScannerModal-CT6iEAdi.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-CnPmXPFb.js → QuickAsk-Ci0h9mJ_.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-Df_tGEa9.js → Recommend-Da5mobZu.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-Z58N0Loe.js → RemoteSession-BaCY8eey.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-CZTBQ2Vt.js → Reputation-CaITfTsI.js} +1 -1
- package/src/assets/web-panel/assets/{Row-CdK3YpCQ.js → Row-DtUDamyP.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CFMVT5sb.js → RssFeed-DX27gFpg.js} +3 -3
- package/src/assets/web-panel/assets/{Search-DrF8RIvD.js → Search-DFL69osN.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Ddk2f2DM.js → Security-BqGeoWv-.js} +3 -3
- package/src/assets/web-panel/assets/{Services-CCuK-VOo.js → Services-3z1WnEAc.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DxCpHzeM.js → Skeleton-C_OJQQ9Z.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-t2oTDgcv.js → Skills-BY7aT6Mo.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-Df63M9_R.js → Sla-BZv7DSaD.js} +1 -1
- package/src/assets/web-panel/assets/SpeechSettings-6lJKLhCn.js +1 -0
- package/src/assets/web-panel/assets/{SyncSettings-COd_tgPp.js → SyncSettings-B6D7STlI.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-CzDCcrik.js → Tasks-Co_FCZAO.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D-vfxTGA.js → Templates-CnY-9fgz.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-BlpT_Gxc.js → Tenant-B71yXfZ8.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-D5rq52Hg.js → Terminal-Dd_P7awo.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DdoMndkK.js → TimelineRenderer-CvIEMyli.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BhgBsI6g.js → Tokens-DknFBGOi.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DwwzoikZ.js → Trigger-D_4nJONB.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-HkTpzXFb.js → Trust-BNl21fa7.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-D9nk6Ehe.js → UkeySign-CFrCI7uK.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BKk0rfoy.js → VideoEditing-BVfY6JLg.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-IVWIU_Lq.js → Wallet-Cj9CAK0J.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-CFTCpfsG.js → WebAuthn-DcqZlzA3.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-Dnf4Obif.js → WorkflowEditor-Dfr_dMld.js} +1 -1
- package/src/assets/web-panel/assets/{chat-D2snERdj.js → chat-Yv6UF0AD.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DKEjK1N1.js → colors-CDW_-1fs.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BEDLwQdt.js → compact-item-BYOQvd-6.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DA9iW1a0.js → createContext-BCGO0BiP.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-H-kXSuf-.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-5l2xEcY9.js → hasIn-DY-70cfQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B7_W_rYd.js → index-366wfQBU.js} +1 -1
- package/src/assets/web-panel/assets/index-B0o4MeNK.js +1 -0
- package/src/assets/web-panel/assets/{index-CxEtQYdi.js → index-B9ZogJJM.js} +1 -1
- package/src/assets/web-panel/assets/{index-B00GeekA.js → index-B9m5QAMg.js} +1 -1
- package/src/assets/web-panel/assets/{index-C7sKbM5s.js → index-BBs2mv5M.js} +1 -1
- package/src/assets/web-panel/assets/{index-CX1x4AFn.js → index-BFv1hzF6.js} +1 -1
- package/src/assets/web-panel/assets/index-BVafOL_I.js +1 -0
- package/src/assets/web-panel/assets/{index-DU2TXJu-.js → index-BXlEx4UH.js} +1 -1
- package/src/assets/web-panel/assets/{index-e-e40id6.js → index-BayRTE5w.js} +1 -1
- package/src/assets/web-panel/assets/{index-DXet1xol.js → index-Bb9nyts1.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7z4zB_a.js → index-Bf_Va0S-.js} +1 -1
- package/src/assets/web-panel/assets/{index-fccZmC_h.js → index-Br3wQLVY.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bqc8tdIF.js → index-BvK4fjkk.js} +1 -1
- package/src/assets/web-panel/assets/{index-BO9dQjpt.js → index-C40UdtlS.js} +1 -1
- package/src/assets/web-panel/assets/{index-Csfb-7hw.js → index-C4UJA2ju.js} +1 -1
- package/src/assets/web-panel/assets/{index-Td8ZwyoC.js → index-CB_Iw73G.js} +1 -1
- package/src/assets/web-panel/assets/{index-BZ5lY2zx.js → index-CCwWp3mT.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpqtbXdE.js → index-CFa2fPCk.js} +1 -1
- package/src/assets/web-panel/assets/{index-NJieh3T1.js → index-CIyHxV4u.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbkghqn_.js → index-CUP-A2_h.js} +1 -1
- package/src/assets/web-panel/assets/{index-DqwPFbOb.js → index-CUo27q9J.js} +3 -3
- package/src/assets/web-panel/assets/{index-B4QYBliR.js → index-CaT8trvf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BgfImyZI.js → index-CnZNbcux.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dbd7eEex.js → index-Cy2NE6AO.js} +1 -1
- package/src/assets/web-panel/assets/{index-CbTPvp2_.js → index-CzeEEazr.js} +1 -1
- package/src/assets/web-panel/assets/{index-5pW4t1iD.js → index-D--TEyDj.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dg2a9owQ.js → index-DCtsjhhT.js} +1 -1
- package/src/assets/web-panel/assets/{index-B_eCoZgW.js → index-DLOf7BSz.js} +1 -1
- package/src/assets/web-panel/assets/{index-7P1b8HZo.js → index-DM5c4pc-.js} +1 -1
- package/src/assets/web-panel/assets/{index-CRPrHE7h.js → index-DRFC2Qt0.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bq5P3piS.js → index-DT_qVaaV.js} +1 -1
- package/src/assets/web-panel/assets/{index-CjWltbi_.js → index-DUDoRk9r.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkMKuqUs.js → index-Dg-AQYDf.js} +1 -1
- package/src/assets/web-panel/assets/{index-DLoalqRX.js → index-DuIPq5MX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CGlotREA.js → index-NYVBUAVN.js} +1 -1
- package/src/assets/web-panel/assets/{index-yYEQXYaU.js → index-NaCESahy.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmruhzFi.js → index-RjIMPG0u.js} +1 -1
- package/src/assets/web-panel/assets/{index-fgYk0QXO.js → index-Y9akzgFO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvV03Ayk.js → index-hZ0Eyrrw.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CPrcB1TC.js → initDefaultProps-CG99CcR4.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BQ7mWRh_.js → motion-Z7MH0_0G.js} +1 -1
- package/src/assets/web-panel/assets/{move-CzOEq99p.js → move-BX67lOdq.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BlQI5jrw.js → mtc-parser-CmAbG1fE.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DlW4gxmv.js → omit-DiU5tI1_.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-BBYms5nP.js → pickAttrs-BGfvLrYL.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-az2MPJ_7.js → placementArrow-CggLEgaJ.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-D1-ibEol.js → responsiveObserve-t3nlghPZ.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DHGqa4GA.js → slide-BkV4dL9s.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-CYGDo6lD.js → statusUtils-qec1PUoC.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-Cl2EM9K6.js → styleChecker-ChjX6T8D.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DdYhzuv1.js → useFlexGapSupport-B1jLoZcM.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DWumPuBW.js → useFs-C3X53s4E.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DxAO-Aqi.js → usePersonalDataHub-DOvbbnkZ.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-CplsQf_N.js → vnode-Ie0TEVFT.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Cw5HXNSG.js → zoom-CRUMVS8l.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +18 -1
- package/src/commands/evolution-benchmark.js +72 -0
- package/src/commands/evolution.js +2 -0
- package/src/commands/governed-skill-marketplace.js +142 -0
- package/src/commands/marketplace.js +4 -1
- package/src/commands/serve.js +41 -0
- package/src/commands/skill.js +3 -0
- package/src/data/changelog.json +39 -0
- package/src/gateways/ws/ws-agent-handler.js +59 -2
- package/src/gateways/ws/ws-server.js +2 -0
- package/src/harness/golden-transcript.js +1 -0
- package/src/harness/prompt-compressor.js +51 -5
- package/src/harness/provider-backed-compaction.js +28 -1
- package/src/harness/remote-session-registry.js +15 -3
- package/src/index.js +30 -4
- package/src/lazy-dispatch.js +15 -1
- package/src/lib/advisor-runtime.js +55 -2
- package/src/lib/app-server/cli-agent-kernel-adapter.js +4 -0
- package/src/lib/app-server/graph-runtime.js +32 -0
- package/src/lib/app-server/server.js +45 -1
- package/src/lib/app-server/websocket-transport.js +23 -0
- package/src/lib/autonomous-agent.js +63 -13
- package/src/lib/cowork/ab-comparator-cli.js +4 -3
- package/src/lib/cowork/debate-review-cli.js +4 -3
- package/src/lib/cowork/decision-kb-cli.js +5 -0
- package/src/lib/cowork-adapter.js +38 -16
- package/src/lib/evolution/agent-evolution-ingress.js +95 -15
- package/src/lib/evolution/agent-evolution-runtime-composition.js +82 -0
- package/src/lib/evolution/agent-evolution-session-lifecycle.js +46 -0
- package/src/lib/evolution/agent-model-projection.js +217 -0
- package/src/lib/evolution/bounded-descriptor-read.js +29 -0
- package/src/lib/evolution/controlled-skill-pilot-ledger-adapter.js +551 -0
- package/src/lib/evolution/controlled-skill-production-pilot.js +308 -18
- package/src/lib/evolution/evidence-backed-wiki-maintainer.js +10 -1
- package/src/lib/evolution/evidence-json-text.js +236 -0
- package/src/lib/evolution/evolution-artifact-ports.js +202 -21
- package/src/lib/evolution/evolution-deployment-loader.js +369 -0
- package/src/lib/evolution/evolution-eval-child-evidence-ledger-adapter.js +373 -0
- package/src/lib/evolution/evolution-eval-gate.js +14 -1
- package/src/lib/evolution/evolution-eval-process-supervisor-worker.mjs +14 -0
- package/src/lib/evolution/evolution-eval-process-supervisor.js +607 -0
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +14 -1
- package/src/lib/evolution/evolution-evidence-projector.js +240 -37
- package/src/lib/evolution/evolution-file-witness.js +153 -30
- package/src/lib/evolution/evolution-ledger-ports.js +1027 -66
- package/src/lib/evolution/evolution-ledger.js +66 -2
- package/src/lib/evolution/evolution-raw-crypto-shred.js +29 -15
- package/src/lib/evolution/evolution-raw-deletion-ledger-adapter.js +865 -0
- package/src/lib/evolution/evolution-release-train-domain-stages.js +769 -0
- package/src/lib/evolution/evolution-release-train-ledger-adapter.js +335 -0
- package/src/lib/evolution/evolution-release-train-stage-output-ledger-adapter.js +333 -0
- package/src/lib/evolution/evolution-release-train.js +586 -0
- package/src/lib/evolution/evolution-workbench-batch-executor.js +101 -144
- package/src/lib/evolution/evolution-workbench-control-ports.js +203 -0
- package/src/lib/evolution/evolution-workbench-file-resources.js +403 -0
- package/src/lib/evolution/evolution-workbench-projection.js +152 -25
- package/src/lib/evolution/evolution-workbench-registry-source.js +482 -0
- package/src/lib/evolution/evolution-workbench-review-ledger-adapter.js +823 -0
- package/src/lib/evolution/evolution-workbench-review-protocol.js +157 -0
- package/src/lib/evolution/evolution-workbench-rollback-authorization.js +57 -0
- package/src/lib/evolution/evolution-workbench-rollback-ledger-adapter.js +1016 -0
- package/src/lib/evolution/evolution-workbench-runtime.js +133 -0
- package/src/lib/evolution/evolution-workbench-version-control.js +70 -36
- package/src/lib/evolution/evolvable-artifact-ledger-adapter.js +736 -0
- package/src/lib/evolution/governed-knowledge-artifact-lifecycle.js +364 -0
- package/src/lib/evolution/governed-knowledge-candidate-rejection.js +343 -0
- package/src/lib/evolution/governed-knowledge-dependency-authority.js +227 -44
- package/src/lib/evolution/governed-knowledge-dependency-ledger-executor.js +95 -83
- package/src/lib/evolution/governed-knowledge-merge-ledger-executor.js +29 -2
- package/src/lib/evolution/governed-knowledge-merge-publisher-authority.js +31 -3
- package/src/lib/evolution/governed-knowledge-record.js +148 -0
- package/src/lib/evolution/governed-knowledge-revocation-record.js +135 -0
- package/src/lib/evolution/governed-knowledge-skill-rollback.js +475 -0
- package/src/lib/evolution/governed-knowledge-sync-ledger-adapter.js +92 -6
- package/src/lib/evolution/governed-knowledge-sync-merge-publisher.js +57 -4
- package/src/lib/evolution/governed-knowledge-sync.js +332 -99
- package/src/lib/evolution/governed-knowledge-wiki-tombstone.js +462 -0
- package/src/lib/evolution/governed-skill-marketplace-badge.js +208 -0
- package/src/lib/evolution/governed-skill-marketplace-candidate.js +330 -0
- package/src/lib/evolution/governed-skill-marketplace-cli-host.js +308 -0
- package/src/lib/evolution/governed-skill-marketplace-ledger-adapter.js +420 -0
- package/src/lib/evolution/governed-skill-marketplace.js +288 -5
- package/src/lib/evolution/governed-wiki-pruning-journal.js +302 -0
- package/src/lib/evolution/governed-wiki-pruning-ledger-adapter.js +459 -0
- package/src/lib/evolution/governed-wiki-pruning-maintenance.js +576 -0
- package/src/lib/evolution/governed-wiki-pruning-plan-authority.js +169 -0
- package/src/lib/evolution/governed-wiki-pruning-raw-shred.js +207 -0
- package/src/lib/evolution/governed-wiki-pruning-retrieval.js +587 -0
- package/src/lib/evolution/governed-wiki-pruning-runtime.js +153 -0
- package/src/lib/evolution/governed-wiki-pruning-skill-rollback.js +360 -0
- package/src/lib/evolution/governed-wiki-pruning.js +322 -143
- package/src/lib/evolution/independent-skill-revocation-source.js +231 -0
- package/src/lib/evolution/knowledge-wiki-source-admission.js +124 -0
- package/src/lib/evolution/knowledge-wiki-source-provenance.js +359 -0
- package/src/lib/evolution/progressive-canary-external-watchdog.js +578 -0
- package/src/lib/evolution/progressive-canary-traffic-worker.js +628 -0
- package/src/lib/evolution/progressive-canary-watchdog-file-store.js +285 -0
- package/src/lib/evolution/progressive-canary-watchdog-node-pki.js +265 -0
- package/src/lib/evolution/skill-candidate-registry.js +22 -0
- package/src/lib/evolution/skill-promotion-controller.js +25 -0
- package/src/lib/evolution/skill-promotion-review-ledger-adapter.js +100 -0
- package/src/lib/evolution/skill-registry-transition-ledger-adapter.js +131 -2
- package/src/lib/evolution/skill-release-registry.js +25 -4
- package/src/lib/evolution/skill-retrieval-revocation-authority.js +361 -0
- package/src/lib/evolution/skill-retrieval-revocation-ledger-adapter.js +346 -0
- package/src/lib/evolution/skill-revocation-propagation.js +467 -0
- package/src/lib/evolution/skill-target-matrix-eval.js +162 -11
- package/src/lib/evolution/skill-wiki-reconciliation.js +985 -0
- package/src/lib/evolution/skill-writer-inventory-manifest.js +15 -12
- package/src/lib/evolution/statistical-progressive-canary.js +845 -0
- package/src/lib/evolution/structured-memory-agent-control-plane.js +120 -0
- package/src/lib/evolution/structured-memory-authority-ledger-adapter.js +5 -1
- package/src/lib/evolution/structured-memory-promotion-receipt-writer.js +126 -0
- package/src/lib/evolution/wiki-informed-skill-proposer.js +127 -21
- package/src/lib/evolution/wiki-maintainer-ledger-adapter.js +760 -100
- package/src/lib/evolution/wiki-revision-protocol.js +120 -0
- package/src/lib/evolution/wiki-skill-proposal-ledger-adapter.js +307 -0
- package/src/lib/evolution/wiki-target-tombstone-revision.js +101 -0
- package/src/lib/evolution/wikiskill-benchmark-cli-host.js +178 -0
- package/src/lib/evolution/wikiskill-benchmark-execution-host.js +702 -0
- package/src/lib/evolution/wikiskill-benchmark-ledger-adapter.js +613 -0
- package/src/lib/evolution/wikiskill-benchmark.js +574 -0
- package/src/lib/goal-assess.js +17 -10
- package/src/lib/interactive-planner.js +9 -1
- package/src/lib/iteration-budget.js +16 -2
- package/src/lib/micro-compact.js +4 -1
- package/src/lib/model-failure-policy.js +21 -0
- package/src/lib/process-execution-broker/index.js +1 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
- package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
- package/src/lib/process-execution-broker/windows-sandbox.cs +33 -15
- package/src/lib/read-file-page.js +191 -0
- package/src/lib/runnable-provider.js +2 -1
- package/src/lib/session-host-lease.js +11 -16
- package/src/lib/skill-retrieval-router.js +22 -1
- package/src/repl/agent-repl.js +127 -33
- package/src/runtime/agent-core.js +224 -80
- package/src/runtime/agent-runtime.js +43 -0
- package/src/runtime/coding-agent-contract-shared.cjs +7 -1
- package/src/runtime/fallback-model.js +143 -62
- package/src/runtime/headless-runner.js +54 -10
- package/src/runtime/headless-stream.js +53 -6
- package/src/runtime/runtime-factory.js +41 -2
- package/src/assets/web-panel/assets/Notes-CgU9DDo9.js +0 -7
- package/src/assets/web-panel/assets/OrderTableRenderer-CwHc15Zs.js +0 -1
- package/src/assets/web-panel/assets/Projects-FF_thRi6.js +0 -1
- package/src/assets/web-panel/assets/SpeechSettings-l7ox6KuX.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DyhgpXPf.js +0 -1
- package/src/assets/web-panel/assets/index-Ck1jhFE0.js +0 -1
- package/src/assets/web-panel/assets/index-c8jJEHVs.js +0 -1
|
@@ -0,0 +1,769 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { types as utilTypes } from "node:util";
|
|
3
|
+
|
|
4
|
+
import { createEvolutionTrainStageReceipt } from "./evolution-release-train.js";
|
|
5
|
+
import {
|
|
6
|
+
evaluateSkillTargetMatrix,
|
|
7
|
+
verifySkillTargetMatrixEvalReceipt,
|
|
8
|
+
} from "./skill-target-matrix-eval.js";
|
|
9
|
+
import { buildSkillPromotionReviewPacket } from "./skill-promotion-review.js";
|
|
10
|
+
import { WIKI_PROPOSAL_STATUS } from "./wiki-informed-skill-proposer.js";
|
|
11
|
+
|
|
12
|
+
const STAGES = Object.freeze({
|
|
13
|
+
WIKI: "wiki-maintain",
|
|
14
|
+
PROPOSE: "propose",
|
|
15
|
+
CANDIDATE: "candidate",
|
|
16
|
+
EVAL: "eval",
|
|
17
|
+
REVIEW: "review",
|
|
18
|
+
PILOT: "pilot",
|
|
19
|
+
PROMOTION: "promotion",
|
|
20
|
+
WIKI_IMPACT: "wiki-impact",
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
function capture(owner, method, name) {
|
|
24
|
+
if (!owner || typeof owner[method] !== "function")
|
|
25
|
+
throw new TypeError(`${name}.${method}() is required`);
|
|
26
|
+
return (...args) => Reflect.apply(owner[method], owner, args);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function assertMatrixEvalPlanBinding(receipt, expected, plan, planRef) {
|
|
30
|
+
if (
|
|
31
|
+
planRef?.digest !== plan.matrixEvalPlanDigest ||
|
|
32
|
+
expected.planDigest !== plan.matrixEvalPlanDigest ||
|
|
33
|
+
expected.tenantId !== plan.tenantId ||
|
|
34
|
+
expected.skillName !== plan.skillId ||
|
|
35
|
+
expected.candidateId !== plan.candidateId ||
|
|
36
|
+
expected.candidateContentDigest !== plan.candidateDigest ||
|
|
37
|
+
expected.baselineId !== plan.baselineId ||
|
|
38
|
+
expected.baselineReleaseDigest !== plan.baselineReleaseDigest ||
|
|
39
|
+
expected.expectedActiveContentDigest !== plan.baselineContentDigest ||
|
|
40
|
+
expected.expectedActiveRevision !== plan.baselineRevision ||
|
|
41
|
+
expected.targetMatrixRoot !== plan.targetMatrixDigest ||
|
|
42
|
+
expected.decision !== "accepted" ||
|
|
43
|
+
receipt.tenantId !== plan.tenantId ||
|
|
44
|
+
receipt.skillName !== plan.skillId ||
|
|
45
|
+
receipt.candidateId !== plan.candidateId ||
|
|
46
|
+
receipt.candidateContentDigest !== plan.candidateDigest ||
|
|
47
|
+
receipt.baselineId !== plan.baselineId ||
|
|
48
|
+
receipt.baselineReleaseDigest !== plan.baselineReleaseDigest ||
|
|
49
|
+
receipt.expectedActiveContentDigest !== plan.baselineContentDigest ||
|
|
50
|
+
receipt.expectedActiveRevision !== plan.baselineRevision ||
|
|
51
|
+
receipt.targetMatrixRoot !== plan.targetMatrixDigest ||
|
|
52
|
+
receipt.planDigest !== plan.matrixEvalPlanDigest ||
|
|
53
|
+
receipt.decision !== "accepted" ||
|
|
54
|
+
!Array.isArray(receipt.cellResults) ||
|
|
55
|
+
receipt.cellResults.length === 0 ||
|
|
56
|
+
receipt.cellResults.some(
|
|
57
|
+
(cell) =>
|
|
58
|
+
cell.suiteDigest !== plan.evalSuiteDigest ||
|
|
59
|
+
cell.policyDigest !== plan.policyDigest,
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
throw new Error(
|
|
63
|
+
"matrix evaluation receipt is not bound to the EvolutionPlan",
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function freezeClone(value) {
|
|
68
|
+
return Object.freeze(structuredClone(value));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function bindPromotionInput(value) {
|
|
72
|
+
const capability = value?.authorization?.capability;
|
|
73
|
+
if (!capability) return freezeClone(value);
|
|
74
|
+
const { authorization, ...request } = value;
|
|
75
|
+
const authorizationData = { ...authorization };
|
|
76
|
+
delete authorizationData.capability;
|
|
77
|
+
return Object.freeze({
|
|
78
|
+
...freezeClone(request),
|
|
79
|
+
authorization: Object.freeze({
|
|
80
|
+
...freezeClone(authorizationData),
|
|
81
|
+
// Mutation capabilities are opaque identity tokens held in an
|
|
82
|
+
// authority WeakMap. Cloning them turns a valid capability into a
|
|
83
|
+
// forgery, so preserve the already-frozen authority object itself.
|
|
84
|
+
capability,
|
|
85
|
+
}),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function canonical(value) {
|
|
90
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
91
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
92
|
+
return `{${Object.keys(value)
|
|
93
|
+
.sort()
|
|
94
|
+
.map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
|
|
95
|
+
.join(",")}}`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function domainDigest(domain, value) {
|
|
99
|
+
return `sha256:${createHash("sha256")
|
|
100
|
+
.update(domain)
|
|
101
|
+
.update("\0")
|
|
102
|
+
.update(canonical(value))
|
|
103
|
+
.digest("hex")}`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function dataRecord(value, label) {
|
|
107
|
+
if (
|
|
108
|
+
!value ||
|
|
109
|
+
typeof value !== "object" ||
|
|
110
|
+
Array.isArray(value) ||
|
|
111
|
+
utilTypes.isProxy(value) ||
|
|
112
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(value))
|
|
113
|
+
)
|
|
114
|
+
throw new TypeError(`${label} must be a plain non-proxy object`);
|
|
115
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
116
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
117
|
+
if (
|
|
118
|
+
typeof key !== "string" ||
|
|
119
|
+
!descriptor ||
|
|
120
|
+
!("value" in descriptor) ||
|
|
121
|
+
!descriptor.enumerable
|
|
122
|
+
)
|
|
123
|
+
throw new TypeError(`${label} must contain only enumerable data fields`);
|
|
124
|
+
}
|
|
125
|
+
return value;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function stageReceipt(context, outputDigest, usage) {
|
|
129
|
+
return createEvolutionTrainStageReceipt({
|
|
130
|
+
planDigest: context.plan.planDigest,
|
|
131
|
+
stage: context.stage,
|
|
132
|
+
operationKey: context.operationKey,
|
|
133
|
+
inputDigest: context.inputDigest,
|
|
134
|
+
outputDigest,
|
|
135
|
+
accepted: true,
|
|
136
|
+
durable: true,
|
|
137
|
+
usage,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function assertStage(context, expected) {
|
|
142
|
+
if (context?.stage !== expected)
|
|
143
|
+
throw new Error(`${expected} adapter received a different stage`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function createEvolutionWikiMaintainStage({
|
|
147
|
+
maintainer,
|
|
148
|
+
request,
|
|
149
|
+
usage,
|
|
150
|
+
} = {}) {
|
|
151
|
+
const maintain = capture(maintainer, "maintain", "maintainer");
|
|
152
|
+
const boundRequest = freezeClone(request);
|
|
153
|
+
const boundUsage = freezeClone(usage);
|
|
154
|
+
return Object.freeze(async (context) => {
|
|
155
|
+
assertStage(context, STAGES.WIKI);
|
|
156
|
+
const result = await maintain(boundRequest);
|
|
157
|
+
if (result?.stateDigest !== context.plan.wikiRevisionDigest)
|
|
158
|
+
throw new Error(
|
|
159
|
+
"wiki-maintain output does not match the EvolutionPlan Wiki digest",
|
|
160
|
+
);
|
|
161
|
+
return stageReceipt(context, result.stateDigest, boundUsage);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function createEvolutionProposalStage({
|
|
166
|
+
proposer,
|
|
167
|
+
proposalLedger,
|
|
168
|
+
effectiveAt,
|
|
169
|
+
usage,
|
|
170
|
+
} = {}) {
|
|
171
|
+
const draft = capture(proposer, "draft", "proposer");
|
|
172
|
+
const load = capture(proposalLedger, "load", "proposalLedger");
|
|
173
|
+
const commit = capture(proposalLedger, "commit", "proposalLedger");
|
|
174
|
+
const timestamp = new Date(effectiveAt).toISOString();
|
|
175
|
+
const boundUsage = freezeClone(usage);
|
|
176
|
+
return Object.freeze(async (context) => {
|
|
177
|
+
assertStage(context, STAGES.PROPOSE);
|
|
178
|
+
let stored = load(context.plan.planDigest);
|
|
179
|
+
if (stored) {
|
|
180
|
+
if (
|
|
181
|
+
stored.operationKey !== context.operationKey ||
|
|
182
|
+
stored.inputDigest !== context.inputDigest
|
|
183
|
+
)
|
|
184
|
+
throw new Error("stored proposal is bound to a different stage input");
|
|
185
|
+
} else {
|
|
186
|
+
const drafted = await draft();
|
|
187
|
+
if (drafted?.status !== WIKI_PROPOSAL_STATUS.PROPOSAL)
|
|
188
|
+
throw new Error(`proposer abstained with status ${drafted?.status}`);
|
|
189
|
+
commit({
|
|
190
|
+
planDigest: context.plan.planDigest,
|
|
191
|
+
operationKey: context.operationKey,
|
|
192
|
+
inputDigest: context.inputDigest,
|
|
193
|
+
drafted,
|
|
194
|
+
effectiveAt: timestamp,
|
|
195
|
+
});
|
|
196
|
+
stored = load(context.plan.planDigest);
|
|
197
|
+
}
|
|
198
|
+
if (!stored)
|
|
199
|
+
throw new Error("proposal was not durably recoverable after commit");
|
|
200
|
+
return stageReceipt(context, stored.outputDigest, boundUsage);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
export function createEvolutionCandidateStage({
|
|
205
|
+
proposer,
|
|
206
|
+
proposalLedger,
|
|
207
|
+
usage,
|
|
208
|
+
} = {}) {
|
|
209
|
+
const createCandidate = capture(
|
|
210
|
+
proposer,
|
|
211
|
+
"createCandidateFromDraft",
|
|
212
|
+
"proposer",
|
|
213
|
+
);
|
|
214
|
+
const load = capture(proposalLedger, "load", "proposalLedger");
|
|
215
|
+
const boundUsage = freezeClone(usage);
|
|
216
|
+
return Object.freeze(async (context) => {
|
|
217
|
+
assertStage(context, STAGES.CANDIDATE);
|
|
218
|
+
const stored = load(context.plan.planDigest);
|
|
219
|
+
if (!stored || stored.outputDigest !== context.inputDigest)
|
|
220
|
+
throw new Error(
|
|
221
|
+
"candidate stage could not resolve its exact proposal input",
|
|
222
|
+
);
|
|
223
|
+
const created = await createCandidate(stored.drafted);
|
|
224
|
+
if (
|
|
225
|
+
created?.candidateId !== context.plan.candidateId ||
|
|
226
|
+
created?.contentDigest !== context.plan.candidateDigest
|
|
227
|
+
)
|
|
228
|
+
throw new Error(
|
|
229
|
+
"candidate output does not match the EvolutionPlan candidate digest",
|
|
230
|
+
);
|
|
231
|
+
return stageReceipt(context, created.contentDigest, boundUsage);
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export function createEvolutionEvalStage({
|
|
236
|
+
aggregator,
|
|
237
|
+
receiptVerifier,
|
|
238
|
+
planRef,
|
|
239
|
+
expectedReceipt,
|
|
240
|
+
durability,
|
|
241
|
+
outputLedger,
|
|
242
|
+
usage,
|
|
243
|
+
} = {}) {
|
|
244
|
+
const load = capture(outputLedger, "load", "outputLedger");
|
|
245
|
+
const commit = capture(outputLedger, "commit", "outputLedger");
|
|
246
|
+
const retain = capture(durability, "retain", "durability");
|
|
247
|
+
const boundPlanRef = freezeClone(planRef);
|
|
248
|
+
const boundExpected = freezeClone(expectedReceipt);
|
|
249
|
+
const boundUsage = freezeClone(usage);
|
|
250
|
+
return Object.freeze(async (context) => {
|
|
251
|
+
assertStage(context, STAGES.EVAL);
|
|
252
|
+
let stored = load({
|
|
253
|
+
planDigest: context.plan.planDigest,
|
|
254
|
+
stage: STAGES.EVAL,
|
|
255
|
+
});
|
|
256
|
+
let receipt;
|
|
257
|
+
if (stored) {
|
|
258
|
+
if (
|
|
259
|
+
stored.operationKey !== context.operationKey ||
|
|
260
|
+
stored.inputDigest !== context.inputDigest
|
|
261
|
+
)
|
|
262
|
+
throw new Error(
|
|
263
|
+
"stored evaluation is bound to a different stage input",
|
|
264
|
+
);
|
|
265
|
+
receipt = stored.value;
|
|
266
|
+
} else {
|
|
267
|
+
receipt = await evaluateSkillTargetMatrix(aggregator, boundPlanRef);
|
|
268
|
+
}
|
|
269
|
+
assertMatrixEvalPlanBinding(
|
|
270
|
+
receipt,
|
|
271
|
+
boundExpected,
|
|
272
|
+
context.plan,
|
|
273
|
+
boundPlanRef,
|
|
274
|
+
);
|
|
275
|
+
const verified = await verifySkillTargetMatrixEvalReceipt(
|
|
276
|
+
receiptVerifier,
|
|
277
|
+
receipt,
|
|
278
|
+
boundExpected,
|
|
279
|
+
);
|
|
280
|
+
if (verified.decision !== "accepted")
|
|
281
|
+
throw new Error(`matrix evaluation did not accept: ${verified.decision}`);
|
|
282
|
+
const retained = await retain(verified);
|
|
283
|
+
if (
|
|
284
|
+
retained?.durable !== true ||
|
|
285
|
+
retained?.receiptDigest !== verified.receiptDigest
|
|
286
|
+
)
|
|
287
|
+
throw new Error("matrix evaluation durability was not confirmed");
|
|
288
|
+
if (!stored) {
|
|
289
|
+
commit({
|
|
290
|
+
planDigest: context.plan.planDigest,
|
|
291
|
+
stage: STAGES.EVAL,
|
|
292
|
+
operationKey: context.operationKey,
|
|
293
|
+
inputDigest: context.inputDigest,
|
|
294
|
+
outputDigest: verified.receiptDigest,
|
|
295
|
+
value: verified,
|
|
296
|
+
effectiveAt: verified.issuedAt,
|
|
297
|
+
});
|
|
298
|
+
stored = load({
|
|
299
|
+
planDigest: context.plan.planDigest,
|
|
300
|
+
stage: STAGES.EVAL,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (
|
|
304
|
+
!stored ||
|
|
305
|
+
stored.outputDigest !== verified.receiptDigest ||
|
|
306
|
+
stored.valueDigest === undefined
|
|
307
|
+
)
|
|
308
|
+
throw new Error("evaluation receipt was not durably recoverable");
|
|
309
|
+
return stageReceipt(context, verified.receiptDigest, boundUsage);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
export function createEvolutionReviewStage({
|
|
314
|
+
reviewLedger,
|
|
315
|
+
packetInput,
|
|
316
|
+
outputLedger,
|
|
317
|
+
usage,
|
|
318
|
+
} = {}) {
|
|
319
|
+
const submitPacket = capture(reviewLedger, "submitPacket", "reviewLedger");
|
|
320
|
+
const listReviews = capture(reviewLedger, "listReviews", "reviewLedger");
|
|
321
|
+
const load = capture(outputLedger, "load", "outputLedger");
|
|
322
|
+
const commit = capture(outputLedger, "commit", "outputLedger");
|
|
323
|
+
const boundPacketInput = freezeClone(packetInput);
|
|
324
|
+
const boundUsage = freezeClone(usage);
|
|
325
|
+
return Object.freeze(async (context) => {
|
|
326
|
+
assertStage(context, STAGES.REVIEW);
|
|
327
|
+
const packet = buildSkillPromotionReviewPacket(boundPacketInput);
|
|
328
|
+
if (
|
|
329
|
+
context.inputDigest !== packet.evaluation.matrixReceiptDigest ||
|
|
330
|
+
packet.tenantId !== context.plan.tenantId ||
|
|
331
|
+
packet.skillName !== context.plan.skillId ||
|
|
332
|
+
packet.candidateId !== context.plan.candidateId ||
|
|
333
|
+
packet.candidateContentDigest !== context.plan.candidateDigest ||
|
|
334
|
+
packet.baselineReleaseDigest !== context.plan.baselineReleaseDigest ||
|
|
335
|
+
packet.expectedActiveRevision !== context.plan.baselineRevision
|
|
336
|
+
)
|
|
337
|
+
throw new Error("review packet is not bound to the EvolutionPlan");
|
|
338
|
+
const stored = load({
|
|
339
|
+
planDigest: context.plan.planDigest,
|
|
340
|
+
stage: STAGES.REVIEW,
|
|
341
|
+
});
|
|
342
|
+
if (
|
|
343
|
+
stored &&
|
|
344
|
+
(stored.operationKey !== context.operationKey ||
|
|
345
|
+
stored.inputDigest !== context.inputDigest)
|
|
346
|
+
)
|
|
347
|
+
throw new Error("stored review is bound to a different stage input");
|
|
348
|
+
await submitPacket(packet);
|
|
349
|
+
const reviews = await listReviews();
|
|
350
|
+
const matches = reviews.filter(
|
|
351
|
+
(review) => review.packet?.packetDigest === packet.packetDigest,
|
|
352
|
+
);
|
|
353
|
+
if (matches.length !== 1)
|
|
354
|
+
throw new Error("review packet is missing or ambiguous after submission");
|
|
355
|
+
const review = matches[0];
|
|
356
|
+
if (review.status === "pending") {
|
|
357
|
+
const error = new Error("human promotion review is pending");
|
|
358
|
+
error.code = "EVOLUTION_RELEASE_TRAIN_REVIEW_PENDING";
|
|
359
|
+
throw error;
|
|
360
|
+
}
|
|
361
|
+
if (review.status !== "approved" || !review.decision?.receiptDigest)
|
|
362
|
+
throw new Error(
|
|
363
|
+
`human promotion review did not approve: ${review.status}`,
|
|
364
|
+
);
|
|
365
|
+
if (!stored) {
|
|
366
|
+
commit({
|
|
367
|
+
planDigest: context.plan.planDigest,
|
|
368
|
+
stage: STAGES.REVIEW,
|
|
369
|
+
operationKey: context.operationKey,
|
|
370
|
+
inputDigest: context.inputDigest,
|
|
371
|
+
outputDigest: review.decision.receiptDigest,
|
|
372
|
+
value: { packet: review.packet, decision: review.decision },
|
|
373
|
+
effectiveAt: review.decision.decidedAt,
|
|
374
|
+
});
|
|
375
|
+
} else if (stored.outputDigest !== review.decision.receiptDigest) {
|
|
376
|
+
throw new Error(
|
|
377
|
+
"stored review decision differs from the durable authority",
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
const recovered = load({
|
|
381
|
+
planDigest: context.plan.planDigest,
|
|
382
|
+
stage: STAGES.REVIEW,
|
|
383
|
+
});
|
|
384
|
+
if (!recovered || recovered.outputDigest !== review.decision.receiptDigest)
|
|
385
|
+
throw new Error("review decision was not durably recoverable");
|
|
386
|
+
return stageReceipt(context, review.decision.receiptDigest, boundUsage);
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export function createEvolutionPilotStage({
|
|
391
|
+
pilot,
|
|
392
|
+
startRequest,
|
|
393
|
+
approvalInput,
|
|
394
|
+
nextAdvanceInput,
|
|
395
|
+
effectiveAt,
|
|
396
|
+
outputLedger,
|
|
397
|
+
usage,
|
|
398
|
+
} = {}) {
|
|
399
|
+
const start = capture(pilot, "start", "pilot");
|
|
400
|
+
const approveShadow = capture(pilot, "approveShadow", "pilot");
|
|
401
|
+
const advance = capture(pilot, "advance", "pilot");
|
|
402
|
+
const reconcile = capture(pilot, "reconcilePendingTransition", "pilot");
|
|
403
|
+
const snapshot = capture(pilot, "snapshot", "pilot");
|
|
404
|
+
const view = capture(pilot, "view", "pilot");
|
|
405
|
+
if (typeof nextAdvanceInput !== "function")
|
|
406
|
+
throw new TypeError("nextAdvanceInput() is required");
|
|
407
|
+
const load = capture(outputLedger, "load", "outputLedger");
|
|
408
|
+
const commit = capture(outputLedger, "commit", "outputLedger");
|
|
409
|
+
const boundStart = freezeClone(startRequest);
|
|
410
|
+
const boundApproval = freezeClone(approvalInput);
|
|
411
|
+
const timestamp = new Date(effectiveAt).toISOString();
|
|
412
|
+
const boundUsage = freezeClone(usage);
|
|
413
|
+
return Object.freeze(async (context) => {
|
|
414
|
+
assertStage(context, STAGES.PILOT);
|
|
415
|
+
const review = load({
|
|
416
|
+
planDigest: context.plan.planDigest,
|
|
417
|
+
stage: STAGES.REVIEW,
|
|
418
|
+
});
|
|
419
|
+
if (
|
|
420
|
+
!review ||
|
|
421
|
+
review.outputDigest !== context.inputDigest ||
|
|
422
|
+
review.value?.decision?.receiptDigest !== context.inputDigest ||
|
|
423
|
+
pilot.descriptor?.tenantId !== context.plan.tenantId ||
|
|
424
|
+
pilot.descriptor?.skillName !== context.plan.skillId ||
|
|
425
|
+
pilot.descriptor?.candidateDigest !== context.plan.candidateDigest ||
|
|
426
|
+
pilot.descriptor?.baselineDigest !==
|
|
427
|
+
(context.plan.baselineReleaseDigest ??
|
|
428
|
+
context.plan.baselineContentDigest) ||
|
|
429
|
+
pilot.descriptor?.evalReceiptDigest !==
|
|
430
|
+
review.value.packet?.evaluation?.matrixReceiptDigest ||
|
|
431
|
+
pilot.descriptor?.reviewPacketDigest !== review.value.packet?.packetDigest
|
|
432
|
+
)
|
|
433
|
+
throw new Error(
|
|
434
|
+
"production Pilot is not bound to the EvolutionPlan review",
|
|
435
|
+
);
|
|
436
|
+
let current = view();
|
|
437
|
+
if (
|
|
438
|
+
current.progressiveCanary?.planDigest !== context.plan.rolloutPolicyDigest
|
|
439
|
+
)
|
|
440
|
+
throw new Error(
|
|
441
|
+
"Pilot progressive rollout differs from the EvolutionPlan",
|
|
442
|
+
);
|
|
443
|
+
if (current.reconciliationRequired) current = await reconcile();
|
|
444
|
+
if (snapshot().state.activeStateDigest === null)
|
|
445
|
+
current = await start(boundStart);
|
|
446
|
+
if (current.stage === "candidate")
|
|
447
|
+
current = await approveShadow(boundApproval);
|
|
448
|
+
for (let step = 0; current.stage !== "active" && step < 64; step += 1) {
|
|
449
|
+
if (current.stage === "rolled-back")
|
|
450
|
+
throw new Error("production Pilot rolled back the candidate");
|
|
451
|
+
if (current.reconciliationRequired) {
|
|
452
|
+
current = await reconcile();
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
const advanceInput = await nextAdvanceInput(freezeClone(current));
|
|
456
|
+
if (advanceInput === null) {
|
|
457
|
+
const error = new Error("production Pilot observation gate is pending");
|
|
458
|
+
error.code = "EVOLUTION_RELEASE_TRAIN_PILOT_PENDING";
|
|
459
|
+
throw error;
|
|
460
|
+
}
|
|
461
|
+
current = await advance(freezeClone(advanceInput));
|
|
462
|
+
}
|
|
463
|
+
if (
|
|
464
|
+
current.stage !== "active" ||
|
|
465
|
+
current.progressiveCanary?.stepId !== null ||
|
|
466
|
+
typeof current.lastTransitionReceiptDigest !== "string"
|
|
467
|
+
)
|
|
468
|
+
throw new Error("production Pilot did not reach stable active state");
|
|
469
|
+
const stored = load({
|
|
470
|
+
planDigest: context.plan.planDigest,
|
|
471
|
+
stage: STAGES.PILOT,
|
|
472
|
+
});
|
|
473
|
+
if (!stored) {
|
|
474
|
+
commit({
|
|
475
|
+
planDigest: context.plan.planDigest,
|
|
476
|
+
stage: STAGES.PILOT,
|
|
477
|
+
operationKey: context.operationKey,
|
|
478
|
+
inputDigest: context.inputDigest,
|
|
479
|
+
outputDigest: current.lastTransitionReceiptDigest,
|
|
480
|
+
value: current,
|
|
481
|
+
effectiveAt: timestamp,
|
|
482
|
+
});
|
|
483
|
+
} else if (
|
|
484
|
+
stored.operationKey !== context.operationKey ||
|
|
485
|
+
stored.inputDigest !== context.inputDigest ||
|
|
486
|
+
stored.outputDigest !== current.lastTransitionReceiptDigest
|
|
487
|
+
) {
|
|
488
|
+
throw new Error(
|
|
489
|
+
"stored Pilot output differs from the durable controller",
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
const recovered = load({
|
|
493
|
+
planDigest: context.plan.planDigest,
|
|
494
|
+
stage: STAGES.PILOT,
|
|
495
|
+
});
|
|
496
|
+
if (!recovered)
|
|
497
|
+
throw new Error("production Pilot output was not durably recoverable");
|
|
498
|
+
return stageReceipt(context, recovered.outputDigest, boundUsage);
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
export function createEvolutionPromotionStage({
|
|
503
|
+
controller,
|
|
504
|
+
releaseRegistry,
|
|
505
|
+
promotionInput,
|
|
506
|
+
outputLedger,
|
|
507
|
+
effectiveAt,
|
|
508
|
+
usage,
|
|
509
|
+
} = {}) {
|
|
510
|
+
const promote = capture(controller, "promoteEvaluated", "controller");
|
|
511
|
+
const readState = capture(releaseRegistry, "readState", "releaseRegistry");
|
|
512
|
+
const readRelease = capture(
|
|
513
|
+
releaseRegistry,
|
|
514
|
+
"readRelease",
|
|
515
|
+
"releaseRegistry",
|
|
516
|
+
);
|
|
517
|
+
const load = capture(outputLedger, "load", "outputLedger");
|
|
518
|
+
const commit = capture(outputLedger, "commit", "outputLedger");
|
|
519
|
+
const boundInput = bindPromotionInput(promotionInput);
|
|
520
|
+
const timestamp = new Date(effectiveAt).toISOString();
|
|
521
|
+
const boundUsage = freezeClone(usage);
|
|
522
|
+
const active = (plan) => {
|
|
523
|
+
const state = readState(plan.skillId);
|
|
524
|
+
if (state?.activeReleaseDigest === null) return null;
|
|
525
|
+
const release = readRelease(state.activeReleaseDigest);
|
|
526
|
+
if (
|
|
527
|
+
state?.tenantId !== plan.tenantId ||
|
|
528
|
+
state.skillName !== plan.skillId ||
|
|
529
|
+
release?.tenantId !== plan.tenantId ||
|
|
530
|
+
release.skillName !== plan.skillId
|
|
531
|
+
)
|
|
532
|
+
throw new Error("active Skill release belongs to another plan subject");
|
|
533
|
+
return { state, release };
|
|
534
|
+
};
|
|
535
|
+
return Object.freeze(async (context) => {
|
|
536
|
+
assertStage(context, STAGES.PROMOTION);
|
|
537
|
+
const pilot = load({
|
|
538
|
+
planDigest: context.plan.planDigest,
|
|
539
|
+
stage: STAGES.PILOT,
|
|
540
|
+
});
|
|
541
|
+
const evaluation = load({
|
|
542
|
+
planDigest: context.plan.planDigest,
|
|
543
|
+
stage: STAGES.EVAL,
|
|
544
|
+
});
|
|
545
|
+
const review = load({
|
|
546
|
+
planDigest: context.plan.planDigest,
|
|
547
|
+
stage: STAGES.REVIEW,
|
|
548
|
+
});
|
|
549
|
+
if (
|
|
550
|
+
!pilot ||
|
|
551
|
+
pilot.outputDigest !== context.inputDigest ||
|
|
552
|
+
pilot.value?.stage !== "active" ||
|
|
553
|
+
pilot.value?.progressiveCanary?.stepId !== null ||
|
|
554
|
+
boundInput.candidateId !== context.plan.candidateId ||
|
|
555
|
+
evaluation?.value?.receiptDigest !== evaluation.outputDigest ||
|
|
556
|
+
review?.value?.decision?.receiptDigest !== review.outputDigest
|
|
557
|
+
)
|
|
558
|
+
throw new Error(
|
|
559
|
+
"promotion inputs are not a stable authorized release train",
|
|
560
|
+
);
|
|
561
|
+
let current = active(context.plan);
|
|
562
|
+
let result = null;
|
|
563
|
+
if (
|
|
564
|
+
current === null ||
|
|
565
|
+
current.release.contentDigest !== context.plan.candidateDigest
|
|
566
|
+
) {
|
|
567
|
+
result = await promote(boundInput);
|
|
568
|
+
current = active(context.plan);
|
|
569
|
+
}
|
|
570
|
+
if (
|
|
571
|
+
!current ||
|
|
572
|
+
current.release.candidateId !== context.plan.candidateId ||
|
|
573
|
+
current.release.contentDigest !== context.plan.candidateDigest ||
|
|
574
|
+
current.state.revision !== context.plan.baselineRevision + 1 ||
|
|
575
|
+
(result &&
|
|
576
|
+
(result.release?.releaseDigest !== current.release.releaseDigest ||
|
|
577
|
+
result.matrixBinding?.matrixReceiptDigest !==
|
|
578
|
+
evaluation.outputDigest ||
|
|
579
|
+
result.reviewBinding?.reviewReceiptDigest !== review.outputDigest))
|
|
580
|
+
)
|
|
581
|
+
throw new Error(
|
|
582
|
+
"evaluated promotion did not commit the exact planned release",
|
|
583
|
+
);
|
|
584
|
+
const stored = load({
|
|
585
|
+
planDigest: context.plan.planDigest,
|
|
586
|
+
stage: STAGES.PROMOTION,
|
|
587
|
+
});
|
|
588
|
+
if (!stored) {
|
|
589
|
+
commit({
|
|
590
|
+
planDigest: context.plan.planDigest,
|
|
591
|
+
stage: STAGES.PROMOTION,
|
|
592
|
+
operationKey: context.operationKey,
|
|
593
|
+
inputDigest: context.inputDigest,
|
|
594
|
+
outputDigest: current.release.releaseDigest,
|
|
595
|
+
value: { state: current.state, release: current.release },
|
|
596
|
+
effectiveAt: timestamp,
|
|
597
|
+
});
|
|
598
|
+
} else if (
|
|
599
|
+
stored.operationKey !== context.operationKey ||
|
|
600
|
+
stored.inputDigest !== context.inputDigest ||
|
|
601
|
+
stored.outputDigest !== current.release.releaseDigest
|
|
602
|
+
) {
|
|
603
|
+
throw new Error(
|
|
604
|
+
"stored promotion differs from the active ReleaseRegistry",
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
const recovered = load({
|
|
608
|
+
planDigest: context.plan.planDigest,
|
|
609
|
+
stage: STAGES.PROMOTION,
|
|
610
|
+
});
|
|
611
|
+
if (!recovered)
|
|
612
|
+
throw new Error("promotion output was not durably recoverable");
|
|
613
|
+
return stageReceipt(context, recovered.outputDigest, boundUsage);
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export function createEvolutionWikiImpactStage({
|
|
618
|
+
reconciler,
|
|
619
|
+
outputLedger,
|
|
620
|
+
effectiveAt,
|
|
621
|
+
limit = 64,
|
|
622
|
+
usage,
|
|
623
|
+
} = {}) {
|
|
624
|
+
const list = capture(reconciler?.source, "list", "reconciler.source");
|
|
625
|
+
const reconcile = capture(reconciler, "reconcile", "reconciler");
|
|
626
|
+
const load = capture(outputLedger, "load", "outputLedger");
|
|
627
|
+
const commit = capture(outputLedger, "commit", "outputLedger");
|
|
628
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 256)
|
|
629
|
+
throw new TypeError("Wiki reconciliation limit must be between 1 and 256");
|
|
630
|
+
const timestamp = new Date(effectiveAt).toISOString();
|
|
631
|
+
const boundUsage = freezeClone(usage);
|
|
632
|
+
return Object.freeze(async (context) => {
|
|
633
|
+
assertStage(context, STAGES.WIKI_IMPACT);
|
|
634
|
+
const promotion = load({
|
|
635
|
+
planDigest: context.plan.planDigest,
|
|
636
|
+
stage: STAGES.PROMOTION,
|
|
637
|
+
});
|
|
638
|
+
if (
|
|
639
|
+
!promotion ||
|
|
640
|
+
promotion.outputDigest !== context.inputDigest ||
|
|
641
|
+
promotion.value?.release?.releaseDigest !== context.inputDigest
|
|
642
|
+
)
|
|
643
|
+
throw new Error("Wiki impact is not bound to the promoted release");
|
|
644
|
+
let sourceCursor = 0;
|
|
645
|
+
let target = null;
|
|
646
|
+
for (let page = 0; page < 10_000; page += 1) {
|
|
647
|
+
const batch = await list({ afterSequence: sourceCursor, limit });
|
|
648
|
+
if (!Array.isArray(batch))
|
|
649
|
+
throw new Error("Wiki reconciliation source returned an invalid page");
|
|
650
|
+
target ??= batch.find(
|
|
651
|
+
(transition) =>
|
|
652
|
+
transition.tenantId === context.plan.tenantId &&
|
|
653
|
+
transition.skillName === context.plan.skillId &&
|
|
654
|
+
transition.candidateId === context.plan.candidateId &&
|
|
655
|
+
transition.activeReleaseDigest === promotion.outputDigest,
|
|
656
|
+
);
|
|
657
|
+
if (batch.length === 0 || batch.length < limit) break;
|
|
658
|
+
sourceCursor = batch.at(-1).sequence;
|
|
659
|
+
}
|
|
660
|
+
if (!target)
|
|
661
|
+
throw new Error(
|
|
662
|
+
"promoted release is absent from the Wiki reconciliation source",
|
|
663
|
+
);
|
|
664
|
+
let settled;
|
|
665
|
+
for (let batch = 0; batch < 10_000; batch += 1) {
|
|
666
|
+
settled = await reconcile({ limit });
|
|
667
|
+
if (
|
|
668
|
+
!Number.isSafeInteger(settled?.processed) ||
|
|
669
|
+
!Number.isSafeInteger(settled?.cursor)
|
|
670
|
+
)
|
|
671
|
+
throw new Error("Wiki reconciler returned an invalid settlement");
|
|
672
|
+
if (settled.processed < limit) break;
|
|
673
|
+
}
|
|
674
|
+
if (!settled || settled.cursor < target.sequence)
|
|
675
|
+
throw new Error("promoted release did not reach the Wiki checkpoint");
|
|
676
|
+
const stored = load({
|
|
677
|
+
planDigest: context.plan.planDigest,
|
|
678
|
+
stage: STAGES.WIKI_IMPACT,
|
|
679
|
+
});
|
|
680
|
+
if (!stored) {
|
|
681
|
+
const value = {
|
|
682
|
+
releaseDigest: promotion.outputDigest,
|
|
683
|
+
transitionDigest: target.transitionDigest,
|
|
684
|
+
transitionSequence: target.sequence,
|
|
685
|
+
checkpointCursor: settled.cursor,
|
|
686
|
+
};
|
|
687
|
+
commit({
|
|
688
|
+
planDigest: context.plan.planDigest,
|
|
689
|
+
stage: STAGES.WIKI_IMPACT,
|
|
690
|
+
operationKey: context.operationKey,
|
|
691
|
+
inputDigest: context.inputDigest,
|
|
692
|
+
outputDigest: domainDigest(
|
|
693
|
+
"chainlesschain.evolution-release-train-wiki-impact/v1",
|
|
694
|
+
value,
|
|
695
|
+
),
|
|
696
|
+
value,
|
|
697
|
+
effectiveAt: timestamp,
|
|
698
|
+
});
|
|
699
|
+
} else if (
|
|
700
|
+
stored.operationKey !== context.operationKey ||
|
|
701
|
+
stored.inputDigest !== context.inputDigest ||
|
|
702
|
+
stored.value?.transitionDigest !== target.transitionDigest ||
|
|
703
|
+
stored.value?.checkpointCursor > settled.cursor
|
|
704
|
+
) {
|
|
705
|
+
throw new Error(
|
|
706
|
+
"stored Wiki impact differs from reconciliation authority",
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
const recovered = load({
|
|
710
|
+
planDigest: context.plan.planDigest,
|
|
711
|
+
stage: STAGES.WIKI_IMPACT,
|
|
712
|
+
});
|
|
713
|
+
if (!recovered)
|
|
714
|
+
throw new Error("Wiki impact output was not durably recoverable");
|
|
715
|
+
return stageReceipt(context, recovered.outputDigest, boundUsage);
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
export function createEvolutionReleaseTrainDomainStages({
|
|
720
|
+
domain,
|
|
721
|
+
proposalLedger,
|
|
722
|
+
outputLedger,
|
|
723
|
+
} = {}) {
|
|
724
|
+
const expected = [
|
|
725
|
+
"wiki-maintain",
|
|
726
|
+
"propose",
|
|
727
|
+
"candidate",
|
|
728
|
+
"eval",
|
|
729
|
+
"review",
|
|
730
|
+
"pilot",
|
|
731
|
+
"promotion",
|
|
732
|
+
"wiki-impact",
|
|
733
|
+
];
|
|
734
|
+
dataRecord(domain, "release train domain");
|
|
735
|
+
if (canonical(Object.keys(domain).sort()) !== canonical([...expected].sort()))
|
|
736
|
+
throw new TypeError("release train domain must configure all eight stages");
|
|
737
|
+
for (const name of expected) dataRecord(domain[name], `domain.${name}`);
|
|
738
|
+
return Object.freeze({
|
|
739
|
+
"wiki-maintain": createEvolutionWikiMaintainStage(domain["wiki-maintain"]),
|
|
740
|
+
propose: createEvolutionProposalStage({
|
|
741
|
+
...domain.propose,
|
|
742
|
+
proposalLedger,
|
|
743
|
+
}),
|
|
744
|
+
candidate: createEvolutionCandidateStage({
|
|
745
|
+
...domain.candidate,
|
|
746
|
+
proposalLedger,
|
|
747
|
+
}),
|
|
748
|
+
eval: createEvolutionEvalStage({
|
|
749
|
+
...domain.eval,
|
|
750
|
+
outputLedger,
|
|
751
|
+
}),
|
|
752
|
+
review: createEvolutionReviewStage({
|
|
753
|
+
...domain.review,
|
|
754
|
+
outputLedger,
|
|
755
|
+
}),
|
|
756
|
+
pilot: createEvolutionPilotStage({
|
|
757
|
+
...domain.pilot,
|
|
758
|
+
outputLedger,
|
|
759
|
+
}),
|
|
760
|
+
promotion: createEvolutionPromotionStage({
|
|
761
|
+
...domain.promotion,
|
|
762
|
+
outputLedger,
|
|
763
|
+
}),
|
|
764
|
+
"wiki-impact": createEvolutionWikiImpactStage({
|
|
765
|
+
...domain["wiki-impact"],
|
|
766
|
+
outputLedger,
|
|
767
|
+
}),
|
|
768
|
+
});
|
|
769
|
+
}
|