chainlesschain 0.166.15 → 0.166.17
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 +3 -3
- package/completions/_cc +1 -1
- package/completions/cc.bash +1 -1
- package/completions/cc.fish +1 -1
- package/completions/cc.ps1 +1 -1
- package/package.json +2 -2
- package/src/assets/web-panel/assets/{AIOps-To-6rimH.js → AIOps-CVW2n2rh.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-CpdCnTv3.js → ActionButton-DtuM163O.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DK7VNES_.js → Analytics-BXvl_qHu.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-NZ5FvhCx.js → AppLayout-VDBTFKOp.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-NXceQPmN.js → Artifacts-BNz2xCiG.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-B2d64DH2.js → Audit-DTu9Hn9P.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-ByYgvEVY.js → BackgroundAgents-D2OCPzLe.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BXvQLDvN.js → Backup-C9M-vG7G.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-C4GZk-As.js → BaseInput-BUkCNiUQ.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-CvPuohL8.js → Chat-OJ2ajF7l.js} +5 -5
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-DTftcclX.js → ChatBubbleRenderer-BdZt76Ab.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-C8dQGIqD.js → Checkbox-C1gXKDsc.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DRM6S1W4.js → Codegen-BXbznLg7.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BDM8l-r5.js → Col-CbCq5N0i.js} +1 -1
- package/src/assets/web-panel/assets/{Community-Bvmfi1fX.js → Community-V8Ks6Yun.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DGQTCima.js → Compact-DkeHQTpQ.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-D_0C-2P6.js → Compliance-JeLKwn4Q.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-3C_q99ok.js → Cowork-azfetcBz.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-CIiMQ1Hl.js → Cron-Q691i_Gp.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-peebGnES.js → Crosschain-BLjDRbr_.js} +1 -1
- package/src/assets/web-panel/assets/{DID-OkX4KB9T.js → DID-D8ptXplK.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-D9lm0Wxa.js → Dashboard-Ctj2VVZL.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-CitActXx.js → Dropdown-D8VgkMJ8.js} +1 -1
- package/src/assets/web-panel/assets/EmailListRenderer-CQPe5S6q.js +1 -0
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-CBWAi8XL.js → FamilyGuardDashboard-ySA-7SiN.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-afj8jDcp.js → Federation-1PMD-fBf.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-Dabt59KY.js → FormItemContext-C_jr6U4Q.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-BQpXA9kj.js → GenericCardRenderer-Bu3bKf2B.js} +1 -1
- package/src/assets/web-panel/assets/{Git-D2p2Moo1.js → Git-Dv4Fa_T5.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DkFfPykv.js → Governance-DOEy1n1k.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-C1DKpeN2.js → Inference-DkvqzWcJ.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-CjfVg4oQ.js → KnowledgeGraph-DdUJK949.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-D-zMvdSf.js → Logs-CRelcdUZ.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-jzEpGkbc.js → MarkdownRenderer-0AHbbTA4.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-DfAjJLyS.js → Marketplace-BuuBKsev.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BGDHQES1.js → McpTools-DlgpEmA1.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-BYqrGAPS.js → Memory-DTfdqUGy.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-CQ6FEtty.js → MobileBridge-CXLE5ZFO.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-BpMvh5JW.js → MobileProjects-Dz25OB0n.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-CWH25SrU.js → Mtc-kEL0fhgD.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-D6DiLmei.js → MtcAudit-BE4UvFJU.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-BSxRN4jD.js → Multisig-CSApSn8c.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-C0FDPKT4.js → NLProgramming-D11FpKWx.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-VKR78bH-.js → Notes-CDL-D2CS.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DLSklSZB.js → NotificationSettings-C0Q6lO-c.js} +1 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-ZRE0OKbj.js +1 -0
- package/src/assets/web-panel/assets/{Organization-BB3pB27e.js → Organization-Dc-maVAq.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-Cr7bzwcs.js → Overflow-B5mUpSvi.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-D1fkMMzI.js → P2P-TjXV53wq.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-DvV2btIr.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-c3Ijv0v4.js → Permissions-DKRzQ2O6.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-BJwbh3P2.js → PersonalDataHub-Dx2eqft8.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-C4fhXafB.js → Pipeline-CnYZMB5p.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-DzSx3CD-.js → Privacy-BonKpPnp.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-D9fL5fED.js → ProjectInit-DWO0Du3J.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CB5FVrOR.js → ProjectSettings-C9jqyYRv.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-DWhwdgfY.js → Projects-CYpKwXbz.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-B9ZH4faS.js → Providers-CW-fkwJq.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-BLKDHT8_.js → QrScannerModal-Cw0J3Zud.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-D1oYUcSY.js → QuickAsk-BH4A4IpR.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CC2nmrOD.js → Recommend-CDwMwJus.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-qW9QF4-r.js → RemoteSession-DKIPwzTf.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-BDWqfzcr.js → Reputation-CklDj7qS.js} +1 -1
- package/src/assets/web-panel/assets/{Row-BBV2iCjT.js → Row-DJWZKsH0.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-CcwrNwZB.js → RssFeed-BfSLCewo.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Dr6fZ0D_.js → Search-B0IST--x.js} +1 -1
- package/src/assets/web-panel/assets/{Security-BPzaoCU6.js → Security-h1sYNWtt.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BoKUU1I_.js → Services-Gh0-oxI_.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-C8lT8GUg.js → Skeleton-CNDV_jOs.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-DPpWeicz.js → Skills-ByCLTh1n.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-UiijzpMU.js → Sla-BfyrJTJz.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DoofrLwS.js → SpeechSettings-BQzo9kNX.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-DXnyfTDw.js → SyncSettings-B6fS6z_1.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-g_WHjKeg.js → Tasks-C-uKCP-l.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-DRuCh9g2.js → Templates-D6oDy7wL.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-QHIq1pH1.js → Tenant-D3LT2wNQ.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-G0fuI216.js → Terminal-BteLcv_O.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-4MT7SpGk.js → TimelineRenderer-DHHuxfqH.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-B5xT5umA.js → Tokens-BRQeykXw.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-D7HPbNgc.js → Trigger-p2XaFWEu.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-CxH69dU5.js → Trust-BxadBMft.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CPPosveH.js → UkeySign-DRBP7LDk.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-Du5lGwAt.js → VideoEditing-CZ3NZkh7.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BBIGNESK.js → Wallet-C3NTBN7G.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-Cc3HSGmv.js → WebAuthn-C7LVgMlb.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-DBoVPNCh.js → WorkflowEditor-0_Iveog7.js} +1 -1
- package/src/assets/web-panel/assets/{chat-DHcjgiem.js → chat-DzzluYo3.js} +1 -1
- package/src/assets/web-panel/assets/{colors-DrRrvJIV.js → colors-DSMYXpaj.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-BuY_sAoN.js → compact-item-W76u1VSV.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CepH1Fha.js → createContext-otsESjb5.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BztaXF84.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-Dh80Ot6o.js → hasIn-3sNLrvug.js} +1 -1
- package/src/assets/web-panel/assets/index-4jP_hG_4.js +1 -0
- package/src/assets/web-panel/assets/{index-LBkSOwky.js → index-B1I1AYJs.js} +1 -1
- package/src/assets/web-panel/assets/{index-B0rvJjId.js → index-B5LOYdYm.js} +1 -1
- package/src/assets/web-panel/assets/{index-D6tOVlq-.js → index-B9X_jqXe.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7lstbTh.js → index-BA8mZxd-.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPDEOOlA.js → index-BDlDO2px.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuSUCH7h.js → index-BJsQio5O.js} +1 -1
- package/src/assets/web-panel/assets/{index-CEfVkKIY.js → index-BRsD1PT2.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYydOga6.js → index-BXLx9HfA.js} +1 -1
- package/src/assets/web-panel/assets/{index-DkZP_QaB.js → index-BcGJtmHM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BnVIvc15.js → index-BdtmEKat.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuRYBWrj.js → index-BpcQYzP7.js} +1 -1
- package/src/assets/web-panel/assets/{index-By0qqC3S.js → index-C2aht9-M.js} +1 -1
- package/src/assets/web-panel/assets/{index-C10033eO.js → index-CE7tSow-.js} +1 -1
- package/src/assets/web-panel/assets/{index-9crgJ3Id.js → index-CENWwjef.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNQK9DIr.js → index-CKoFyHYQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUNyTmkS.js → index-Cg86EzNp.js} +1 -1
- package/src/assets/web-panel/assets/{index-CnRK8_Dd.js → index-ClOFeZ-t.js} +1 -1
- package/src/assets/web-panel/assets/{index-BW9Pycxh.js → index-CtFOt5x1.js} +1 -1
- package/src/assets/web-panel/assets/{index-D5_K3GKu.js → index-D7A5U2IH.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRy3_beb.js → index-DH4cl52p.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWANFMlq.js → index-DLDh1OW3.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5vhNRqS.js → index-DMmdIpLA.js} +1 -1
- package/src/assets/web-panel/assets/{index-Ca5d64IH.js → index-DS9WYDMf.js} +1 -1
- package/src/assets/web-panel/assets/{index-zGH9zH3w.js → index-DTA8Iavv.js} +3 -3
- package/src/assets/web-panel/assets/{index-BoRy2yup.js → index-DZKAzEge.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cx21_p3m.js → index-DdU7IkKX.js} +1 -1
- package/src/assets/web-panel/assets/{index-B9Gh-SOn.js → index-Ddd4mird.js} +1 -1
- package/src/assets/web-panel/assets/{index-CiUx-tkV.js → index-DmpaC2yk.js} +1 -1
- package/src/assets/web-panel/assets/{index-DYN49m7k.js → index-GlIOE4ja.js} +1 -1
- package/src/assets/web-panel/assets/{index-CUnd5hyp.js → index-MhQQ3h8q.js} +1 -1
- package/src/assets/web-panel/assets/{index-CW_23-gU.js → index-NaO9AE-F.js} +1 -1
- package/src/assets/web-panel/assets/{index-0TYLnd11.js → index-UUHCwfNq.js} +1 -1
- package/src/assets/web-panel/assets/{index-NS9dW1F1.js → index-pVm_iUre.js} +1 -1
- package/src/assets/web-panel/assets/{index-hYaigdGm.js → index-q7ftLqNt.js} +1 -1
- package/src/assets/web-panel/assets/{index-A5lVwYVq.js → index-uSCkbpZH.js} +1 -1
- package/src/assets/web-panel/assets/{index-BtqigRzf.js → index-vBKPcmAP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiZQooWK.js → index-vUmYkqmu.js} +1 -1
- package/src/assets/web-panel/assets/index-zxwuAXL5.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-nI_X3wKl.js → initDefaultProps-DF6llUXV.js} +1 -1
- package/src/assets/web-panel/assets/{motion-LUHbQu_R.js → motion-vtDV8_5K.js} +1 -1
- package/src/assets/web-panel/assets/{move-DHI_KvJt.js → move-B6c0bdy2.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-AYdL_7Mo.js → mtc-parser-DlLYWuBK.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CtV3HRKa.js → omit-BH0zOxLN.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CcJLTOu4.js → pickAttrs-D9di8_In.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-DHbiLUps.js → placementArrow-BDSngufM.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-BC2DGkWP.js → responsiveObserve-C_EawMvP.js} +1 -1
- package/src/assets/web-panel/assets/{slide-B4ga4pPY.js → slide-B_4wShxA.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-hzphgKfH.js → statusUtils-CbQu6qJ-.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-IfN9Bxoi.js → styleChecker-CvXJWYXb.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-pcGKJ4pT.js → useFlexGapSupport-jjY1XknO.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-COXhQpTG.js → useFs-CMXBdsK_.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-xp9F9szv.js → usePersonalDataHub-YbAhhPXx.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-BdSQy1Ve.js → vnode-BFCTKc0H.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-CHCt5P55.js → zoom-CY9aBl5O.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +2 -2
- package/src/command-manifest.json +2 -2
- package/src/commands/evolution.js +30 -17
- package/src/commands/learning.js +95 -9
- package/src/commands/team.js +5 -0
- package/src/data/changelog.json +28 -2
- package/src/lib/agent-team/task-lease.js +12 -1
- package/src/lib/capability-manifest.js +212 -1
- package/src/lib/evolution/bounded-skill-improvement-pilot.js +498 -0
- package/src/lib/evolution/evolution-artifact-ports.js +3277 -0
- package/src/lib/evolution/evolution-eval-gate.js +6442 -0
- package/src/lib/evolution/evolution-evidence-projector.js +3786 -0
- package/src/lib/evolution/evolution-ledger-ports.js +2689 -0
- package/src/lib/evolution/evolution-ledger.js +4280 -0
- package/src/lib/evolution/evolution-run-runtime-adapter.js +5 -0
- package/src/lib/evolution/skill-candidate-registry.js +2258 -0
- package/src/lib/evolution/skill-evaluated-promotion-durability.js +899 -0
- package/src/lib/evolution/skill-evaluated-promotion.js +481 -0
- package/src/lib/evolution/skill-execution-manifest.js +942 -0
- package/src/lib/evolution/skill-mutation-authority.js +1677 -0
- package/src/lib/evolution/skill-promotion-controller.js +618 -0
- package/src/lib/evolution/skill-release-registry.js +3277 -0
- package/src/lib/evolution/skill-target-matrix-eval.js +3233 -0
- package/src/lib/evolution/skill-writer-inventory-manifest.js +998 -0
- package/src/lib/evolution/skill-writer-inventory-validator.js +816 -0
- package/src/lib/evolution/wiki-informed-skill-proposer.js +343 -0
- package/src/lib/formal-quality-eval-runtime.js +100 -0
- package/src/lib/graph-kernel/cutover-contract.js +7 -0
- package/src/lib/graph-kernel/cutover-ledger.js +8 -7
- package/src/lib/graph-kernel/evidence-digest.js +47 -0
- package/src/lib/graph-kernel/evolution-run-runtime-adapter.js +5 -0
- package/src/lib/graph-kernel/graph-runtime-surfaces.json +8 -1
- package/src/lib/graph-kernel/production-cutover-evidence.js +342 -15
- package/src/lib/graph-kernel/production-source-evidence.js +1599 -0
- package/src/lib/graph-kernel/retirement-evidence.js +15 -5
- package/src/lib/graph-kernel/runtime-surface-manifest.js +67 -2
- package/src/lib/headless-manifest.js +3 -1
- package/src/lib/hooks-v2-runtime.js +20 -0
- package/src/lib/learning/skill-improver.js +311 -43
- package/src/lib/learning/skill-synthesizer.js +236 -16
- package/src/lib/secure-fs.js +20 -0
- package/src/runtime/agent-core.js +68 -0
- package/src/assets/web-panel/assets/EmailListRenderer-DSmFkNKV.js +0 -1
- package/src/assets/web-panel/assets/OrderTableRenderer-Dpj7D6tC.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-BiDEbLNA.js +0 -7
- package/src/assets/web-panel/assets/devWarning-DIb8j04q.js +0 -1
- package/src/assets/web-panel/assets/index-BJc3t4PC.js +0 -1
- package/src/assets/web-panel/assets/index-CkksSUnI.js +0 -1
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { types as utilTypes } from "node:util";
|
|
3
|
+
|
|
4
|
+
import { verifySkillMutationRequest } from "./skill-mutation-authority.js";
|
|
5
|
+
import {
|
|
6
|
+
SKILL_TARGET_MATRIX_EVAL_RECEIPT_SCHEMA,
|
|
7
|
+
verifySkillTargetMatrixEvalReceipt,
|
|
8
|
+
} from "./skill-target-matrix-eval.js";
|
|
9
|
+
|
|
10
|
+
export const SKILL_EVALUATED_PROMOTION_RECEIPT_ENVELOPE_SCHEMA =
|
|
11
|
+
"chainlesschain.skill-evaluated-promotion-receipt-envelope/v1";
|
|
12
|
+
export const SKILL_EVALUATED_PROMOTION_BINDING_SCHEMA =
|
|
13
|
+
"chainlesschain.skill-evaluated-promotion-binding/v1";
|
|
14
|
+
export const SKILL_EVALUATED_PROMOTION_PROVIDER_SCHEMA =
|
|
15
|
+
"chainlesschain.skill-evaluated-promotion-provider/v1";
|
|
16
|
+
export const SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLVER_SCHEMA =
|
|
17
|
+
"chainlesschain.skill-evaluated-promotion-receipt-resolver/v1";
|
|
18
|
+
export const SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_REQUEST_SCHEMA =
|
|
19
|
+
"chainlesschain.skill-evaluated-promotion-receipt-resolution-request/v1";
|
|
20
|
+
export const SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_SCHEMA =
|
|
21
|
+
"chainlesschain.skill-evaluated-promotion-receipt-resolution/v1";
|
|
22
|
+
|
|
23
|
+
const DIGEST_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
24
|
+
const ENVELOPE_KEYS = new Set(["receiptDigest", "schema"]);
|
|
25
|
+
const MATRIX_CONTEXT_KEYS = new Set([
|
|
26
|
+
"baselineId",
|
|
27
|
+
"matrixAuthorityRoot",
|
|
28
|
+
"matrixEvalId",
|
|
29
|
+
"planDigest",
|
|
30
|
+
]);
|
|
31
|
+
const RECEIPT_RESOLVER_KEYS = new Set([
|
|
32
|
+
"schema",
|
|
33
|
+
"authorityId",
|
|
34
|
+
"trust",
|
|
35
|
+
"revision",
|
|
36
|
+
"handlerArtifactDigest",
|
|
37
|
+
"resolve",
|
|
38
|
+
]);
|
|
39
|
+
const RECEIPT_RESOLUTION_KEYS = new Set([
|
|
40
|
+
"schema",
|
|
41
|
+
"authorityId",
|
|
42
|
+
"trust",
|
|
43
|
+
"revision",
|
|
44
|
+
"handlerArtifactDigest",
|
|
45
|
+
"tenantId",
|
|
46
|
+
"receiptDigest",
|
|
47
|
+
"matrixReceipt",
|
|
48
|
+
"resolvedAt",
|
|
49
|
+
]);
|
|
50
|
+
const SAFE_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$/u;
|
|
51
|
+
const PROVIDER_OPTION_KEYS = new Set([
|
|
52
|
+
"authorityId",
|
|
53
|
+
"handlerArtifactDigest",
|
|
54
|
+
"receiptResolver",
|
|
55
|
+
"revision",
|
|
56
|
+
"verifier",
|
|
57
|
+
]);
|
|
58
|
+
const PROVIDER_KEYS = new Set([
|
|
59
|
+
"schema",
|
|
60
|
+
"authorityId",
|
|
61
|
+
"handlerArtifactDigest",
|
|
62
|
+
"revision",
|
|
63
|
+
"verify",
|
|
64
|
+
]);
|
|
65
|
+
const PROVIDER_INPUT_KEYS = new Set([
|
|
66
|
+
"activeContentDigest",
|
|
67
|
+
"authorization",
|
|
68
|
+
"candidate",
|
|
69
|
+
"matrixContext",
|
|
70
|
+
"state",
|
|
71
|
+
]);
|
|
72
|
+
const PROVIDER_INSTANCES = new WeakSet();
|
|
73
|
+
|
|
74
|
+
export class SkillEvaluatedPromotionError extends Error {
|
|
75
|
+
constructor(code, message, details = {}) {
|
|
76
|
+
super(message, details.cause ? { cause: details.cause } : undefined);
|
|
77
|
+
this.name = "SkillEvaluatedPromotionError";
|
|
78
|
+
this.code = code;
|
|
79
|
+
for (const [key, value] of Object.entries(details)) {
|
|
80
|
+
if (key !== "cause") this[key] = value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function failure(code, message, details = {}) {
|
|
86
|
+
return new SkillEvaluatedPromotionError(code, message, details);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function assertDataRecord(value, keys, label) {
|
|
90
|
+
if (
|
|
91
|
+
!value ||
|
|
92
|
+
typeof value !== "object" ||
|
|
93
|
+
Array.isArray(value) ||
|
|
94
|
+
utilTypes.isProxy(value)
|
|
95
|
+
) {
|
|
96
|
+
throw failure(
|
|
97
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
98
|
+
`${label} must be a plain object`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
const prototype = Object.getPrototypeOf(value);
|
|
102
|
+
const ownKeys = Reflect.ownKeys(value);
|
|
103
|
+
if (
|
|
104
|
+
(prototype !== Object.prototype && prototype !== null) ||
|
|
105
|
+
ownKeys.length !== keys.size ||
|
|
106
|
+
ownKeys.some((key) => typeof key !== "string" || !keys.has(key))
|
|
107
|
+
) {
|
|
108
|
+
throw failure(
|
|
109
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
110
|
+
`${label} must contain exactly the supported fields`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
for (const key of ownKeys) {
|
|
114
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
115
|
+
if (!descriptor || !("value" in descriptor) || !descriptor.enumerable) {
|
|
116
|
+
throw failure(
|
|
117
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
118
|
+
`${label}.${String(key)} must be an enumerable own data field`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function deepFreeze(value, seen = new WeakSet()) {
|
|
125
|
+
if (!value || typeof value !== "object" || seen.has(value)) return value;
|
|
126
|
+
seen.add(value);
|
|
127
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
128
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
129
|
+
if (!descriptor || !("value" in descriptor)) {
|
|
130
|
+
throw failure(
|
|
131
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
132
|
+
"trusted matrix evidence must contain only own data fields",
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
deepFreeze(descriptor.value, seen);
|
|
136
|
+
}
|
|
137
|
+
return Object.freeze(value);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function normalizeId(value, label) {
|
|
141
|
+
if (typeof value !== "string" || !SAFE_ID_PATTERN.test(value)) {
|
|
142
|
+
throw failure("SKILL_EVALUATED_PROMOTION_INVALID", `${label} is invalid`);
|
|
143
|
+
}
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function normalizeDigest(value, label) {
|
|
148
|
+
if (typeof value !== "string" || !DIGEST_PATTERN.test(value)) {
|
|
149
|
+
throw failure(
|
|
150
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
151
|
+
`${label} must be a lowercase SHA-256 digest`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function resolverDescriptorDigest(descriptor) {
|
|
158
|
+
return `sha256:${createHash("sha256")
|
|
159
|
+
.update(
|
|
160
|
+
`chainlesschain.skill-evaluated-promotion-receipt-resolver-descriptor/v1\0${JSON.stringify(descriptor)}`,
|
|
161
|
+
"utf8",
|
|
162
|
+
)
|
|
163
|
+
.digest("hex")}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function captureReceiptResolver(value) {
|
|
167
|
+
assertDataRecord(value, RECEIPT_RESOLVER_KEYS, "matrix receipt resolver");
|
|
168
|
+
if (
|
|
169
|
+
value.schema !== SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLVER_SCHEMA ||
|
|
170
|
+
value.trust !== "trusted" ||
|
|
171
|
+
!Number.isSafeInteger(value.revision) ||
|
|
172
|
+
value.revision < 1 ||
|
|
173
|
+
typeof value.resolve !== "function" ||
|
|
174
|
+
utilTypes.isProxy(value.resolve)
|
|
175
|
+
) {
|
|
176
|
+
throw failure(
|
|
177
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
178
|
+
"matrix receipt resolver authority is invalid",
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
const descriptor = deepFreeze({
|
|
182
|
+
schema: value.schema,
|
|
183
|
+
authorityId: normalizeId(value.authorityId, "resolver authorityId"),
|
|
184
|
+
trust: value.trust,
|
|
185
|
+
revision: value.revision,
|
|
186
|
+
handlerArtifactDigest: normalizeDigest(
|
|
187
|
+
value.handlerArtifactDigest,
|
|
188
|
+
"resolver handlerArtifactDigest",
|
|
189
|
+
),
|
|
190
|
+
});
|
|
191
|
+
const resolve = value.resolve.bind(value);
|
|
192
|
+
Object.freeze(value);
|
|
193
|
+
return { descriptor, resolve };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function resolveMatrixReceipt(resolver, tenantId, receiptDigest) {
|
|
197
|
+
const captured = captureReceiptResolver(resolver);
|
|
198
|
+
const request = deepFreeze({
|
|
199
|
+
schema: SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_REQUEST_SCHEMA,
|
|
200
|
+
tenantId,
|
|
201
|
+
receiptDigest,
|
|
202
|
+
});
|
|
203
|
+
let resolution;
|
|
204
|
+
try {
|
|
205
|
+
resolution = await captured.resolve(request);
|
|
206
|
+
} catch (cause) {
|
|
207
|
+
throw failure(
|
|
208
|
+
"SKILL_EVALUATED_PROMOTION_RESOLUTION_FAILED",
|
|
209
|
+
"matrix receipt resolver failed closed",
|
|
210
|
+
{ cause },
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
assertDataRecord(
|
|
214
|
+
resolution,
|
|
215
|
+
RECEIPT_RESOLUTION_KEYS,
|
|
216
|
+
"matrix receipt resolution",
|
|
217
|
+
);
|
|
218
|
+
const receipt = Object.getOwnPropertyDescriptor(
|
|
219
|
+
resolution,
|
|
220
|
+
"matrixReceipt",
|
|
221
|
+
)?.value;
|
|
222
|
+
const resolvedAt = resolution.resolvedAt;
|
|
223
|
+
if (
|
|
224
|
+
resolution.schema !== SKILL_EVALUATED_PROMOTION_RECEIPT_RESOLUTION_SCHEMA ||
|
|
225
|
+
resolution.authorityId !== captured.descriptor.authorityId ||
|
|
226
|
+
resolution.trust !== captured.descriptor.trust ||
|
|
227
|
+
resolution.revision !== captured.descriptor.revision ||
|
|
228
|
+
resolution.handlerArtifactDigest !==
|
|
229
|
+
captured.descriptor.handlerArtifactDigest ||
|
|
230
|
+
resolution.tenantId !== tenantId ||
|
|
231
|
+
resolution.receiptDigest !== receiptDigest ||
|
|
232
|
+
!receipt ||
|
|
233
|
+
typeof receipt !== "object" ||
|
|
234
|
+
utilTypes.isProxy(receipt) ||
|
|
235
|
+
Object.getOwnPropertyDescriptor(receipt, "receiptDigest")?.value !==
|
|
236
|
+
receiptDigest ||
|
|
237
|
+
typeof resolvedAt !== "string" ||
|
|
238
|
+
!Number.isFinite(Date.parse(resolvedAt)) ||
|
|
239
|
+
new Date(resolvedAt).toISOString() !== resolvedAt
|
|
240
|
+
) {
|
|
241
|
+
throw failure(
|
|
242
|
+
"SKILL_EVALUATED_PROMOTION_RESOLUTION_REJECTED",
|
|
243
|
+
"matrix receipt resolution is not exactly bound to its trusted authority and digest",
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
receipt,
|
|
248
|
+
resolution: deepFreeze({
|
|
249
|
+
authorityId: captured.descriptor.authorityId,
|
|
250
|
+
resolverDescriptorDigest: resolverDescriptorDigest(captured.descriptor),
|
|
251
|
+
resolverRevision: captured.descriptor.revision,
|
|
252
|
+
resolvedAt,
|
|
253
|
+
}),
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function buildSkillEvaluatedPromotionReceiptEnvelope(receipt) {
|
|
258
|
+
if (receipt && typeof receipt === "object" && utilTypes.isProxy(receipt)) {
|
|
259
|
+
throw failure(
|
|
260
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
261
|
+
"matrix receipt must be a plain object",
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
assertDataRecord(
|
|
265
|
+
receipt,
|
|
266
|
+
new Set(Reflect.ownKeys(receipt).filter((key) => typeof key === "string")),
|
|
267
|
+
"matrix receipt",
|
|
268
|
+
);
|
|
269
|
+
const schema = Object.getOwnPropertyDescriptor(receipt, "schema")?.value;
|
|
270
|
+
const receiptDigest = Object.getOwnPropertyDescriptor(
|
|
271
|
+
receipt,
|
|
272
|
+
"receiptDigest",
|
|
273
|
+
)?.value;
|
|
274
|
+
if (
|
|
275
|
+
schema !== SKILL_TARGET_MATRIX_EVAL_RECEIPT_SCHEMA ||
|
|
276
|
+
typeof receiptDigest !== "string" ||
|
|
277
|
+
!DIGEST_PATTERN.test(receiptDigest)
|
|
278
|
+
) {
|
|
279
|
+
throw failure(
|
|
280
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
281
|
+
"matrix receipt envelope requires a typed receipt and lowercase SHA-256 digest",
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
return JSON.stringify({
|
|
285
|
+
schema: SKILL_EVALUATED_PROMOTION_RECEIPT_ENVELOPE_SCHEMA,
|
|
286
|
+
receiptDigest,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function parseSkillEvaluatedPromotionReceiptEnvelope(value) {
|
|
291
|
+
if (typeof value !== "string" || value.length < 1 || value.length > 4096) {
|
|
292
|
+
throw failure(
|
|
293
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
294
|
+
"evalReceipt must be a bounded matrix receipt envelope",
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
let envelope;
|
|
298
|
+
try {
|
|
299
|
+
envelope = JSON.parse(value);
|
|
300
|
+
} catch (cause) {
|
|
301
|
+
throw failure(
|
|
302
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
303
|
+
"evalReceipt is not a matrix receipt envelope",
|
|
304
|
+
{ cause },
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
assertDataRecord(envelope, ENVELOPE_KEYS, "matrix receipt envelope");
|
|
308
|
+
if (
|
|
309
|
+
envelope.schema !== SKILL_EVALUATED_PROMOTION_RECEIPT_ENVELOPE_SCHEMA ||
|
|
310
|
+
!DIGEST_PATTERN.test(envelope.receiptDigest)
|
|
311
|
+
) {
|
|
312
|
+
throw failure(
|
|
313
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
314
|
+
"evalReceipt envelope is not bound to its typed matrix receipt",
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
if (
|
|
318
|
+
JSON.stringify({
|
|
319
|
+
schema: SKILL_EVALUATED_PROMOTION_RECEIPT_ENVELOPE_SCHEMA,
|
|
320
|
+
receiptDigest: envelope.receiptDigest,
|
|
321
|
+
}) !== value
|
|
322
|
+
) {
|
|
323
|
+
throw failure(
|
|
324
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
325
|
+
"evalReceipt envelope must use the canonical encoding",
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
return deepFreeze(envelope);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
export async function verifySkillEvaluatedPromotionBinding({
|
|
332
|
+
verifier,
|
|
333
|
+
receiptResolver,
|
|
334
|
+
matrixContext,
|
|
335
|
+
authorization,
|
|
336
|
+
candidate,
|
|
337
|
+
state,
|
|
338
|
+
activeContentDigest,
|
|
339
|
+
} = {}) {
|
|
340
|
+
assertDataRecord(
|
|
341
|
+
authorization,
|
|
342
|
+
new Set(["capability", "request"]),
|
|
343
|
+
"authorization",
|
|
344
|
+
);
|
|
345
|
+
const request = verifySkillMutationRequest(authorization.request);
|
|
346
|
+
const envelope = parseSkillEvaluatedPromotionReceiptEnvelope(
|
|
347
|
+
request.receipts.evalReceipt,
|
|
348
|
+
);
|
|
349
|
+
assertDataRecord(matrixContext, MATRIX_CONTEXT_KEYS, "matrix context");
|
|
350
|
+
if (!candidate || !state || typeof activeContentDigest !== "string") {
|
|
351
|
+
throw failure(
|
|
352
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
353
|
+
"candidate, active state, and active content digest are required",
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
const resolved = await resolveMatrixReceipt(
|
|
357
|
+
receiptResolver,
|
|
358
|
+
request.tenantId,
|
|
359
|
+
envelope.receiptDigest,
|
|
360
|
+
);
|
|
361
|
+
const expected = {
|
|
362
|
+
matrixEvalId: matrixContext.matrixEvalId,
|
|
363
|
+
tenantId: request.tenantId,
|
|
364
|
+
skillName: request.skillName,
|
|
365
|
+
candidateId: candidate.candidateId,
|
|
366
|
+
candidateContentDigest: candidate.contentDigest,
|
|
367
|
+
baselineId: matrixContext.baselineId,
|
|
368
|
+
baselineReleaseDigest: state.activeReleaseDigest,
|
|
369
|
+
expectedActiveContentDigest: activeContentDigest,
|
|
370
|
+
expectedActiveRevision: state.revision,
|
|
371
|
+
dependencyLockDigest: candidate.dependencyLockDigest,
|
|
372
|
+
runtimeManifestDigest: candidate.runtimeManifestDigest,
|
|
373
|
+
targetMatrixRoot: candidate.targetMatrixRoot,
|
|
374
|
+
matrixAuthorityRoot: matrixContext.matrixAuthorityRoot,
|
|
375
|
+
planDigest: matrixContext.planDigest,
|
|
376
|
+
decision: "accepted",
|
|
377
|
+
};
|
|
378
|
+
let verified;
|
|
379
|
+
try {
|
|
380
|
+
verified = await verifySkillTargetMatrixEvalReceipt(
|
|
381
|
+
verifier,
|
|
382
|
+
resolved.receipt,
|
|
383
|
+
expected,
|
|
384
|
+
);
|
|
385
|
+
} catch (cause) {
|
|
386
|
+
throw failure(
|
|
387
|
+
"SKILL_EVALUATED_PROMOTION_REJECTED",
|
|
388
|
+
"matrix evaluation receipt did not authorize this exact promotion",
|
|
389
|
+
{ cause },
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
if (verified.receiptDigest !== envelope.receiptDigest) {
|
|
393
|
+
throw failure(
|
|
394
|
+
"SKILL_EVALUATED_PROMOTION_REJECTED",
|
|
395
|
+
"evalReceipt envelope does not identify the verified matrix receipt",
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
return deepFreeze({
|
|
399
|
+
schema: SKILL_EVALUATED_PROMOTION_BINDING_SCHEMA,
|
|
400
|
+
tenantId: verified.tenantId,
|
|
401
|
+
skillName: verified.skillName,
|
|
402
|
+
candidateId: verified.candidateId,
|
|
403
|
+
candidateContentDigest: verified.candidateContentDigest,
|
|
404
|
+
expectedActiveContentDigest: verified.expectedActiveContentDigest,
|
|
405
|
+
expectedActiveRevision: verified.expectedActiveRevision,
|
|
406
|
+
matrixEvalId: verified.matrixEvalId,
|
|
407
|
+
matrixReceiptDigest: verified.receiptDigest,
|
|
408
|
+
decisionCommitmentDigest: verified.decisionCommitmentDigest,
|
|
409
|
+
expiresAt: verified.expiresAt,
|
|
410
|
+
receiptResolution: resolved.resolution,
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
export function createSkillEvaluatedPromotionProvider(options = {}) {
|
|
415
|
+
assertDataRecord(
|
|
416
|
+
options,
|
|
417
|
+
PROVIDER_OPTION_KEYS,
|
|
418
|
+
"evaluated promotion provider options",
|
|
419
|
+
);
|
|
420
|
+
const capturedResolver = captureReceiptResolver(options.receiptResolver);
|
|
421
|
+
const authorityId = normalizeId(options.authorityId, "provider authorityId");
|
|
422
|
+
const handlerArtifactDigest = normalizeDigest(
|
|
423
|
+
options.handlerArtifactDigest,
|
|
424
|
+
"provider handlerArtifactDigest",
|
|
425
|
+
);
|
|
426
|
+
if (
|
|
427
|
+
!Number.isSafeInteger(options.revision) ||
|
|
428
|
+
options.revision < 1 ||
|
|
429
|
+
!options.verifier ||
|
|
430
|
+
typeof options.verifier !== "object" ||
|
|
431
|
+
utilTypes.isProxy(options.verifier)
|
|
432
|
+
) {
|
|
433
|
+
throw failure(
|
|
434
|
+
"SKILL_EVALUATED_PROMOTION_INVALID",
|
|
435
|
+
"evaluated promotion provider revision or verifier is invalid",
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
const receiptResolver = Object.freeze({
|
|
439
|
+
...capturedResolver.descriptor,
|
|
440
|
+
resolve: capturedResolver.resolve,
|
|
441
|
+
});
|
|
442
|
+
const verifier = options.verifier;
|
|
443
|
+
Object.freeze(verifier);
|
|
444
|
+
const provider = {
|
|
445
|
+
schema: SKILL_EVALUATED_PROMOTION_PROVIDER_SCHEMA,
|
|
446
|
+
authorityId,
|
|
447
|
+
handlerArtifactDigest,
|
|
448
|
+
revision: options.revision,
|
|
449
|
+
async verify(input = {}) {
|
|
450
|
+
assertDataRecord(
|
|
451
|
+
input,
|
|
452
|
+
PROVIDER_INPUT_KEYS,
|
|
453
|
+
"evaluated promotion provider input",
|
|
454
|
+
);
|
|
455
|
+
return verifySkillEvaluatedPromotionBinding({
|
|
456
|
+
...input,
|
|
457
|
+
receiptResolver,
|
|
458
|
+
verifier,
|
|
459
|
+
});
|
|
460
|
+
},
|
|
461
|
+
};
|
|
462
|
+
PROVIDER_INSTANCES.add(provider);
|
|
463
|
+
return Object.freeze(provider);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export function captureSkillEvaluatedPromotionProvider(value) {
|
|
467
|
+
if (!value || !PROVIDER_INSTANCES.has(value)) {
|
|
468
|
+
throw failure(
|
|
469
|
+
"SKILL_EVALUATED_PROMOTION_PROVIDER_REQUIRED",
|
|
470
|
+
"a branded evaluated promotion provider is required",
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
assertDataRecord(value, PROVIDER_KEYS, "evaluated promotion provider");
|
|
474
|
+
return Object.freeze({
|
|
475
|
+
schema: value.schema,
|
|
476
|
+
authorityId: value.authorityId,
|
|
477
|
+
handlerArtifactDigest: value.handlerArtifactDigest,
|
|
478
|
+
revision: value.revision,
|
|
479
|
+
verify: value.verify.bind(value),
|
|
480
|
+
});
|
|
481
|
+
}
|