chainlesschain 0.166.44 → 0.166.45
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/package.json +3 -3
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-HiHMDVK3.js → AIOps-CrMhYNeH.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-H2RKuS8V.js → ActionButton-DLY5blZ3.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-CBPFBB61.js → Analytics-C0NhKQB0.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-Da-3Laze.js → AppLayout-DLyepgMq.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-DiRQ9yzD.js → Artifacts-Depk01Sa.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-C9LtWEBh.js → Audit-jKe6NQ3J.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-4rpi7fVg.js → BackgroundAgents-CG4GKT9s.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-B8VQmHys.js → Backup-DYWCkzwM.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-iCVpF2DK.js → BaseInput-xm5vodmJ.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-BrQaXBwC.js → Chat-B20_PNd3.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-HIyU-9c0.js → ChatBubbleRenderer-D4d-eh0F.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CsV__0_R.js → Checkbox-CfgwkV_r.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BvFeCIAE.js → Codegen-DbnoWI44.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CagxV1O8.js → Col-CfzzhgGw.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DAWr4ahG.js → Community-BU7mGM8p.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-Ba49Tdc2.js → Compact-DpYim0an.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-Brk-MSO4.js → Compliance-BNJcO6ra.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-DeKH1v0o.js → Cowork-CecZ-pWj.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-AHB-T-VL.js → Cron-BG_C1fe3.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Zbcrtimh.js → Crosschain-BAeILQLL.js} +1 -1
- package/src/assets/web-panel/assets/{DID-ByFa1MWG.js → DID-CYqOEkXi.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-9jKovyuH.js → Dashboard-BYU8wmL1.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DY8TaXi5.js → Dropdown-DYlJeTTa.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-rcaSveQ8.js → EmailListRenderer-C0M6py3K.js} +1 -1
- package/src/assets/web-panel/assets/EvolutionSettings-_QnjPFZJ.js +1 -0
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-5ao8smvA.js → FamilyGuardDashboard-Du90iDch.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-RTpNXXHT.js → Federation-DkFp_hzB.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DWZvRMWv.js → FormItemContext-BGgtGTfG.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-CWi8SGvx.js → GenericCardRenderer-BIDsSCei.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CCLgDIqs.js → Git--d3Te93J.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DUuyKrQl.js → Governance-CZwD0vmO.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-RkFcM2A0.js → Inference-DiDcSFEW.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-C-QTauZr.js → KnowledgeGraph-Bi0hSfzg.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-B-7Dz5Ui.js → Logs-C8NHSc0K.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-CgiHBe0A.js → MarkdownRenderer-DfDuADqF.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CK1kSFDt.js → Marketplace-D6kD0bNf.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BcaVwoY6.js → McpTools-mTSamCr5.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-QEI4xRwF.js → Memory-YQBXfLjU.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BqD-R0Ek.js → MobileBridge-D2awuupp.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-CwFoXf1M.js → MobileProjects-Bl7lZc_-.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CTZ6qICG.js → Mtc-CBqjLK2Q.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-Cn7y2BzO.js → MtcAudit-C4poRInZ.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-BCjsdGiN.js → Multisig-C_J0zXYZ.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CupTVNtA.js → NLProgramming-Ci43sWOU.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-C8kO3mGt.js → Notes-DN7A-GFZ.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-Cn-MJ8sQ.js → NotificationSettings-D5jNm71V.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-C9UsPOG8.js +1 -0
- package/src/assets/web-panel/assets/{Organization-G_RjOL7M.js → Organization-BapYMJrP.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BvX644ya.js → Overflow-BwxwjhFw.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-yWmLgYgQ.js → P2P-TObXXOu3.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-UwJvMbFO.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-DtU8fhcZ.js → Permissions-Damnxv-O.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-B17Vyk-x.js → PersonalDataHub-d_7jlBb-.js} +5 -5
- package/src/assets/web-panel/assets/{Pipeline-BZUsTyhP.js → Pipeline-DA87VjLw.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-BswdhlPL.js → Privacy-DzO_UvWn.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-sJxSlY0C.js → ProjectInit-CwqECDhs.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BnbpdOke.js → ProjectSettings-CT5YdIl6.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DUjauf-6.js → Projects-D3KdZPCv.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-DhF5I-UR.js → Providers-BjBIS8kk.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-B3PeCAGo.js → QrScannerModal-mMFqiKkI.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-Cpaxrabg.js → QuickAsk-BwGi9ZU1.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DqXFF66-.js → Recommend-BY65SR5s.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DtDQ76Ox.js → RemoteSession-BGsVH_XU.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-BgLLKwu2.js → Reputation-DpPbxSgI.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BuMLhd8M.js → Row-B5YBYoVz.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BizxUzBA.js → RssFeed-DvM5jaoh.js} +2 -2
- package/src/assets/web-panel/assets/{Search-CYNrJAQY.js → Search-6RX39EPO.js} +1 -1
- package/src/assets/web-panel/assets/{Security-CIC02soH.js → Security-Beal-7cM.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DD3WxXxw.js → Services-D6rjVLe-.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-C-d9Mbos.js → Skeleton-Dur7R7vz.js} +1 -1
- package/src/assets/web-panel/assets/Skills-D1QkGwMk.js +1 -0
- package/src/assets/web-panel/assets/{Sla-DgrqUhns.js → Sla-3ObrX8Es.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CDXFwOHX.js → SpeechSettings-DG_KAiH1.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-BBio_v8M.js → SyncSettings-BaHq0SJ2.js} +2 -2
- package/src/assets/web-panel/assets/Tasks-BDpAkBAB.js +1 -0
- package/src/assets/web-panel/assets/{Templates-RAPdM85o.js → Templates-tYdoRd-c.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-2jI745PC.js → Tenant-yGS5zIQ1.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-ZCtYBMAe.js → Terminal-B3QbmVFa.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-DfI36Yg6.js → TimelineRenderer-B_7Pr5dS.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-NQ1VaO0W.js → Tokens-DPvpDa53.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-DwFh5AMe.js → Trigger-DcSAD0GZ.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Dr0v45uH.js → Trust-BBzEq-uy.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-i7Q1Bdqr.js → UkeySign-Dssav7-5.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CXSkk4gl.js → VideoEditing-CPOZf4yi.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-8_cAjou4.js → Wallet-BzBVRXEq.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-jn_3Gma7.js → WebAuthn-DdSGaCCh.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-BmvodVLl.js → WorkflowEditor-CKjBFoSs.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DGi3bmwL.js → chat-B9aMGLg0.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D8OSTOU0.js → colors-GFCMctSV.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-DfNygJU_.js → compact-item-BqSDFAYJ.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-B0lT0dbj.js → createContext-BwUm3Ffp.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-LxtRBsCm.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-Xtzg_EDR.js → hasIn-DN1kMJOT.js} +1 -1
- package/src/assets/web-panel/assets/index-36hxBH-o.js +1 -0
- package/src/assets/web-panel/assets/{index-De9jsBiC.js → index-7W1e9Vi4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DZKM2nm2.js → index-B4MfxM5W.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFkgqRqx.js → index-B4dI_csl.js} +1 -1
- package/src/assets/web-panel/assets/{index-BVOyO-ZV.js → index-B7Yu5wwV.js} +1 -1
- package/src/assets/web-panel/assets/{index-svr-L6NS.js → index-B9Pe-EyB.js} +3 -3
- package/src/assets/web-panel/assets/{index-Cp-yGWti.js → index-BBMW8bQO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEH5ms1R.js → index-BCnbC2z7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVfE2S0f.js → index-BDL2MwxN.js} +1 -1
- package/src/assets/web-panel/assets/{index-B4-hl9Rw.js → index-BHUxz4dy.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2bgL5vL.js → index-BL_0ndQc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BbTx5wo1.js → index-BPGlcDvs.js} +1 -1
- package/src/assets/web-panel/assets/{index-BFRkiqtr.js → index-BeycSy7n.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBegBTDb.js → index-BpiR6uzH.js} +1 -1
- package/src/assets/web-panel/assets/{index-4s8GZJ73.js → index-BwssFWI1.js} +1 -1
- package/src/assets/web-panel/assets/{index-BBR-_Pkv.js → index-By9GbJhu.js} +1 -1
- package/src/assets/web-panel/assets/index-C0b78zWZ.js +1 -0
- package/src/assets/web-panel/assets/{index-DXNWsfbw.js → index-CEMl-Qte.js} +1 -1
- package/src/assets/web-panel/assets/{index-Byto86PA.js → index-CH2wK5dx.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cx_EAQEh.js → index-CRikhGgx.js} +1 -1
- package/src/assets/web-panel/assets/{index-ConAvib0.js → index-Ci0zIpSX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CShl59Um.js → index-Cli0VREv.js} +1 -1
- package/src/assets/web-panel/assets/{index-BpsIkWwQ.js → index-CmEHzOsw.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhYM_Rzp.js → index-Cwih67e8.js} +1 -1
- package/src/assets/web-panel/assets/{index-BJ6nxb18.js → index-D8jcp9Rj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWpRgQvO.js → index-DAK28GY8.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhS9-r8Z.js → index-DI90Wo_P.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhhS0xnV.js → index-DO-IKERp.js} +1 -1
- package/src/assets/web-panel/assets/{index-B-B7DDjX.js → index-DaFr7XB1.js} +1 -1
- package/src/assets/web-panel/assets/{index-kdyFlPZw.js → index-DbDhKroq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CyVOaMS7.js → index-DnJt9DaX.js} +1 -1
- package/src/assets/web-panel/assets/{index-EV-o-rTH.js → index-DvvJWwT8.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bujix_OR.js → index-PJt1Zrx2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLRMkKeD.js → index-PKwZkQDC.js} +1 -1
- package/src/assets/web-panel/assets/{index-hDo9-qDw.js → index-THsr_UUJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0kDqFPU.js → index-bwb4cg_D.js} +1 -1
- package/src/assets/web-panel/assets/{index-CIbYQLD-.js → index-rCTtYCGu.js} +1 -1
- package/src/assets/web-panel/assets/{index-DVnowoxR.js → index-tMF_deZb.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3ittRaJ.js → index-y7cfh9rP.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CPsOp_T6.js → initDefaultProps-B6e5CZ5p.js} +1 -1
- package/src/assets/web-panel/assets/{motion-8Jakob3_.js → motion-riMM1KfJ.js} +1 -1
- package/src/assets/web-panel/assets/{move-DAogsEBs.js → move-C1NSDMjc.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CkA9zZB_.js → mtc-parser-Bibuny9B.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DMHNkosQ.js → omit-Cmf6FoRn.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-ByIvo_lk.js → pickAttrs-BSsYBUCY.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-CafMUHzz.js → placementArrow-gSB7-GAS.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CTehELUQ.js → responsiveObserve-qaqttvKa.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BQISQ1KV.js → slide-RX2gxl3k.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Drm4jUoK.js → statusUtils-DEJmkhqw.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DGniLRqn.js → styleChecker-CIWmJ78O.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DYz_z9wn.js → useFlexGapSupport-D-UPSQBE.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-DRAPQMjC.js → useFs-9QFtqADc.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CpgGLb8q.js → usePersonalDataHub-DM6kyift.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-p6925VWJ.js → vnode-C-q6FNSJ.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-ClpO8REK.js → zoom-D4WJY2m8.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agent.js +19 -2
- package/src/commands/ask.js +13 -8
- package/src/commands/chat.js +8 -5
- package/src/commands/cowork.js +18 -9
- package/src/commands/eval.js +100 -45
- package/src/commands/evolution-deployment.js +58 -0
- package/src/commands/hub.js +13 -7
- package/src/commands/setup.js +31 -1
- package/src/data/changelog.json +5 -5
- package/src/gateways/ws/personal-data-hub-protocol.js +12 -5
- package/src/lazy-dispatch.js +42 -6
- package/src/lib/agent-router.js +25 -23
- package/src/lib/chat-intent-service.js +3 -13
- package/src/lib/context-memory-kernel/provider-context.js +19 -3
- package/src/lib/cowork-adapter.js +9 -4
- package/src/lib/doctor-checkup.js +42 -0
- package/src/lib/eval/evidence.js +203 -0
- package/src/lib/eval/runner.js +16 -2
- package/src/lib/eval/trend.js +4 -3
- package/src/lib/evolution/evolution-deployment-config.js +217 -10
- package/src/lib/evolution/evolution-deployment-descriptor-revocations.js +131 -0
- package/src/lib/evolution/evolution-deployment-loader.js +23 -2
- package/src/lib/evolution/evolution-deployment-profile.js +281 -37
- package/src/lib/evolution/evolution-deployment-root-rotation.js +154 -0
- package/src/lib/evolution/governed-hub-llm.js +18 -12
- package/src/lib/evolution/governed-hub-skill.js +4 -17
- package/src/lib/evolution/governed-model-turn.js +7 -8
- package/src/lib/orchestrator.js +14 -8
- package/src/lib/personal-data-hub-wiring.js +7 -1
- package/src/lib/sub-agent-context.js +5 -1
- package/src/repl/agent-repl.js +1 -1
- package/src/repl/chat-repl.js +8 -4
- package/src/runtime/agent-core.js +35 -9
- package/src/runtime/headless-runner.js +16 -0
- package/src/assets/web-panel/assets/EvolutionSettings-B3dcSq1H.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-BX4PrVfN.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-yYL7-rno.js +0 -7
- package/src/assets/web-panel/assets/Skills-BBkg1Eqr.js +0 -1
- package/src/assets/web-panel/assets/Tasks-QQWSk-tc.js +0 -1
- package/src/assets/web-panel/assets/devWarning-BUooUkHH.js +0 -1
- package/src/assets/web-panel/assets/index-DVu4QCII.js +0 -1
- package/src/assets/web-panel/assets/index-XYnz-yJ_.js +0 -1
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
+
assertEvolutionDeploymentActiveTrustRoot,
|
|
3
|
+
assertEvolutionDeploymentDescriptorNotRevoked,
|
|
4
|
+
assertEvolutionDeploymentRevisionFloor,
|
|
2
5
|
readEvolutionDeploymentProfile,
|
|
3
6
|
setEvolutionDeploymentProfileEnabled,
|
|
4
|
-
|
|
7
|
+
updateEvolutionDeploymentProfile,
|
|
5
8
|
} from "./evolution-deployment-profile.js";
|
|
6
9
|
import { verifyEvolutionDeployment } from "./evolution-deployment-loader.js";
|
|
10
|
+
import { verifyEvolutionDeploymentRootRotationSync } from "./evolution-deployment-root-rotation.js";
|
|
11
|
+
import { verifyEvolutionDeploymentDescriptorRevocationsSync } from "./evolution-deployment-descriptor-revocations.js";
|
|
7
12
|
|
|
8
13
|
function environmentSelection(env) {
|
|
9
14
|
const descriptorPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_DESCRIPTOR;
|
|
@@ -12,6 +17,102 @@ function environmentSelection(env) {
|
|
|
12
17
|
return { descriptorPath, trustRootPath };
|
|
13
18
|
}
|
|
14
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Project verified deployment prerequisites without importing the host module.
|
|
22
|
+
* `ready` describes deployment admission only, never a successful model probe:
|
|
23
|
+
* the command must still load and validate its composition at execution time.
|
|
24
|
+
*/
|
|
25
|
+
export function assessEvolutionDeploymentReadiness(
|
|
26
|
+
status,
|
|
27
|
+
{ requiredCommands = ["ask", "agent"] } = {},
|
|
28
|
+
) {
|
|
29
|
+
if (
|
|
30
|
+
!Array.isArray(requiredCommands) ||
|
|
31
|
+
requiredCommands.length === 0 ||
|
|
32
|
+
requiredCommands.some(
|
|
33
|
+
(command) =>
|
|
34
|
+
typeof command !== "string" || !/^[a-z][a-z-]*$/.test(command),
|
|
35
|
+
)
|
|
36
|
+
) {
|
|
37
|
+
throw new TypeError("deployment readiness requires explicit command names");
|
|
38
|
+
}
|
|
39
|
+
const commands = Object.freeze([...new Set(requiredCommands)]);
|
|
40
|
+
const allowed = Array.isArray(status?.commands) ? status.commands : [];
|
|
41
|
+
const missingCommands = Object.freeze(
|
|
42
|
+
commands.filter((command) => !allowed.includes(command)),
|
|
43
|
+
);
|
|
44
|
+
const result = (state, code, detail, remediation) => {
|
|
45
|
+
const ready = state === "admitted";
|
|
46
|
+
return Object.freeze({
|
|
47
|
+
scope: "deployment-admission",
|
|
48
|
+
state,
|
|
49
|
+
code,
|
|
50
|
+
ready,
|
|
51
|
+
requiredCommands: commands,
|
|
52
|
+
missingCommands,
|
|
53
|
+
runtimeVerification: "not_checked",
|
|
54
|
+
taskReady: ready ? null : false,
|
|
55
|
+
detail,
|
|
56
|
+
remediation,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
if (
|
|
60
|
+
status?.error ||
|
|
61
|
+
(status?.effectiveEnabled === true && status?.verified !== true)
|
|
62
|
+
) {
|
|
63
|
+
return result(
|
|
64
|
+
"invalid",
|
|
65
|
+
"EVOLUTION_DEPLOYMENT_NOT_VERIFIED",
|
|
66
|
+
`configured Evolution deployment is not verified${status?.error ? `: ${status.error}` : ""}`,
|
|
67
|
+
"repair the signed descriptor or trust root, then run cc evolution deployment status --json",
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
if (status?.effectiveEnabled !== true) {
|
|
71
|
+
const disabled =
|
|
72
|
+
status?.profileEnabled === false && Boolean(status?.descriptorPath);
|
|
73
|
+
return result(
|
|
74
|
+
disabled ? "disabled" : "not_configured",
|
|
75
|
+
disabled
|
|
76
|
+
? "EVOLUTION_DEPLOYMENT_DISABLED"
|
|
77
|
+
: "EVOLUTION_DEPLOYMENT_NOT_CONFIGURED",
|
|
78
|
+
disabled
|
|
79
|
+
? "signed Evolution deployment is disabled"
|
|
80
|
+
: "no enabled signed Evolution deployment",
|
|
81
|
+
disabled
|
|
82
|
+
? "review the saved signed deployment, then run cc evolution deployment enable"
|
|
83
|
+
: "configure a signed descriptor and trust root with cc evolution deployment configure --descriptor <path> --trust-root <path>",
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
if (missingCommands.length > 0) {
|
|
87
|
+
return result(
|
|
88
|
+
"command_not_allowed",
|
|
89
|
+
"EVOLUTION_DEPLOYMENT_COMMAND_NOT_ALLOWED",
|
|
90
|
+
`signed Evolution deployment does not admit commands: ${missingCommands.join(", ")}`,
|
|
91
|
+
`request a signed deployment that admits ${missingCommands.join(", ")}; do not edit the signed descriptor in place`,
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
return result(
|
|
95
|
+
"admitted",
|
|
96
|
+
"EVOLUTION_DEPLOYMENT_ADMITTED",
|
|
97
|
+
`signed Evolution deployment admits ${commands.join(", ")}; runtime composition and model execution are not checked`,
|
|
98
|
+
null,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function withDeploymentReadiness(status) {
|
|
103
|
+
return Object.freeze({
|
|
104
|
+
...status,
|
|
105
|
+
readiness: Object.freeze({
|
|
106
|
+
ask: assessEvolutionDeploymentReadiness(status, {
|
|
107
|
+
requiredCommands: ["ask"],
|
|
108
|
+
}),
|
|
109
|
+
agent: assessEvolutionDeploymentReadiness(status, {
|
|
110
|
+
requiredCommands: ["agent"],
|
|
111
|
+
}),
|
|
112
|
+
}),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
15
116
|
export async function getEvolutionDeploymentStatus(options = {}) {
|
|
16
117
|
const env = options.env || process.env;
|
|
17
118
|
const saved = await readEvolutionDeploymentProfile(options);
|
|
@@ -28,6 +129,7 @@ export async function getEvolutionDeploymentStatus(options = {}) {
|
|
|
28
129
|
effectiveEnabled: source !== "none",
|
|
29
130
|
profileEnabled: saved.profile?.enabled === true,
|
|
30
131
|
profilePath: saved.filePath,
|
|
132
|
+
activeTrustRootDigest: saved.profile?.activeTrustRootDigest || null,
|
|
31
133
|
descriptorPath:
|
|
32
134
|
selected?.descriptorPath || saved.profile?.descriptorPath || null,
|
|
33
135
|
trustRootPath:
|
|
@@ -36,20 +138,38 @@ export async function getEvolutionDeploymentStatus(options = {}) {
|
|
|
36
138
|
error: saved.error,
|
|
37
139
|
autoPromotion: "hold",
|
|
38
140
|
};
|
|
39
|
-
if (!selected || saved.error) return
|
|
141
|
+
if (!selected || saved.error) return withDeploymentReadiness(base);
|
|
40
142
|
try {
|
|
41
143
|
const verified = await verifyEvolutionDeployment(selected, options);
|
|
42
|
-
|
|
144
|
+
if (source === "profile")
|
|
145
|
+
assertEvolutionDeploymentActiveTrustRoot(
|
|
146
|
+
saved.profile,
|
|
147
|
+
verified.descriptor,
|
|
148
|
+
);
|
|
149
|
+
if (source === "profile")
|
|
150
|
+
assertEvolutionDeploymentDescriptorNotRevoked(
|
|
151
|
+
saved.profile,
|
|
152
|
+
verified.descriptor,
|
|
153
|
+
);
|
|
154
|
+
if (source === "profile")
|
|
155
|
+
assertEvolutionDeploymentRevisionFloor(
|
|
156
|
+
saved.profile,
|
|
157
|
+
verified.descriptor,
|
|
158
|
+
);
|
|
159
|
+
return withDeploymentReadiness({
|
|
43
160
|
...base,
|
|
44
161
|
verified: true,
|
|
45
162
|
error: null,
|
|
46
163
|
revision: verified.descriptor.revision,
|
|
164
|
+
revisionFloor:
|
|
165
|
+
saved.profile?.revisionFloors?.[verified.descriptor.trustRootDigest] ||
|
|
166
|
+
null,
|
|
47
167
|
modulePath: verified.modulePath,
|
|
48
168
|
moduleDigest: verified.descriptor.moduleDigest,
|
|
49
169
|
commands: verified.descriptor.commands,
|
|
50
170
|
});
|
|
51
171
|
} catch (error) {
|
|
52
|
-
return
|
|
172
|
+
return withDeploymentReadiness({
|
|
53
173
|
...base,
|
|
54
174
|
error: error instanceof Error ? error.message : String(error),
|
|
55
175
|
});
|
|
@@ -57,21 +177,77 @@ export async function getEvolutionDeploymentStatus(options = {}) {
|
|
|
57
177
|
}
|
|
58
178
|
|
|
59
179
|
export async function configureEvolutionDeployment(
|
|
60
|
-
{
|
|
180
|
+
{
|
|
181
|
+
descriptorPath,
|
|
182
|
+
trustRootPath,
|
|
183
|
+
rootRotationPath = null,
|
|
184
|
+
revocationPath = null,
|
|
185
|
+
enabled = true,
|
|
186
|
+
},
|
|
61
187
|
options = {},
|
|
62
188
|
) {
|
|
63
189
|
const verified = await verifyEvolutionDeployment(
|
|
64
190
|
{ descriptorPath, trustRootPath },
|
|
65
191
|
options,
|
|
66
192
|
);
|
|
67
|
-
|
|
68
|
-
|
|
193
|
+
updateEvolutionDeploymentProfile((current) => {
|
|
194
|
+
if (
|
|
195
|
+
current?.activeTrustRootDigest &&
|
|
196
|
+
current.activeTrustRootDigest !== verified.descriptor.trustRootDigest
|
|
197
|
+
) {
|
|
198
|
+
if (typeof rootRotationPath !== "string" || !rootRotationPath) {
|
|
199
|
+
const error = new Error(
|
|
200
|
+
"evolution deployment trust root rotation requires a certificate signed by the active root",
|
|
201
|
+
);
|
|
202
|
+
error.code = "EVOLUTION_DEPLOYMENT_ROOT_ROTATION_REQUIRED";
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
verifyEvolutionDeploymentRootRotationSync({
|
|
206
|
+
rotationPath: rootRotationPath,
|
|
207
|
+
fromTrustRootPath: current.trustRootPath,
|
|
208
|
+
expectedFromTrustRootDigest: current.activeTrustRootDigest,
|
|
209
|
+
expectedToTrustRootDigest: verified.descriptor.trustRootDigest,
|
|
210
|
+
destinationRevision: verified.descriptor.revision,
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
assertEvolutionDeploymentRevisionFloor(current, verified.descriptor);
|
|
214
|
+
const receivedRevocations = revocationPath
|
|
215
|
+
? verifyEvolutionDeploymentDescriptorRevocationsSync({
|
|
216
|
+
revocationPath,
|
|
217
|
+
trustRootPath: verified.trustRootPath,
|
|
218
|
+
expectedTrustRootDigest: verified.descriptor.trustRootDigest,
|
|
219
|
+
}).revokedDescriptorRevisions
|
|
220
|
+
: [];
|
|
221
|
+
const priorRevocations =
|
|
222
|
+
current?.revokedDescriptorRevisions?.[
|
|
223
|
+
verified.descriptor.trustRootDigest
|
|
224
|
+
] || [];
|
|
225
|
+
const revokedDescriptorRevisions = {
|
|
226
|
+
...(current?.revokedDescriptorRevisions || {}),
|
|
227
|
+
[verified.descriptor.trustRootDigest]: [
|
|
228
|
+
...new Set([...priorRevocations, ...receivedRevocations]),
|
|
229
|
+
].sort((left, right) => left - right),
|
|
230
|
+
};
|
|
231
|
+
assertEvolutionDeploymentDescriptorNotRevoked(
|
|
232
|
+
{ revokedDescriptorRevisions },
|
|
233
|
+
verified.descriptor,
|
|
234
|
+
);
|
|
235
|
+
const revisionFloors = {
|
|
236
|
+
...(current?.revisionFloors || {}),
|
|
237
|
+
[verified.descriptor.trustRootDigest]: Math.max(
|
|
238
|
+
current?.revisionFloors?.[verified.descriptor.trustRootDigest] || 0,
|
|
239
|
+
verified.descriptor.revision,
|
|
240
|
+
),
|
|
241
|
+
};
|
|
242
|
+
return {
|
|
69
243
|
enabled: enabled === true,
|
|
70
244
|
descriptorPath: verified.descriptorPath,
|
|
71
245
|
trustRootPath: verified.trustRootPath,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
246
|
+
revisionFloors,
|
|
247
|
+
activeTrustRootDigest: verified.descriptor.trustRootDigest,
|
|
248
|
+
revokedDescriptorRevisions,
|
|
249
|
+
};
|
|
250
|
+
}, options);
|
|
75
251
|
return getEvolutionDeploymentStatus(options);
|
|
76
252
|
}
|
|
77
253
|
|
|
@@ -79,3 +255,34 @@ export async function setEvolutionDeploymentEnabled(enabled, options = {}) {
|
|
|
79
255
|
await setEvolutionDeploymentProfileEnabled(enabled, options);
|
|
80
256
|
return getEvolutionDeploymentStatus(options);
|
|
81
257
|
}
|
|
258
|
+
|
|
259
|
+
export function revokeEvolutionDeploymentDescriptorRevisions(
|
|
260
|
+
{ revocationPath },
|
|
261
|
+
options = {},
|
|
262
|
+
) {
|
|
263
|
+
updateEvolutionDeploymentProfile((current) => {
|
|
264
|
+
if (!current?.activeTrustRootDigest)
|
|
265
|
+
throw new Error("evolution deployment profile is not configured");
|
|
266
|
+
const record = verifyEvolutionDeploymentDescriptorRevocationsSync({
|
|
267
|
+
revocationPath,
|
|
268
|
+
trustRootPath: current.trustRootPath,
|
|
269
|
+
expectedTrustRootDigest: current.activeTrustRootDigest,
|
|
270
|
+
});
|
|
271
|
+
const prior =
|
|
272
|
+
current.revokedDescriptorRevisions?.[current.activeTrustRootDigest] || [];
|
|
273
|
+
return {
|
|
274
|
+
...current,
|
|
275
|
+
// Disabling is conservative: the current descriptor may be one of the
|
|
276
|
+
// newly revoked revisions, and it must not remain executable while the
|
|
277
|
+
// caller is recovering or selecting a replacement.
|
|
278
|
+
enabled: false,
|
|
279
|
+
revokedDescriptorRevisions: {
|
|
280
|
+
...(current.revokedDescriptorRevisions || {}),
|
|
281
|
+
[current.activeTrustRootDigest]: [
|
|
282
|
+
...new Set([...prior, ...record.revokedDescriptorRevisions]),
|
|
283
|
+
].sort((left, right) => left - right),
|
|
284
|
+
},
|
|
285
|
+
};
|
|
286
|
+
}, options);
|
|
287
|
+
return getEvolutionDeploymentStatus(options);
|
|
288
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { createHash, createPublicKey, verify } from "node:crypto";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { isAbsolute } from "node:path";
|
|
4
|
+
|
|
5
|
+
export const EVOLUTION_DEPLOYMENT_DESCRIPTOR_REVOCATIONS_SCHEMA =
|
|
6
|
+
"chainlesschain.evolution-deployment-descriptor-revocations/v1";
|
|
7
|
+
|
|
8
|
+
const DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
9
|
+
const MAX_BYTES = 64 * 1024;
|
|
10
|
+
const MAX_REVOKED_REVISIONS = 1024;
|
|
11
|
+
|
|
12
|
+
function canonical(value) {
|
|
13
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
14
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
15
|
+
return `{${Object.keys(value)
|
|
16
|
+
.sort()
|
|
17
|
+
.map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
|
|
18
|
+
.join(",")}}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function digest(bytes) {
|
|
22
|
+
return `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function normalize(value) {
|
|
26
|
+
const expected = [
|
|
27
|
+
"revision",
|
|
28
|
+
"revokedDescriptorRevisions",
|
|
29
|
+
"schema",
|
|
30
|
+
"signature",
|
|
31
|
+
"trustRootDigest",
|
|
32
|
+
];
|
|
33
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
34
|
+
throw new TypeError("evolution deployment revocations must be an object");
|
|
35
|
+
if (canonical(Object.keys(value).sort()) !== canonical(expected))
|
|
36
|
+
throw new TypeError("evolution deployment revocations fields are invalid");
|
|
37
|
+
if (value.schema !== EVOLUTION_DEPLOYMENT_DESCRIPTOR_REVOCATIONS_SCHEMA)
|
|
38
|
+
throw new TypeError("evolution deployment revocations schema is invalid");
|
|
39
|
+
if (!DIGEST.test(value.trustRootDigest || ""))
|
|
40
|
+
throw new TypeError("evolution deployment revocations trust root is invalid");
|
|
41
|
+
if (!Number.isSafeInteger(value.revision) || value.revision < 1)
|
|
42
|
+
throw new TypeError("evolution deployment revocations revision is invalid");
|
|
43
|
+
if (
|
|
44
|
+
!Array.isArray(value.revokedDescriptorRevisions) ||
|
|
45
|
+
value.revokedDescriptorRevisions.length > MAX_REVOKED_REVISIONS ||
|
|
46
|
+
value.revokedDescriptorRevisions.some(
|
|
47
|
+
(revision) => !Number.isSafeInteger(revision) || revision < 1,
|
|
48
|
+
) ||
|
|
49
|
+
new Set(value.revokedDescriptorRevisions).size !==
|
|
50
|
+
value.revokedDescriptorRevisions.length
|
|
51
|
+
) {
|
|
52
|
+
throw new TypeError("evolution deployment revoked revisions are invalid");
|
|
53
|
+
}
|
|
54
|
+
if (
|
|
55
|
+
typeof value.signature !== "string" ||
|
|
56
|
+
value.signature.length === 0 ||
|
|
57
|
+
!/^[A-Za-z0-9+/]+={0,2}$/u.test(value.signature)
|
|
58
|
+
) {
|
|
59
|
+
throw new TypeError("evolution deployment revocations signature is invalid");
|
|
60
|
+
}
|
|
61
|
+
return Object.freeze({
|
|
62
|
+
...value,
|
|
63
|
+
revokedDescriptorRevisions: Object.freeze(
|
|
64
|
+
[...value.revokedDescriptorRevisions].sort((left, right) => left - right),
|
|
65
|
+
),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function serializeEvolutionDeploymentDescriptorRevocationsPayload(value) {
|
|
70
|
+
const revocations = normalize({ ...value, signature: "AA==" });
|
|
71
|
+
return canonical({
|
|
72
|
+
schema: revocations.schema,
|
|
73
|
+
revision: revocations.revision,
|
|
74
|
+
trustRootDigest: revocations.trustRootDigest,
|
|
75
|
+
revokedDescriptorRevisions: revocations.revokedDescriptorRevisions,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function verifyEvolutionDeploymentDescriptorRevocationsSync({
|
|
80
|
+
revocationPath,
|
|
81
|
+
trustRootPath,
|
|
82
|
+
expectedTrustRootDigest,
|
|
83
|
+
}) {
|
|
84
|
+
if (
|
|
85
|
+
typeof revocationPath !== "string" ||
|
|
86
|
+
!isAbsolute(revocationPath) ||
|
|
87
|
+
typeof trustRootPath !== "string" ||
|
|
88
|
+
!isAbsolute(trustRootPath) ||
|
|
89
|
+
!DIGEST.test(expectedTrustRootDigest || "")
|
|
90
|
+
) {
|
|
91
|
+
throw new Error("evolution deployment revocation inputs are invalid");
|
|
92
|
+
}
|
|
93
|
+
let record;
|
|
94
|
+
let trustRootBytes;
|
|
95
|
+
try {
|
|
96
|
+
const bytes = readFileSync(revocationPath);
|
|
97
|
+
if (bytes.byteLength === 0 || bytes.byteLength > MAX_BYTES)
|
|
98
|
+
throw new Error("evolution deployment revocations size is invalid");
|
|
99
|
+
record = normalize(JSON.parse(bytes.toString("utf8")));
|
|
100
|
+
trustRootBytes = readFileSync(trustRootPath);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
"evolution deployment revocations could not be read",
|
|
104
|
+
error instanceof Error ? { cause: error } : undefined,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
if (digest(trustRootBytes) !== expectedTrustRootDigest)
|
|
108
|
+
throw new Error("evolution deployment revocation trust root changed");
|
|
109
|
+
if (record.trustRootDigest !== expectedTrustRootDigest)
|
|
110
|
+
throw new Error("evolution deployment revocation trust root does not match");
|
|
111
|
+
let publicKey;
|
|
112
|
+
try {
|
|
113
|
+
publicKey = createPublicKey(trustRootBytes);
|
|
114
|
+
} catch {
|
|
115
|
+
throw new Error("evolution deployment revocation trust root is invalid");
|
|
116
|
+
}
|
|
117
|
+
if (
|
|
118
|
+
!verify(
|
|
119
|
+
null,
|
|
120
|
+
Buffer.from(
|
|
121
|
+
serializeEvolutionDeploymentDescriptorRevocationsPayload(record),
|
|
122
|
+
"utf8",
|
|
123
|
+
),
|
|
124
|
+
publicKey,
|
|
125
|
+
Buffer.from(record.signature, "base64"),
|
|
126
|
+
)
|
|
127
|
+
) {
|
|
128
|
+
throw new Error("evolution deployment revocation signature rejected");
|
|
129
|
+
}
|
|
130
|
+
return record;
|
|
131
|
+
}
|
|
@@ -2,7 +2,12 @@ import { createHash, createPublicKey, verify } from "node:crypto";
|
|
|
2
2
|
import { readFile, realpath } from "node:fs/promises";
|
|
3
3
|
import { isAbsolute } from "node:path";
|
|
4
4
|
import { types as utilTypes } from "node:util";
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
assertEvolutionDeploymentActiveTrustRoot,
|
|
7
|
+
assertEvolutionDeploymentDescriptorNotRevoked,
|
|
8
|
+
assertEvolutionDeploymentRevisionFloor,
|
|
9
|
+
readEvolutionDeploymentProfile,
|
|
10
|
+
} from "./evolution-deployment-profile.js";
|
|
6
11
|
|
|
7
12
|
export const EVOLUTION_DEPLOYMENT_DESCRIPTOR_SCHEMA =
|
|
8
13
|
"chainlesschain.evolution-deployment-descriptor/v1";
|
|
@@ -486,8 +491,9 @@ export async function loadEvolutionDeploymentCommandDependencies(
|
|
|
486
491
|
let descriptorPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_DESCRIPTOR;
|
|
487
492
|
let trustRootPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_TRUST_ROOT;
|
|
488
493
|
let fromSavedProfile = false;
|
|
494
|
+
let saved = null;
|
|
489
495
|
if (!descriptorPath && !trustRootPath) {
|
|
490
|
-
|
|
496
|
+
saved = await readEvolutionDeploymentProfile({ env });
|
|
491
497
|
if (!saved.error && saved.profile?.enabled) {
|
|
492
498
|
descriptorPath = saved.profile.descriptorPath;
|
|
493
499
|
trustRootPath = saved.profile.trustRootPath;
|
|
@@ -505,6 +511,21 @@ export async function loadEvolutionDeploymentCommandDependencies(
|
|
|
505
511
|
{ descriptorPath, trustRootPath },
|
|
506
512
|
{ read, resolveRealPath, includeModuleBytes: true },
|
|
507
513
|
);
|
|
514
|
+
if (fromSavedProfile)
|
|
515
|
+
assertEvolutionDeploymentActiveTrustRoot(
|
|
516
|
+
saved.profile,
|
|
517
|
+
verified.descriptor,
|
|
518
|
+
);
|
|
519
|
+
if (fromSavedProfile)
|
|
520
|
+
assertEvolutionDeploymentDescriptorNotRevoked(
|
|
521
|
+
saved.profile,
|
|
522
|
+
verified.descriptor,
|
|
523
|
+
);
|
|
524
|
+
if (fromSavedProfile)
|
|
525
|
+
assertEvolutionDeploymentRevisionFloor(
|
|
526
|
+
saved.profile,
|
|
527
|
+
verified.descriptor,
|
|
528
|
+
);
|
|
508
529
|
} catch (error) {
|
|
509
530
|
// A saved profile may become stale after files are moved or rotated. Keep
|
|
510
531
|
// governed capabilities fail-closed while allowing `deployment status`,
|