chainlesschain 0.166.102 → 0.166.104
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 +1 -1
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/assets/{AIOps-CyHIMEd8.js → AIOps-Bah3HREy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-vuNxDpHm.js → ActionButton-DY2aeZMc.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-D0quEM0q.js → Analytics-BFly8Xaa.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-xRSVpbCs.js → AppLayout-dp0Zz-JM.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-ktfVAZBC.js → Artifacts-DcIg09ai.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-UJW6maH4.js → Audit-DkN-lsjZ.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BYrfdCoT.js → BackgroundAgents-BjzgusLx.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-IBgsJ7BK.js → Backup-CU8S6qu9.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-BmP8_zxy.js → BaseInput-B1pC2gjL.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-urkw8_BF.js → Chat-B6xFp6gD.js} +6 -6
- package/src/assets/web-panel/assets/{ChatBubbleRenderer-Cw44zZbh.js → ChatBubbleRenderer-DxNCLZ_X.js} +1 -1
- package/src/assets/web-panel/assets/{Checkbox-CYboo-__.js → Checkbox-QHw7Vc4U.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-DaqR_Ay8.js → Codegen-gdecsfjg.js} +1 -1
- package/src/assets/web-panel/assets/{Col-04BSIj_z.js → Col-B0_JmAmc.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DxFk7Trv.js → Community-DRCcP5xR.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-mjgWlMCB.js → Compact-DZtoGzhX.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CC5ee7QV.js → Compliance-BfNTvEnT.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BK4BhHZd.js → Cowork-CDXTLm84.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-CP6jAxq0.js → Cron-Big35CbN.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-DJPaViZS.js → Crosschain-C8ArrAVr.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BTLxkuOj.js → DID-D_77BI2O.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-Djkiqh3d.js → Dashboard-D2SxTzEp.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-t_eUhqom.js → Dropdown-mR1-b9ud.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-7w6USx_J.js → EmailListRenderer-DPl7TE1c.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-mU5IHEk5.js → EvolutionSettings-BxRYLRSH.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-BCh-VBBC.js → FamilyGuardDashboard-rnGtXJ5Z.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-Be_VpjI2.js → Federation-BpxenYK8.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-D_lzQ7PI.js → FormItemContext-Cz1kDf6l.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-LYu3KapV.js → GenericCardRenderer-CGV3KN6U.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BBeF-PP4.js → Git-CIRP4UTx.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CoF8Kzg7.js → Governance-DX4r8Vmt.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-C4DLMnXS.js → Inference-DQKk02Hl.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-B2mlNewk.js → KnowledgeGraph-DdD6J-By.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-DMZ_44Ya.js → Logs-DA2w-1_m.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-Ck7Iv_9e.js → MarkdownRenderer-C9aSGETh.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-BqDzTew_.js → Marketplace-BsJ6_6KW.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-BbwSbDN9.js → McpTools-_6k30z6u.js} +2 -2
- package/src/assets/web-panel/assets/{Memory-DAaTWgrm.js → Memory-C0_dYY0A.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-BjbTGxoR.js → MobileBridge-CCTnVqiC.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-DMODOBr-.js → MobileProjects-RZdxDSwC.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DT9N2rCs.js → Mtc-D4Ys8lvX.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-DagMfUVv.js → MtcAudit-BKTC--a2.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-C1BKP6nM.js → Multisig-CGR1qOe1.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-B5LFh72i.js → NLProgramming-hKKD4qWb.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Q77V3ltW.js → Notes-pCn7Ec40.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-HxdpNIBs.js → NotificationSettings-B9eEJXEs.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-Dc0DpvBH.js → OrderTableRenderer-CmJuhaT2.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-QL3NZ7uW.js → Organization-CcQbrnwW.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-B_gqOKho.js → Overflow-HmD4Mn72.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BBJubU8Z.js → P2P-B7LIgx5H.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CFnGd-2E.js → PdhVaultBrowser-CXiHnBfX.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BKkznIUM.js → Permissions-CQRI3y_l.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-DYK7ZAcd.js → PersonalDataHub-1EeHmsy5.js} +4 -4
- package/src/assets/web-panel/assets/{Pipeline-CoeKpjoN.js → Pipeline-BFyoIdn8.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-Diw4G-92.js → Privacy-BxWthXMF.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-CHBOFkma.js → ProjectInit-DfigBilu.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-BJIsgdOf.js → ProjectSettings-CFmIcVc-.js} +2 -2
- package/src/assets/web-panel/assets/Projects-CR7H59v3.js +1 -0
- package/src/assets/web-panel/assets/{Providers-o8QCimor.js → Providers-2ulom-76.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-z2W-zvhW.js → QrScannerModal-BwhO07b_.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-_yubhsna.js → QuickAsk-_Wg34OwF.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-CucgJwih.js → Recommend-D_jq6Svg.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-EzfIIRg1.js → RemoteSession-BlzvEfsa.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-_shttE67.js → Reputation-9CTXHfL4.js} +1 -1
- package/src/assets/web-panel/assets/{Row-DQA_S8-9.js → Row-DlCYCN-t.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BOqWawXT.js → RssFeed-BvlInFCH.js} +3 -3
- package/src/assets/web-panel/assets/{Search-Dx1v2xOq.js → Search-CfaUzKuL.js} +1 -1
- package/src/assets/web-panel/assets/{Security-Bt4HHsT4.js → Security-bAWgLyve.js} +4 -4
- package/src/assets/web-panel/assets/{Services-sruHiQ-r.js → Services-C4LOGACW.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-CiBxvmOJ.js → Skeleton-Dd0Uwh3_.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-De9qKODU.js → Skills-ZYF1kYCU.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-B_6yn8Wp.js → Sla-DpsmIaEo.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-C2CafExS.js → SpeechSettings-BBXoJ4yc.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Dhh3Qmb0.js → SyncSettings-SOnROi2Y.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Mvo5mTWm.js → Tasks-HFA_ZlDk.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D7WVTQQy.js → Templates-fsK-RCEc.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-7ur9Yfxd.js → Tenant-CuqYxamb.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BgzrOA6k.js → Terminal-GKlI2R5F.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-Dco20pT1.js → TimelineRenderer-DMDMHLeY.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-hN6qBPag.js → Tokens-BoV60rh3.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-C4f_twAM.js → Trigger-CE344-Ws.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-Wf1SMypp.js → Trust-DENwgkVc.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-DUXSyg3N.js → UkeySign-FrcM7yfm.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-BvqsJaL0.js → VideoEditing-DAY9WaC2.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-CgAbcjKl.js → Wallet-BuUR5i82.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DaLT0W3s.js → WebAuthn-nfSQuq85.js} +2 -2
- package/src/assets/web-panel/assets/{WorkflowEditor-CQqAXoaS.js → WorkflowEditor-DHhPOp9l.js} +1 -1
- package/src/assets/web-panel/assets/{chat-BhlohFTB.js → chat-C4nsLzYy.js} +1 -1
- package/src/assets/web-panel/assets/{colors-D7HqXIL8.js → colors-BwXH0Wjn.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Bqk4FCLY.js → compact-item-uApFG30S.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CEmWrWf0.js → createContext-BpyYs4fe.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-Bk6HGn3N.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CDY0pFi2.js → hasIn-MXCLi00p.js} +1 -1
- package/src/assets/web-panel/assets/{index-e9oCy7_4.js → index-1LxX2IwJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-DEzL7s7P.js → index-61CBBrHE.js} +1 -1
- package/src/assets/web-panel/assets/{index-D0nfNmbq.js → index-B0P1Z_oa.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiLu-ImR.js → index-B7jojVc7.js} +1 -1
- package/src/assets/web-panel/assets/{index-CqK0J4Sj.js → index-BEGMfaOo.js} +1 -1
- package/src/assets/web-panel/assets/{index-aBHlgMrq.js → index-BOhjapd5.js} +1 -1
- package/src/assets/web-panel/assets/{index-DPBoWNwq.js → index-BaBwXpAp.js} +1 -1
- package/src/assets/web-panel/assets/index-Bb1LPYdi.js +1 -0
- package/src/assets/web-panel/assets/{index-BxXFRLTZ.js → index-Btv--Nnt.js} +1 -1
- package/src/assets/web-panel/assets/index-C-FsTuFG.js +1 -0
- package/src/assets/web-panel/assets/{index-BxYO6nde.js → index-CF0bUOP4.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGKRAO61.js → index-CNjUPfJP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkjgSHVz.js → index-CRmNdEk_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CrsM-oiD.js → index-C_oOpXhP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BNrvBWDS.js → index-ChUTKrOq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CYcjOnDX.js → index-CiIpIYhs.js} +1 -1
- package/src/assets/web-panel/assets/{index-C02yDu4f.js → index-CwVvk2i7.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmKdCWq1.js → index-D3_tj06B.js} +1 -1
- package/src/assets/web-panel/assets/{index-CkqBoCiu.js → index-DE4W4vLO.js} +3 -3
- package/src/assets/web-panel/assets/{index-B8L3_-sG.js → index-DLxKx5_J.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dwob5XoD.js → index-DTXi_gQh.js} +1 -1
- package/src/assets/web-panel/assets/{index-DuMt3ewl.js → index-Daco83me.js} +1 -1
- package/src/assets/web-panel/assets/{index-DpI1LqJX.js → index-DffWVpZv.js} +1 -1
- package/src/assets/web-panel/assets/{index-lBAbMOzg.js → index-Dkncxel3.js} +1 -1
- package/src/assets/web-panel/assets/{index-DRcDWMwP.js → index-Dn12gJJU.js} +1 -1
- package/src/assets/web-panel/assets/{index-CVrwozwH.js → index-Dt-nq2eF.js} +1 -1
- package/src/assets/web-panel/assets/{index-C3opQg47.js → index-Du01X9N9.js} +1 -1
- package/src/assets/web-panel/assets/{index-o_lc3eww.js → index-DucLR6YX.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cur88hoN.js → index-Gz2rGWef.js} +1 -1
- package/src/assets/web-panel/assets/{index-XErJQ1yF.js → index-IvgszJ3C.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuKGuH_y.js → index-S80LLjdx.js} +1 -1
- package/src/assets/web-panel/assets/{index-Chxt0t-A.js → index-WKbnwbKa.js} +1 -1
- package/src/assets/web-panel/assets/{index-1HBam9t1.js → index-XHBXtvqp.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXRooi-O.js → index-nn22NSDK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BHGOdvOQ.js → index-pCIAE2yS.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cf1ha8l0.js → index-pRpMLhMt.js} +1 -1
- package/src/assets/web-panel/assets/{index-6f6n0KFR.js → index-pgHGBAoF.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPmRkxeX.js → index-ugIUt5TL.js} +1 -1
- package/src/assets/web-panel/assets/{index-C9mvnSii.js → index-xLGf7f9K.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CIeEUxIN.js → initDefaultProps-C58CkKEo.js} +1 -1
- package/src/assets/web-panel/assets/{motion-IPIj1ZtP.js → motion-BLWPO2NV.js} +1 -1
- package/src/assets/web-panel/assets/{move-BfSeXZ-f.js → move-BgrFMwYp.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-DX03-Xp4.js → mtc-parser-Cq2AuGzl.js} +1 -1
- package/src/assets/web-panel/assets/{omit-z9EannfX.js → omit-Bb-9L7if.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-DXKmRkqZ.js → pickAttrs-vLmOxYr1.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-k2HV7cIU.js → placementArrow-BNySU_dJ.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-bX7CsyWy.js → responsiveObserve-xnbwagnm.js} +1 -1
- package/src/assets/web-panel/assets/{slide-NskjQLbJ.js → slide-BccbY5Cn.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-B3IoG-Er.js → statusUtils-DOp9d2-w.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-DHv_UilX.js → styleChecker-Bu1w6ho9.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DEqGB5Ng.js → useFlexGapSupport-ZsUOrVdL.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Bl9CbrqZ.js → useFs-C0zpzKtO.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-O-Ukv93M.js → usePersonalDataHub-DO1OdgXK.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-hGCHTaZt.js → vnode-jTIRyhR5.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BWhIVeKQ.js → zoom-DKvS7-Qs.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/commands/agent.js +56 -20
- package/src/commands/ask.js +6 -4
- package/src/commands/batch.js +17 -12
- package/src/commands/eval.js +24 -8
- package/src/commands/team.js +28 -19
- package/src/data/changelog.json +26 -0
- package/src/harness/mcp-client.js +187 -26
- package/src/harness/prompt-compressor.js +2 -0
- package/src/lib/advisor-runtime.js +4 -2
- package/src/lib/agent-ipc-bus.js +2 -0
- package/src/lib/background-agent-keeper-client.js +3 -0
- package/src/lib/background-session-transport.js +21 -5
- package/src/lib/browser-automation.js +4 -0
- package/src/lib/cc-android-bridge.js +4 -0
- package/src/lib/chat-core.js +11 -9
- package/src/lib/cloud/cloud-client.js +10 -1
- package/src/lib/cowork-adapter.js +4 -3
- package/src/lib/decision-layer/providers.js +16 -11
- package/src/lib/decision-layer/runtime.js +180 -10
- package/src/lib/direct-model-usage.js +34 -0
- package/src/lib/evolution/agent-evolution-ingress.js +63 -7
- package/src/lib/evolution/evolution-evidence-artifact-adapter.js +10 -0
- package/src/lib/evolution/evolution-evidence-projector.js +46 -7
- package/src/lib/evolution/governed-hub-llm.js +31 -16
- package/src/lib/evolution/governed-hub-resolver.js +4 -0
- package/src/lib/evolution/governed-skill-synthesis-process-grader.js +4 -0
- package/src/lib/evolution/skill-decision-projection.js +211 -0
- package/src/lib/evolution/skill-retrieval-revocation-authority.js +17 -2
- package/src/lib/evomap-client.js +14 -2
- package/src/lib/formal-budget-authority.js +191 -59
- package/src/lib/formal-budget-contract.js +7 -13
- package/src/lib/formal-budget-errors.js +31 -0
- package/src/lib/formal-budget-lineage-registry.js +612 -0
- package/src/lib/formal-budget-provider-scope.js +143 -0
- package/src/lib/formal-budget-transport.js +235 -100
- package/src/lib/gateway-client-resilience.js +5 -0
- package/src/lib/hub-llm-client.js +25 -16
- package/src/lib/llm-connection-probe.js +17 -10
- package/src/lib/llm-providers.js +4 -1
- package/src/lib/model-failure-policy.js +2 -0
- package/src/lib/plugin-runtime/marketplace-network.js +9 -5
- package/src/lib/process-execution-broker/credential-agent.js +7 -2
- package/src/lib/process-execution-broker/credential-transport.js +4 -0
- package/src/lib/process-execution-broker/index.js +8 -0
- package/src/lib/provider-stream.js +28 -13
- package/src/lib/sandbox-egress-worker.js +3 -0
- package/src/lib/skill-loader.js +16 -0
- package/src/lib/stream-retry.js +2 -0
- package/src/lib/sub-agent-context.js +6 -3
- package/src/lib/web-fetch.js +2 -0
- package/src/lib/web-search.js +5 -0
- package/src/repl/agent-repl.js +86 -7
- package/src/runtime/agent-core.js +141 -22
- package/src/runtime/headless-runner.js +212 -22
- package/src/runtime/headless-stream.js +189 -25
- package/src/runtime/mcp-config.js +26 -17
- package/src/runtime/mcp-tool-search.js +44 -14
- package/src/assets/web-panel/assets/Projects-GJjItXIk.js +0 -1
- package/src/assets/web-panel/assets/devWarning-YPX_TU7w.js +0 -1
- package/src/assets/web-panel/assets/index-D53szVZQ.js +0 -1
- package/src/assets/web-panel/assets/index-Ub2nJbV2.js +0 -1
|
@@ -5,6 +5,7 @@ import evolutionRun from "@chainlesschain/session-core/evolution-run";
|
|
|
5
5
|
import { EvolutionEvidenceArtifactAdapter } from "./evolution-evidence-artifact-adapter.js";
|
|
6
6
|
import {
|
|
7
7
|
EVOLUTION_AGENT_MODEL_PROJECTION_RULESET_DIGEST,
|
|
8
|
+
EVOLUTION_SKILL_DECISION_PROJECTION_RULESET_DIGEST,
|
|
8
9
|
EVOLUTION_PROJECTION_RULESET_DIGEST,
|
|
9
10
|
} from "./evolution-evidence-projector.js";
|
|
10
11
|
import { EvolutionRunLedgerAdapter } from "./evolution-run-ledger-adapter.js";
|
|
@@ -15,6 +16,10 @@ import {
|
|
|
15
16
|
snapshotAgentModelRequest,
|
|
16
17
|
buildAgentModelRequest,
|
|
17
18
|
} from "./agent-model-projection.js";
|
|
19
|
+
import {
|
|
20
|
+
snapshotSkillDecisionRequest,
|
|
21
|
+
buildSkillDecisionPayload,
|
|
22
|
+
} from "./skill-decision-projection.js";
|
|
18
23
|
|
|
19
24
|
const { EVOLUTION_RUN_EVENT_SCHEMA, EVENT_TYPES } = evolutionRun;
|
|
20
25
|
|
|
@@ -265,6 +270,7 @@ export function createAgentEvolutionIngress({
|
|
|
265
270
|
options = {},
|
|
266
271
|
modelRequest = null,
|
|
267
272
|
cacheRecord = false,
|
|
273
|
+
skillDecisionRequest = null,
|
|
268
274
|
) =>
|
|
269
275
|
guardIngress(
|
|
270
276
|
serialize(async () => {
|
|
@@ -304,7 +310,7 @@ export function createAgentEvolutionIngress({
|
|
|
304
310
|
),
|
|
305
311
|
responseEvent: clone(lastModelResponse.event),
|
|
306
312
|
}
|
|
307
|
-
: (modelRequest ?? clone(evidence));
|
|
313
|
+
: (skillDecisionRequest?.payload ?? modelRequest ?? clone(evidence));
|
|
308
314
|
const sourceEnvelope = await issueSourceEnvelope(
|
|
309
315
|
Object.freeze({
|
|
310
316
|
schema: AGENT_EVOLUTION_INGRESS_SCHEMA,
|
|
@@ -321,12 +327,17 @@ export function createAgentEvolutionIngress({
|
|
|
321
327
|
payload,
|
|
322
328
|
};
|
|
323
329
|
const persisted =
|
|
324
|
-
|
|
325
|
-
? await
|
|
326
|
-
: await EvolutionEvidenceArtifactAdapter.prototype.projectAndPersistAgentModelRequest.call(
|
|
330
|
+
skillDecisionRequest !== null
|
|
331
|
+
? await EvolutionEvidenceArtifactAdapter.prototype.projectAndPersistSkillDecisionRequest.call(
|
|
327
332
|
evidenceAdapter,
|
|
328
333
|
projectionInput,
|
|
329
|
-
)
|
|
334
|
+
)
|
|
335
|
+
: modelRequest === null
|
|
336
|
+
? await evidenceAdapter.projectAndPersist(projectionInput)
|
|
337
|
+
: await EvolutionEvidenceArtifactAdapter.prototype.projectAndPersistAgentModelRequest.call(
|
|
338
|
+
evidenceAdapter,
|
|
339
|
+
projectionInput,
|
|
340
|
+
);
|
|
330
341
|
if (
|
|
331
342
|
persisted?.tenantId !== descriptor.tenantId ||
|
|
332
343
|
persisted.evidenceId == null ||
|
|
@@ -353,6 +364,13 @@ export function createAgentEvolutionIngress({
|
|
|
353
364
|
evidenceKind: kind,
|
|
354
365
|
occurredAt,
|
|
355
366
|
derivationManifestDigest: persisted.manifest.digest,
|
|
367
|
+
...(skillDecisionRequest === null
|
|
368
|
+
? {}
|
|
369
|
+
: {
|
|
370
|
+
decisionId: skillDecisionRequest.decisionId,
|
|
371
|
+
requestDigest: skillDecisionRequest.requestDigest,
|
|
372
|
+
candidateSetDigest: skillDecisionRequest.candidateSetDigest,
|
|
373
|
+
}),
|
|
356
374
|
},
|
|
357
375
|
});
|
|
358
376
|
if (kind === "model-input") {
|
|
@@ -370,7 +388,8 @@ export function createAgentEvolutionIngress({
|
|
|
370
388
|
eventId,
|
|
371
389
|
artifact: persisted,
|
|
372
390
|
});
|
|
373
|
-
if (modelRequest === null
|
|
391
|
+
if (modelRequest === null && skillDecisionRequest === null)
|
|
392
|
+
return appended;
|
|
374
393
|
// Resolve the published manifest and every attested component afresh.
|
|
375
394
|
// The prototype call requires the real adapter's private state; an
|
|
376
395
|
// instance-shaped facade cannot mint model-visible input.
|
|
@@ -383,7 +402,9 @@ export function createAgentEvolutionIngress({
|
|
|
383
402
|
resolved.verification.verified !== true ||
|
|
384
403
|
resolved.verification.tenantId !== descriptor.tenantId ||
|
|
385
404
|
resolved.bundle.modelProjection.rulesetDigest !==
|
|
386
|
-
|
|
405
|
+
(skillDecisionRequest === null
|
|
406
|
+
? EVOLUTION_AGENT_MODEL_PROJECTION_RULESET_DIGEST
|
|
407
|
+
: EVOLUTION_SKILL_DECISION_PROJECTION_RULESET_DIGEST) ||
|
|
387
408
|
resolved.bundle.modelProjection.evidenceId !== persisted.evidenceId
|
|
388
409
|
) {
|
|
389
410
|
throw new Error("Agent model projection readback is unbound");
|
|
@@ -396,6 +417,26 @@ export function createAgentEvolutionIngress({
|
|
|
396
417
|
throw new Error("Agent model projection Run frontier changed");
|
|
397
418
|
}
|
|
398
419
|
if (admissionFailure !== null) throw admissionFailure;
|
|
420
|
+
if (skillDecisionRequest !== null) {
|
|
421
|
+
return Object.freeze({
|
|
422
|
+
payload: buildSkillDecisionPayload(
|
|
423
|
+
skillDecisionRequest.payload,
|
|
424
|
+
resolved.bundle.modelProjection,
|
|
425
|
+
),
|
|
426
|
+
receipt: Object.freeze({
|
|
427
|
+
tenantId: descriptor.tenantId,
|
|
428
|
+
runId: descriptor.runId,
|
|
429
|
+
eventId,
|
|
430
|
+
evidenceId: persisted.evidenceId,
|
|
431
|
+
requestDigest: skillDecisionRequest.requestDigest,
|
|
432
|
+
candidateSetDigest: skillDecisionRequest.candidateSetDigest,
|
|
433
|
+
manifestDigest: persisted.manifest.digest,
|
|
434
|
+
projectionDigest:
|
|
435
|
+
resolved.bundle.modelProjection.projectionDigest,
|
|
436
|
+
rulesetDigest: resolved.bundle.modelProjection.rulesetDigest,
|
|
437
|
+
}),
|
|
438
|
+
});
|
|
439
|
+
}
|
|
399
440
|
return buildAgentModelRequest(
|
|
400
441
|
modelRequest,
|
|
401
442
|
resolved.bundle.modelProjection,
|
|
@@ -522,6 +563,21 @@ export function createAgentEvolutionIngress({
|
|
|
522
563
|
return response;
|
|
523
564
|
},
|
|
524
565
|
start: () => guardIngress(serialize(() => appendStarted())),
|
|
566
|
+
prepareSkillDecisionRequest: (request) => {
|
|
567
|
+
if (admissionFailure !== null) return Promise.reject(admissionFailure);
|
|
568
|
+
let snapshot;
|
|
569
|
+
try {
|
|
570
|
+
snapshot = snapshotSkillDecisionRequest(request);
|
|
571
|
+
if (snapshot.binding.tenantId !== descriptor.tenantId)
|
|
572
|
+
throw new TypeError(
|
|
573
|
+
"Skill decision request belongs to another tenant",
|
|
574
|
+
);
|
|
575
|
+
} catch (error) {
|
|
576
|
+
admissionFailure = ingressFailure(error);
|
|
577
|
+
return Promise.reject(admissionFailure);
|
|
578
|
+
}
|
|
579
|
+
return ingest("skill-decision-input", null, {}, null, false, snapshot);
|
|
580
|
+
},
|
|
525
581
|
prepareModelRequest: (request) => {
|
|
526
582
|
if (admissionFailure !== null) return Promise.reject(admissionFailure);
|
|
527
583
|
let snapshot;
|
|
@@ -340,6 +340,7 @@ export class EvolutionEvidenceArtifactAdapter {
|
|
|
340
340
|
#ttlMs;
|
|
341
341
|
#project;
|
|
342
342
|
#projectAgentModel;
|
|
343
|
+
#projectSkillDecision;
|
|
343
344
|
#verify;
|
|
344
345
|
#ports;
|
|
345
346
|
#resolveManifestRef;
|
|
@@ -385,6 +386,11 @@ export class EvolutionEvidenceArtifactAdapter {
|
|
|
385
386
|
"projectAgentModelRequest",
|
|
386
387
|
"projector",
|
|
387
388
|
);
|
|
389
|
+
this.#projectSkillDecision = captureMethod(
|
|
390
|
+
projector,
|
|
391
|
+
"projectSkillDecisionRequest",
|
|
392
|
+
"projector",
|
|
393
|
+
);
|
|
388
394
|
this.#verify = captureMethod(bundleVerifier, "verify", "bundleVerifier");
|
|
389
395
|
this.#ports = artifactPorts;
|
|
390
396
|
this.#resolveManifestRef =
|
|
@@ -411,6 +417,10 @@ export class EvolutionEvidenceArtifactAdapter {
|
|
|
411
417
|
return this.#persist(await this.#projectAgentModel(input));
|
|
412
418
|
}
|
|
413
419
|
|
|
420
|
+
async projectAndPersistSkillDecisionRequest(input) {
|
|
421
|
+
return this.#persist(await this.#projectSkillDecision(input));
|
|
422
|
+
}
|
|
423
|
+
|
|
414
424
|
async #persist(bundle) {
|
|
415
425
|
const verification = await this.#verify(bundle);
|
|
416
426
|
if (
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
projectAgentOpaqueTransportBlock,
|
|
15
15
|
snapshotAgentModelRequest,
|
|
16
16
|
} from "./agent-model-projection.js";
|
|
17
|
+
import { snapshotSkillDecisionPayload } from "./skill-decision-projection.js";
|
|
17
18
|
import {
|
|
18
19
|
createEvidenceJsonTextBoundary,
|
|
19
20
|
EVIDENCE_JSON_POLICY,
|
|
@@ -523,7 +524,24 @@ export const EVOLUTION_AGENT_MODEL_PROJECTION_RULESET_DIGEST = `sha256:${createH
|
|
|
523
524
|
"utf8",
|
|
524
525
|
)
|
|
525
526
|
.digest("hex")}`;
|
|
527
|
+
const SKILL_DECISION_RULESET = Object.freeze({
|
|
528
|
+
...AGENT_MODEL_RULESET_V2,
|
|
529
|
+
schema: "chainlesschain.evolution-skill-decision-projection-rules/v1",
|
|
530
|
+
version: 1,
|
|
531
|
+
protocol: "skill-routing-state-and-questions/v1",
|
|
532
|
+
maxInputBytes: 256 * 1024,
|
|
533
|
+
});
|
|
534
|
+
export const EVOLUTION_SKILL_DECISION_PROJECTION_RULESET_DIGEST = `sha256:${createHash(
|
|
535
|
+
"sha256",
|
|
536
|
+
)
|
|
537
|
+
.update(
|
|
538
|
+
`${SKILL_DECISION_RULESET.schema}\0${JSON.stringify(SKILL_DECISION_RULESET)}`,
|
|
539
|
+
"utf8",
|
|
540
|
+
)
|
|
541
|
+
.digest("hex")}`;
|
|
542
|
+
|
|
526
543
|
const SUPPORTED_RULESETS = new Map([
|
|
544
|
+
[EVOLUTION_SKILL_DECISION_PROJECTION_RULESET_DIGEST, SKILL_DECISION_RULESET],
|
|
527
545
|
[RULESET_DIGEST, RULESET],
|
|
528
546
|
[RAW_RULESET_V3_DIGEST, RAW_RULESET_V3],
|
|
529
547
|
[AGENT_MODEL_RULESET_V1_DIGEST, AGENT_MODEL_RULESET_V1],
|
|
@@ -601,7 +619,8 @@ const AGENT_VALUE_PATTERNS = Object.freeze([
|
|
|
601
619
|
]);
|
|
602
620
|
|
|
603
621
|
function valuePatterns(ruleset) {
|
|
604
|
-
return ruleset ===
|
|
622
|
+
return ruleset === SKILL_DECISION_RULESET ||
|
|
623
|
+
ruleset === AGENT_MODEL_RULESET ||
|
|
605
624
|
ruleset === AGENT_MODEL_RULESET_V2 ||
|
|
606
625
|
ruleset === AGENT_MODEL_RULESET_V1
|
|
607
626
|
? AGENT_VALUE_PATTERNS
|
|
@@ -3101,6 +3120,18 @@ function validateBundleIntegrity(bundle) {
|
|
|
3101
3120
|
);
|
|
3102
3121
|
}
|
|
3103
3122
|
if (model.content !== null) {
|
|
3123
|
+
if (ruleset === SKILL_DECISION_RULESET) {
|
|
3124
|
+
snapshotSkillDecisionPayload(model.content);
|
|
3125
|
+
if (
|
|
3126
|
+
model.truncated ||
|
|
3127
|
+
(model.redactionSummary.byType["content-truncation"] ?? 0) > 0
|
|
3128
|
+
) {
|
|
3129
|
+
throw projectionError(
|
|
3130
|
+
EVOLUTION_PROJECTION_INVALID_CODE,
|
|
3131
|
+
"Skill decision projection cannot be truncated",
|
|
3132
|
+
);
|
|
3133
|
+
}
|
|
3134
|
+
}
|
|
3104
3135
|
if (
|
|
3105
3136
|
ruleset === AGENT_MODEL_RULESET ||
|
|
3106
3137
|
ruleset === AGENT_MODEL_RULESET_V2 ||
|
|
@@ -3368,6 +3399,10 @@ export class EvolutionEvidenceProjector {
|
|
|
3368
3399
|
return this.#project(input, AGENT_MODEL_RULESET);
|
|
3369
3400
|
}
|
|
3370
3401
|
|
|
3402
|
+
projectSkillDecisionRequest(input) {
|
|
3403
|
+
return this.#project(input, SKILL_DECISION_RULESET);
|
|
3404
|
+
}
|
|
3405
|
+
|
|
3371
3406
|
async #project(input, ruleset) {
|
|
3372
3407
|
assertExactRecord(input, INPUT_KEYS, "evidence projection input");
|
|
3373
3408
|
if (
|
|
@@ -3381,9 +3416,11 @@ export class EvolutionEvidenceProjector {
|
|
|
3381
3416
|
);
|
|
3382
3417
|
}
|
|
3383
3418
|
const payload =
|
|
3384
|
-
ruleset ===
|
|
3385
|
-
?
|
|
3386
|
-
:
|
|
3419
|
+
ruleset === SKILL_DECISION_RULESET
|
|
3420
|
+
? snapshotSkillDecisionPayload(input.payload)
|
|
3421
|
+
: ruleset === AGENT_MODEL_RULESET
|
|
3422
|
+
? snapshotAgentModelRequest(input.payload)
|
|
3423
|
+
: cloneCanonical(input.payload);
|
|
3387
3424
|
const sourceInputDigest = digest(
|
|
3388
3425
|
payload,
|
|
3389
3426
|
"chainlesschain.evolution-raw-plaintext/v2",
|
|
@@ -3627,9 +3664,11 @@ export class EvolutionEvidenceProjector {
|
|
|
3627
3664
|
const modelProjection = buildModelProjection(
|
|
3628
3665
|
rawRecord,
|
|
3629
3666
|
sanitized,
|
|
3630
|
-
ruleset ===
|
|
3631
|
-
?
|
|
3632
|
-
:
|
|
3667
|
+
ruleset === SKILL_DECISION_RULESET
|
|
3668
|
+
? EVOLUTION_SKILL_DECISION_PROJECTION_RULESET_DIGEST
|
|
3669
|
+
: ruleset === AGENT_MODEL_RULESET
|
|
3670
|
+
? EVOLUTION_AGENT_MODEL_PROJECTION_RULESET_DIGEST
|
|
3671
|
+
: RAW_RULESET_V3_DIGEST,
|
|
3633
3672
|
);
|
|
3634
3673
|
const trustedSanitized = source.compilable
|
|
3635
3674
|
? sanitizePayload(
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { types } from "node:util";
|
|
3
3
|
import { prepareGovernedModelTurn } from "./governed-model-turn.js";
|
|
4
|
+
import {
|
|
5
|
+
providerFetch,
|
|
6
|
+
requireUnscopedModelTransport,
|
|
7
|
+
} from "../formal-budget-provider-scope.js";
|
|
4
8
|
|
|
5
9
|
const { createAuthenticatedEvolutionModelClient } = createRequire(
|
|
6
10
|
import.meta.url,
|
|
@@ -97,21 +101,25 @@ function captureHubTransport(llm, sdk) {
|
|
|
97
101
|
const signal = options.signal
|
|
98
102
|
? AbortSignal.any([controller.signal, options.signal])
|
|
99
103
|
: controller.signal;
|
|
100
|
-
const response = await
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
104
|
+
const response = await providerFetch(
|
|
105
|
+
`${baseUrl}/api/chat`,
|
|
106
|
+
{
|
|
107
|
+
method: "POST",
|
|
108
|
+
headers: { "Content-Type": "application/json" },
|
|
109
|
+
redirect: "error",
|
|
110
|
+
signal,
|
|
111
|
+
body: JSON.stringify({
|
|
112
|
+
model,
|
|
113
|
+
messages,
|
|
114
|
+
stream: false,
|
|
115
|
+
options: {
|
|
116
|
+
temperature: options.temperature ?? 0.2,
|
|
117
|
+
...(options.numCtx ? { num_ctx: options.numCtx } : {}),
|
|
118
|
+
},
|
|
119
|
+
}),
|
|
120
|
+
},
|
|
121
|
+
fetchImpl,
|
|
122
|
+
);
|
|
115
123
|
if (!response.ok)
|
|
116
124
|
throw new Error(
|
|
117
125
|
`Hub Ollama request failed: HTTP ${response.status}`,
|
|
@@ -202,6 +210,7 @@ function captureHubTransport(llm, sdk) {
|
|
|
202
210
|
);
|
|
203
211
|
},
|
|
204
212
|
async chat(messages, options) {
|
|
213
|
+
requireUnscopedModelTransport();
|
|
205
214
|
const result = await chat(messages, options);
|
|
206
215
|
const text =
|
|
207
216
|
result?.content ??
|
|
@@ -233,7 +242,13 @@ function captureHubTransport(llm, sdk) {
|
|
|
233
242
|
},
|
|
234
243
|
};
|
|
235
244
|
}
|
|
236
|
-
return {
|
|
245
|
+
return {
|
|
246
|
+
assertIdentity() {},
|
|
247
|
+
chat(messages, options) {
|
|
248
|
+
requireUnscopedModelTransport();
|
|
249
|
+
return llm.chat(messages, options);
|
|
250
|
+
},
|
|
251
|
+
};
|
|
237
252
|
}
|
|
238
253
|
|
|
239
254
|
// A scoped wrapper preserves the Hub's independent local/cloud consent check.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { prepareGovernedModelTurn } from "./governed-model-turn.js";
|
|
2
|
+
import { requireUnscopedModelTransport } from "../formal-budget-provider-scope.js";
|
|
2
3
|
import {
|
|
3
4
|
captureGovernedHubSdkPorts,
|
|
4
5
|
createGovernedHubLlm,
|
|
@@ -48,6 +49,9 @@ function captureEmbeddingTransport(stage, sdk) {
|
|
|
48
49
|
);
|
|
49
50
|
},
|
|
50
51
|
async embed(profile) {
|
|
52
|
+
// Neither arbitrary embedding callbacks nor the native embeddings
|
|
53
|
+
// protocol have a verified Chat billing contract in this scope.
|
|
54
|
+
requireUnscopedModelTransport();
|
|
51
55
|
if (!defaultOllama) return await embed.call(stage, profile);
|
|
52
56
|
// The raw SDK ollamaEmbed remains closed. This private transport is only
|
|
53
57
|
// invoked below, after the scoped Run projected the profile.
|
|
@@ -8,6 +8,7 @@ import executionBroker, {
|
|
|
8
8
|
SANDBOX_BOUNDARIES,
|
|
9
9
|
} from "../process-execution-broker/index.js";
|
|
10
10
|
import { BUILT_IN_PROVIDERS } from "../llm-providers.js";
|
|
11
|
+
import { requireUnscopedModelTransport } from "../formal-budget-provider-scope.js";
|
|
11
12
|
|
|
12
13
|
export const GOVERNED_SKILL_SYNTHESIS_PROCESS_GRADER_SCHEMA =
|
|
13
14
|
"chainlesschain.governed-skill-synthesis-process-grader/v2";
|
|
@@ -399,6 +400,9 @@ export function createGovernedSkillSynthesisProcessGrader(options = {}) {
|
|
|
399
400
|
persistentProcessAuditRequired: true,
|
|
400
401
|
});
|
|
401
402
|
const port = async (messages) => {
|
|
403
|
+
// This worker owns a separate credential reference and cannot inherit an
|
|
404
|
+
// async-local authority. Refuse before provisioning or launching it.
|
|
405
|
+
requireUnscopedModelTransport();
|
|
402
406
|
const current = executionSnapshot();
|
|
403
407
|
if (!executionSnapshotMatches(current, snapshot)) {
|
|
404
408
|
throw new Error(
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { types } from "node:util";
|
|
2
|
+
import { createSkillDecisionRequest } from "../decision-layer/contracts.js";
|
|
3
|
+
|
|
4
|
+
const MAX_BYTES = 256 * 1024;
|
|
5
|
+
|
|
6
|
+
function canonical(value) {
|
|
7
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
8
|
+
if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
|
|
9
|
+
return `{${Object.keys(value)
|
|
10
|
+
.sort()
|
|
11
|
+
.map((key) => `${JSON.stringify(key)}:${canonical(value[key])}`)
|
|
12
|
+
.join(",")}}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Capture descriptors before any authority await. Never evaluate source getters
|
|
16
|
+
// or allow caller mutation to change committed evidence or outbound bytes.
|
|
17
|
+
function snapshot(value) {
|
|
18
|
+
let nodes = 0;
|
|
19
|
+
let bytes = 0;
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
const visit = (entry, depth) => {
|
|
22
|
+
if (++nodes > 4096 || depth > 16)
|
|
23
|
+
throw new TypeError("Skill decision input exceeds its structural budget");
|
|
24
|
+
if (typeof entry === "string") {
|
|
25
|
+
bytes += Buffer.byteLength(entry, "utf8");
|
|
26
|
+
if (bytes > MAX_BYTES)
|
|
27
|
+
throw new TypeError("Skill decision input exceeds its byte budget");
|
|
28
|
+
return entry;
|
|
29
|
+
}
|
|
30
|
+
if (
|
|
31
|
+
entry === null ||
|
|
32
|
+
typeof entry === "boolean" ||
|
|
33
|
+
(typeof entry === "number" && Number.isFinite(entry))
|
|
34
|
+
)
|
|
35
|
+
return entry;
|
|
36
|
+
if (
|
|
37
|
+
!entry ||
|
|
38
|
+
typeof entry !== "object" ||
|
|
39
|
+
types.isProxy(entry) ||
|
|
40
|
+
seen.has(entry)
|
|
41
|
+
)
|
|
42
|
+
throw new TypeError(
|
|
43
|
+
"Skill decision input must be acyclic plain JSON data",
|
|
44
|
+
);
|
|
45
|
+
const array = Array.isArray(entry);
|
|
46
|
+
if (
|
|
47
|
+
!array &&
|
|
48
|
+
![Object.prototype, null].includes(Object.getPrototypeOf(entry))
|
|
49
|
+
)
|
|
50
|
+
throw new TypeError("Skill decision input must use plain objects");
|
|
51
|
+
const keys = Reflect.ownKeys(entry).filter(
|
|
52
|
+
(key) => !(array && key === "length"),
|
|
53
|
+
);
|
|
54
|
+
if (
|
|
55
|
+
array &&
|
|
56
|
+
(keys.length !== entry.length ||
|
|
57
|
+
keys.some((key, index) => key !== String(index)))
|
|
58
|
+
)
|
|
59
|
+
throw new TypeError("Skill decision arrays must be dense data");
|
|
60
|
+
seen.add(entry);
|
|
61
|
+
const output = array ? [] : Object.create(null);
|
|
62
|
+
for (const key of keys) {
|
|
63
|
+
const property = Object.getOwnPropertyDescriptor(entry, key);
|
|
64
|
+
if (
|
|
65
|
+
typeof key !== "string" ||
|
|
66
|
+
!property?.enumerable ||
|
|
67
|
+
!("value" in property)
|
|
68
|
+
)
|
|
69
|
+
throw new TypeError(
|
|
70
|
+
"Skill decision input cannot contain accessors or symbols",
|
|
71
|
+
);
|
|
72
|
+
bytes += Buffer.byteLength(key, "utf8");
|
|
73
|
+
if (bytes > MAX_BYTES)
|
|
74
|
+
throw new TypeError("Skill decision input exceeds its byte budget");
|
|
75
|
+
Object.defineProperty(output, key, {
|
|
76
|
+
value: visit(property.value, depth + 1),
|
|
77
|
+
enumerable: true,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
seen.delete(entry);
|
|
81
|
+
return Object.freeze(output);
|
|
82
|
+
};
|
|
83
|
+
const result = visit(value, 0);
|
|
84
|
+
if (Buffer.byteLength(JSON.stringify(result), "utf8") > MAX_BYTES)
|
|
85
|
+
throw new TypeError("Skill decision input exceeds its byte budget");
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function exact(value, keys) {
|
|
90
|
+
if (
|
|
91
|
+
!value ||
|
|
92
|
+
typeof value !== "object" ||
|
|
93
|
+
Array.isArray(value) ||
|
|
94
|
+
Object.keys(value).sort().join("\0") !== [...keys].sort().join("\0")
|
|
95
|
+
)
|
|
96
|
+
throw new TypeError("Skill decision has an unsupported protocol shape");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function text(value) {
|
|
100
|
+
if (typeof value !== "string" || !value.length)
|
|
101
|
+
throw new TypeError("Skill decision requires nonempty text");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function snapshotSkillDecisionPayload(value) {
|
|
105
|
+
const payload = snapshot(value);
|
|
106
|
+
exact(payload, ["state", "questions"]);
|
|
107
|
+
exact(payload.state, ["task", "candidates"]);
|
|
108
|
+
text(payload.state.task);
|
|
109
|
+
const candidates = payload.state.candidates;
|
|
110
|
+
if (
|
|
111
|
+
!Array.isArray(candidates) ||
|
|
112
|
+
candidates.length < 1 ||
|
|
113
|
+
candidates.length > 8
|
|
114
|
+
)
|
|
115
|
+
throw new TypeError("Skill decision requires bounded candidates");
|
|
116
|
+
candidates.forEach((candidate, index) => {
|
|
117
|
+
exact(candidate, [
|
|
118
|
+
"candidateId",
|
|
119
|
+
"name",
|
|
120
|
+
"description",
|
|
121
|
+
"category",
|
|
122
|
+
"tags",
|
|
123
|
+
]);
|
|
124
|
+
if (candidate.candidateId !== `c${index + 1}`)
|
|
125
|
+
throw new TypeError("Skill decision candidate identity changed");
|
|
126
|
+
for (const key of ["name", "description", "category"]) text(candidate[key]);
|
|
127
|
+
if (!Array.isArray(candidate.tags) || candidate.tags.length > 32)
|
|
128
|
+
throw new TypeError("Skill decision tags are unbounded");
|
|
129
|
+
candidate.tags.forEach(text);
|
|
130
|
+
});
|
|
131
|
+
const ids = candidates.map(({ candidateId }) => candidateId);
|
|
132
|
+
exact(payload.questions, [
|
|
133
|
+
"needs_skill",
|
|
134
|
+
"best_skill",
|
|
135
|
+
...ids.map((id) => `fits_${id}`),
|
|
136
|
+
]);
|
|
137
|
+
for (const key of ["needs_skill", ...ids.map((id) => `fits_${id}`)]) {
|
|
138
|
+
exact(payload.questions[key], ["type", "instructions"]);
|
|
139
|
+
if (payload.questions[key].type !== "noul")
|
|
140
|
+
throw new TypeError("Skill decision question type changed");
|
|
141
|
+
text(payload.questions[key].instructions);
|
|
142
|
+
}
|
|
143
|
+
const choice = payload.questions.best_skill;
|
|
144
|
+
exact(choice, ["type", "instructions", "criteria"]);
|
|
145
|
+
if (choice.type !== "choice")
|
|
146
|
+
throw new TypeError("Skill decision question type changed");
|
|
147
|
+
text(choice.instructions);
|
|
148
|
+
exact(choice.criteria, [...ids, "none"]);
|
|
149
|
+
Object.values(choice.criteria).forEach(text);
|
|
150
|
+
return payload;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function snapshotSkillDecisionRequest(value) {
|
|
154
|
+
const request = snapshot(value);
|
|
155
|
+
const rebuilt = createSkillDecisionRequest({
|
|
156
|
+
decisionId: request.decisionId,
|
|
157
|
+
...request.binding,
|
|
158
|
+
query: request.payload?.state?.task,
|
|
159
|
+
candidates: request.candidates,
|
|
160
|
+
});
|
|
161
|
+
if (canonical(request) !== canonical(rebuilt))
|
|
162
|
+
throw new TypeError("Skill decision request identity or contract changed");
|
|
163
|
+
snapshotSkillDecisionPayload(request.payload);
|
|
164
|
+
return request;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function textPath(path) {
|
|
168
|
+
return (
|
|
169
|
+
/^state\.task$/u.test(path) ||
|
|
170
|
+
/^state\.candidates\.\d+\.(?:name|description|category|tags\.\d+)$/u.test(
|
|
171
|
+
path,
|
|
172
|
+
) ||
|
|
173
|
+
/^questions\.best_skill\.criteria\.c[1-8]$/u.test(path)
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function buildSkillDecisionPayload(original, projection) {
|
|
178
|
+
if (
|
|
179
|
+
projection.visibility !== "model-visible" ||
|
|
180
|
+
projection.truncated ||
|
|
181
|
+
(projection.redactionSummary?.byType?.["content-truncation"] ?? 0) > 0
|
|
182
|
+
)
|
|
183
|
+
throw new Error("Skill decision projection is opaque or truncated");
|
|
184
|
+
const captured = snapshotSkillDecisionPayload(original);
|
|
185
|
+
const projected = snapshotSkillDecisionPayload(projection.content);
|
|
186
|
+
const compare = (before, after, path = "") => {
|
|
187
|
+
if (
|
|
188
|
+
typeof before === "string" &&
|
|
189
|
+
typeof after === "string" &&
|
|
190
|
+
textPath(path)
|
|
191
|
+
)
|
|
192
|
+
return;
|
|
193
|
+
if (before === null || typeof before !== "object") {
|
|
194
|
+
if (before !== after)
|
|
195
|
+
throw new Error("Skill decision projection changed protocol metadata");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (
|
|
199
|
+
!after ||
|
|
200
|
+
typeof after !== "object" ||
|
|
201
|
+
Array.isArray(before) !== Array.isArray(after) ||
|
|
202
|
+
Object.keys(before).sort().join("\0") !==
|
|
203
|
+
Object.keys(after).sort().join("\0")
|
|
204
|
+
)
|
|
205
|
+
throw new Error("Skill decision projection changed protocol structure");
|
|
206
|
+
for (const key of Object.keys(before))
|
|
207
|
+
compare(before[key], after[key], path ? `${path}.${key}` : key);
|
|
208
|
+
};
|
|
209
|
+
compare(captured, projected);
|
|
210
|
+
return projected;
|
|
211
|
+
}
|
|
@@ -239,9 +239,19 @@ export async function openSkillRetrievalRevocationAuthority({
|
|
|
239
239
|
) {
|
|
240
240
|
throw new Error("Retrieval revocation load is not authoritative");
|
|
241
241
|
}
|
|
242
|
-
|
|
242
|
+
const loadedState = loaded.found
|
|
243
243
|
? verifySkillRetrievalRevocationState(loaded.state, tenantId)
|
|
244
244
|
: null;
|
|
245
|
+
if (
|
|
246
|
+
state !== null &&
|
|
247
|
+
(loadedState === null ||
|
|
248
|
+
loadedState.revision < state.revision ||
|
|
249
|
+
(loadedState.revision === state.revision &&
|
|
250
|
+
loadedState.stateDigest !== state.stateDigest))
|
|
251
|
+
) {
|
|
252
|
+
throw new Error("Retrieval revocation state regressed");
|
|
253
|
+
}
|
|
254
|
+
state = loadedState;
|
|
245
255
|
return state;
|
|
246
256
|
}
|
|
247
257
|
|
|
@@ -265,6 +275,10 @@ export async function openSkillRetrievalRevocationAuthority({
|
|
|
265
275
|
receiptDigest: entry?.propagationRequestDigest ?? null,
|
|
266
276
|
});
|
|
267
277
|
},
|
|
278
|
+
async refresh() {
|
|
279
|
+
const current = await reload();
|
|
280
|
+
return current?.stateDigest ?? null;
|
|
281
|
+
},
|
|
268
282
|
async invalidateRetrieval(input) {
|
|
269
283
|
const request = normalizeRequest(input, tenantId);
|
|
270
284
|
const contentDigest = request.dependency.digest;
|
|
@@ -351,7 +365,8 @@ export function captureSkillRetrievalRevocationReader(reader) {
|
|
|
351
365
|
if (
|
|
352
366
|
!readerBrand.has(reader) ||
|
|
353
367
|
reader.schema !== SKILL_RETRIEVAL_REVOCATION_READER_SCHEMA ||
|
|
354
|
-
typeof reader.inspect !== "function"
|
|
368
|
+
typeof reader.inspect !== "function" ||
|
|
369
|
+
typeof reader.refresh !== "function"
|
|
355
370
|
) {
|
|
356
371
|
throw new TypeError(
|
|
357
372
|
"A branded Skill retrieval revocation reader is required",
|