chainlesschain 0.165.3 → 0.165.5
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 +151 -29
- package/package.json +2 -2
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-BiHNUlbU.js → AIOps-CEeYTeDB.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-D-UFjDRQ.js → ActionButton-BeRUQ3V2.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DazVsDgW.js → Analytics-DrV718XF.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DXh9UfNJ.js → AppLayout-Cd2Frt7Q.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-CZ6tsceY.js → Artifacts-CUJMlORU.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-RyxnBr_h.js → Audit-CXJcfT6p.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BWS51Q6X.js → BackgroundAgents-DOv6Z7H9.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BRtPcUul.js → Backup-BwdDyBI0.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-CGd4vZYY.js → BaseInput-BmLn4kYH.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-h8ijVwCg.js → Chat-COg8pAW2.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-4gGkdGgA.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-NyF6dPl8.js → Checkbox-BCP4uoU8.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-Ci4OOxr5.js → Codegen-pRt6Y9JI.js} +1 -1
- package/src/assets/web-panel/assets/{Col-CwTkc9BM.js → Col-DLaprKhS.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DW_tM82m.js → Community-DyATsz5f.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-DEvHRV4S.js → Compact-BXAaupZK.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-BbjBEEfD.js → Compliance-DpcJBELr.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-10IXBaBa.js → Cowork-DG4EFWyd.js} +2 -2
- package/src/assets/web-panel/assets/{Cron-BZkbpd5I.js → Cron-F6Oy5n2P.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-CFQ8L_6v.js → Crosschain-BOdgtalX.js} +1 -1
- package/src/assets/web-panel/assets/{DID-BDF6AkXe.js → DID-DT1dSkjH.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-CoOdWMi4.js → Dashboard-NBUIqWzC.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DEsGmu8Y.js → Dropdown-CSpHeMYB.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-BS89SWlK.js → EmailListRenderer-CEG0xISr.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-C1FpCHiI.js → FamilyGuardDashboard-BTZ0BZna.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BzvpVmLA.js → Federation-BuuCTn2V.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-BeC259PQ.js → FormItemContext-KAVceevk.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-azgG3bmV.js → GenericCardRenderer-DnHpcQvW.js} +1 -1
- package/src/assets/web-panel/assets/{Git-BmSSowc5.js → Git-C_B_0HwB.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-CTBCSyQZ.js → Governance-DPSZuzuu.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-DA5xyk4a.js → Inference-BV-06V7q.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-D1gPHNig.js → KnowledgeGraph-wpDuupn6.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BPmLf1AR.js → Logs-Bseca1_I.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-SVLOg49H.js → MarkdownRenderer-B4RLp2zs.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-DtUFcR0E.js → Marketplace-d3kM4DDL.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DS_kqBv-.js → McpTools-DQ_xZ23i.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-Fvh7XL7V.js → Memory-CRIeYO4L.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-C7itAP45.js → MobileBridge-BsllIa9l.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-BUuQy30X.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B57MiNLK.js → Mtc-BOFDIzrC.js} +6 -6
- package/src/assets/web-panel/assets/{MtcAudit-BXfCUcM7.js → MtcAudit-BQg-vyvG.js} +5 -5
- package/src/assets/web-panel/assets/{Multisig-yaJ-ZcF6.js → Multisig-Bo1jrPdN.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-CoaUCKrO.js → NLProgramming-Bmod8alw.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-BKLM_65R.js → Notes-CGGFL8w-.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DoDtK9uZ.js → NotificationSettings-BsZvCJxC.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-BJ28TGr-.js → OrderTableRenderer-C1-Quo_h.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-MuGsdoIb.js → Organization-BjOeDYOi.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-BLUN9J4R.js → Overflow-DwVV3l5A.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-DWuoBUPd.js → P2P-Cu3DQT9W.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CUi37YPj.js → PdhVaultBrowser-Cg0gR7dH.js} +3 -3
- package/src/assets/web-panel/assets/{Permissions-BYQg2pcr.js → Permissions-CsAXxRN5.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CAxoV2xu.js → PersonalDataHub-C-nNmnYp.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-B33wGvIO.js → Pipeline-BOnW7nNc.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-A8yXTORP.js → Privacy-ClLSyGKt.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-D49I2I1O.js → ProjectInit-DuLvjjq7.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-Ci73jJDw.js → ProjectSettings-DQYYbDD9.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-CF-yD6Cn.js → Projects-Drw8MBGK.js} +1 -1
- package/src/assets/web-panel/assets/Providers-ckqHQe6K.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-Brza0ykJ.js → QrScannerModal-DW5BXk-G.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-DFydhjxL.js → QuickAsk-DDLnhNTp.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DLF8_NhA.js → Recommend-PJQ2C91U.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-dyuStW3x.js → RemoteSession-s6wmda34.js} +3 -3
- package/src/assets/web-panel/assets/{Reputation-5F3tA6yw.js → Reputation-DC2sb-I3.js} +1 -1
- package/src/assets/web-panel/assets/{Row-Ca2A57S5.js → Row-hPGk1eGj.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-B0bxBkq_.js → RssFeed-RIvfZql0.js} +3 -3
- package/src/assets/web-panel/assets/{Search-CFNvHalZ.js → Search-DFg1G1eR.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DSoH3Hav.js → Security-D6H5p8Dp.js} +4 -4
- package/src/assets/web-panel/assets/{Services-BHpfEmBQ.js → Services-nxYiFV_w.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-Dsh-QNmn.js → Skeleton-BmgFNAdB.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BhT1NkSU.js → Skills-CsaaD2av.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DY9snPeJ.js → Sla-yM5y9yvK.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-CWaX0_Cx.js → SpeechSettings-DPy1XMYh.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-B690y_TC.js → SyncSettings-CFVhEyyr.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-2N-w3zWd.js → Tasks-DdO02Inn.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-BjwQOQYC.js → Templates-Eo2d8Llu.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CUqHErxY.js → Tenant-ChESOXgy.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-C13rXvNy.js → Terminal-BJ7oDxTI.js} +2 -2
- package/src/assets/web-panel/assets/TimelineRenderer-hWX0fUvz.js +1 -0
- package/src/assets/web-panel/assets/{Tokens-BXHLGXYC.js → Tokens-DVBZQnd-.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-1e5i65o3.js → Trigger-D89cQfVq.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-FLGqNHs5.js → Trust-BIVSb4-V.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-BbaR_LJB.js → UkeySign-B58gWopl.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-NOp4RIov.js → VideoEditing-DhHI7bmG.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-B7DW7bG4.js → Wallet-C4FheWS_.js} +3 -3
- package/src/assets/web-panel/assets/{WebAuthn-BptSUWix.js → WebAuthn-DnPRq-Bx.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-CAJnDOXS.js → WorkflowEditor-BerRPjpJ.js} +1 -1
- package/src/assets/web-panel/assets/{chat-I8LgG1-Z.js → chat-BzZ52iKr.js} +1 -1
- package/src/assets/web-panel/assets/{colors-CWe7SOVD.js → colors-BI_E4BAn.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Cx3u3CA3.js → compact-item-d50mr3yk.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-CgD5ArwY.js → createContext-C6FsQ1IH.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-CagEcIex.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-BfQWiXN8.js → hasIn-DLZEMgLP.js} +1 -1
- package/src/assets/web-panel/assets/{index-BuEQSorC.js → index-9H_M2jju.js} +1 -1
- package/src/assets/web-panel/assets/{index-BiI-xPRH.js → index-A5CDWP7y.js} +1 -1
- package/src/assets/web-panel/assets/{index-DAVy98u7.js → index-AHr7ryWf.js} +1 -1
- package/src/assets/web-panel/assets/{index-BUAR7RY-.js → index-B81mo1Et.js} +1 -1
- package/src/assets/web-panel/assets/{index-DlIyt1qF.js → index-BAE3hwev.js} +1 -1
- package/src/assets/web-panel/assets/{index-Dcdm_Z2c.js → index-BB9SqVSt.js} +1 -1
- package/src/assets/web-panel/assets/{index-CWZ3REg6.js → index-BRGx3w6T.js} +3 -3
- package/src/assets/web-panel/assets/{index-B6yChzt1.js → index-BTpIOTfR.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeizoQVZ.js → index-BZjjdQ62.js} +1 -1
- package/src/assets/web-panel/assets/{index-e8BM1yY1.js → index-BcSUl9fA.js} +1 -1
- package/src/assets/web-panel/assets/{index-CNYFQxAW.js → index-BeM4hfht.js} +1 -1
- package/src/assets/web-panel/assets/{index-DGMYTN5W.js → index-Bmr_vxXD.js} +1 -1
- package/src/assets/web-panel/assets/{index-BREnPKGo.js → index-BoNZlzhQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-B1cX4Rxu.js → index-C3k8kevG.js} +1 -1
- package/src/assets/web-panel/assets/{index-3iKP9OTJ.js → index-CLoTQr0W.js} +1 -1
- package/src/assets/web-panel/assets/{index-C1UjHdgZ.js → index-CO8DAF7U.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cy_cCJlr.js → index-CRN5TRTQ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0nDKhWv.js → index-CUaEHfQ0.js} +1 -1
- package/src/assets/web-panel/assets/{index-DslTuqro.js → index-CVzuawCX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CAUnl4Jv.js → index-CdKt9fOd.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMu16vPC.js → index-CgkoH3_g.js} +1 -1
- package/src/assets/web-panel/assets/{index-C-rIKccl.js → index-CjuKZBqJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bx7BNIRH.js → index-Co7s9LsB.js} +1 -1
- package/src/assets/web-panel/assets/{index-Doc0Ftpd.js → index-D-aBumtY.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cd79NQAx.js → index-DE0V6cp-.js} +1 -1
- package/src/assets/web-panel/assets/{index-V-kIHzAV.js → index-DY4j5zkF.js} +1 -1
- package/src/assets/web-panel/assets/{index-Bi24S7Dw.js → index-Dec0Kf_Z.js} +1 -1
- package/src/assets/web-panel/assets/{index-DCJEY2T0.js → index-DoFtCVZ7.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0ztiqtB.js → index-DqkbHHg8.js} +1 -1
- package/src/assets/web-panel/assets/{index-CcX4FSPf.js → index-DsscwxPE.js} +1 -1
- package/src/assets/web-panel/assets/{index-CdRkCwm4.js → index-GXE0D8Nx.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmgtY58H.js → index-IPkwSAW_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CQDKYbnv.js → index-KNGgO4Wm.js} +1 -1
- package/src/assets/web-panel/assets/{index-87gMxqhN.js → index-Pvf30m8Q.js} +1 -1
- package/src/assets/web-panel/assets/{index-DmrdUwzU.js → index-Q5Tn735s.js} +1 -1
- package/src/assets/web-panel/assets/{index-DFb-XIKy.js → index-TWG-_D1M.js} +1 -1
- package/src/assets/web-panel/assets/{index-DsQcURkA.js → index-Y2-q7QLm.js} +1 -1
- package/src/assets/web-panel/assets/index-pzT9PpOU.js +1 -0
- package/src/assets/web-panel/assets/index-z1kFadaX.js +1 -0
- package/src/assets/web-panel/assets/{initDefaultProps-DiBszVdG.js → initDefaultProps-D-4Hzgej.js} +1 -1
- package/src/assets/web-panel/assets/{motion-BGIFFozv.js → motion-D4Wl4xU7.js} +1 -1
- package/src/assets/web-panel/assets/{move-D5W7mp7B.js → move-Cd5eQvL0.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-JFIlxJ7F.js → mtc-parser-B4ilslCW.js} +1 -1
- package/src/assets/web-panel/assets/{omit-CQ3o6LIU.js → omit-Ckarx-tf.js} +1 -1
- package/src/assets/web-panel/assets/parsers-YNLm7sQ0.js +4 -0
- package/src/assets/web-panel/assets/{pickAttrs-R8MIlXo3.js → pickAttrs-QJ0bpCmc.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-sW7ylSky.js → placementArrow-CKHm-tq8.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-Cnl39Vbz.js → responsiveObserve-CV6a_w_Y.js} +1 -1
- package/src/assets/web-panel/assets/{slide-sn8tFd14.js → slide-mHpeQFgk.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-IKKY_QxZ.js → statusUtils-DIaQNQWA.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-BNpV4Nqs.js → styleChecker-PJpzavV8.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-BWyT_eoU.js → useFlexGapSupport-BH7zTw8S.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-D09p6_U9.js → useFs-BDNG3JDd.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-CzW3TkJZ.js → usePersonalDataHub-CY2VWdUg.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-3s3WoAKB.js → vnode-D0kw9jhz.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-Cjy_673s.js → zoom-B5g7TN7r.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +3 -3
- package/src/commands/agent.js +105 -35
- package/src/commands/artifacts.js +598 -33
- package/src/commands/cowork.js +200 -5
- package/src/commands/session-budget.js +155 -0
- package/src/commands/session-location.js +968 -1
- package/src/commands/session.js +23 -2
- package/src/data/changelog.json +28 -2
- package/src/gateways/ws/artifact-protocol.js +77 -13
- package/src/gateways/ws/message-dispatcher.js +57 -0
- package/src/gateways/ws/session-protocol.js +391 -24
- package/src/gateways/ws/ws-agent-handler.js +191 -14
- package/src/gateways/ws/ws-server.js +14 -3
- package/src/gateways/ws/ws-session-gateway.js +101 -5
- package/src/harness/jsonl-session-store.js +1210 -0
- package/src/lib/agent-team/team-runner.js +43 -13
- package/src/lib/artifact-access-ledger.js +462 -0
- package/src/lib/artifact-cleanup-ledger.js +861 -0
- package/src/lib/artifact-deletion-ledger.js +678 -0
- package/src/lib/artifact-recovery.js +970 -0
- package/src/lib/artifact-store.js +256 -51
- package/src/lib/artifact-workbench-projection.js +171 -0
- package/src/lib/command-lifecycle-report.js +8 -4
- package/src/lib/cowork-adapter.js +9 -5
- package/src/lib/cowork-task-runner.js +20 -0
- package/src/lib/cowork-workflow.js +178 -20
- package/src/lib/direct-model-usage.js +62 -22
- package/src/lib/dynamic-workflow-runtime.js +3592 -112
- package/src/lib/execution-location-result-apply.js +339 -0
- package/src/lib/execution-location-result-artifact.js +271 -0
- package/src/lib/execution-location-result-review.js +253 -0
- package/src/lib/execution-location-result-store.js +331 -0
- package/src/lib/execution-location-result.js +617 -0
- package/src/lib/execution-location-target.js +240 -3
- package/src/lib/managed-tool-checkpoint.js +47 -4
- package/src/lib/mcp-stdio-executable-identity.js +16 -0
- package/src/lib/mcp-stdio-native-code-policy.js +74 -0
- package/src/lib/mcp-stdio-package-materialization.js +12 -3
- package/src/lib/process-execution-broker/index.js +112 -0
- package/src/lib/process-execution-broker/platform-sandbox.js +57 -3
- package/src/lib/process-execution-broker/workspace-transaction.js +29 -0
- package/src/lib/session-budget-production-root.js +376 -0
- package/src/lib/session-budget-runtime.js +109 -18
- package/src/lib/session-budget-usage.js +63 -0
- package/src/lib/session-host-snapshot.js +19 -2
- package/src/lib/session-projection.js +126 -10
- package/src/lib/session-resource-budget.js +766 -105
- package/src/lib/sub-agent-context.js +69 -22
- package/src/lib/web-ui-server.js +12 -1
- package/src/repl/agent-repl.js +237 -16
- package/src/runtime/agent-core.js +135 -0
- package/src/runtime/headless-runner.js +135 -46
- package/src/runtime/headless-stream.js +133 -25
- package/src/runtime/policies/agent-policy.js +10 -0
- package/src/assets/web-panel/assets/ChatBubbleRenderer-D7tcdDS9.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-DGbP36-3.js +0 -1
- package/src/assets/web-panel/assets/Providers-D-etEhg5.js +0 -1
- package/src/assets/web-panel/assets/TimelineRenderer-CpbWcya_.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DLv_872g.js +0 -1
- package/src/assets/web-panel/assets/index-CdiGCibe.js +0 -1
- package/src/assets/web-panel/assets/index-D_0z-gyz.js +0 -1
- package/src/assets/web-panel/assets/parsers-UEvh_ShA.js +0 -4
|
@@ -16,12 +16,21 @@ import {
|
|
|
16
16
|
} from "./secure-file-identity.js";
|
|
17
17
|
import { canonicalJson } from "./scheduler-kernel/contract.js";
|
|
18
18
|
import { executionBroker } from "./process-execution-broker/index.js";
|
|
19
|
+
import {
|
|
20
|
+
MAX_EXECUTION_LOCATION_RESULT_BUNDLE_BYTES,
|
|
21
|
+
normalizeExecutionLocationResultBundle,
|
|
22
|
+
verifyExecutionLocationResultBundle,
|
|
23
|
+
} from "./execution-location-result.js";
|
|
19
24
|
|
|
20
25
|
export const EXECUTION_LOCATION_PROFILE_SCHEMA =
|
|
21
26
|
"cc-execution-location-profile/v1";
|
|
22
27
|
export { EXECUTION_LOCATION_TARGET_ATTESTATION_SCHEMA };
|
|
23
28
|
export const EXECUTION_LOCATION_TARGET_RESUME_SCHEMA =
|
|
24
29
|
"cc-execution-location-target-resume/v1";
|
|
30
|
+
export const EXECUTION_LOCATION_TARGET_RESULT_COLLECTION_SCHEMA =
|
|
31
|
+
"cc-execution-location-target-result-collection/v1";
|
|
32
|
+
export const EXECUTION_LOCATION_TARGET_RESULT_COLLECTION_REQUEST_SCHEMA =
|
|
33
|
+
"cc-execution-location-target-result-collection-request/v1";
|
|
25
34
|
|
|
26
35
|
const SESSION_LOCATION_AUTHORITY_SCHEMA =
|
|
27
36
|
"cc-session-execution-location-authority/v1";
|
|
@@ -34,6 +43,8 @@ const COMMIT_RE = /^[a-f0-9]{40,64}$/u;
|
|
|
34
43
|
const MAX_PROFILE_BYTES = 1024 * 1024;
|
|
35
44
|
const MAX_PROBE_BYTES = 1024 * 1024;
|
|
36
45
|
const MAX_REPLICA_BYTES = 64 * 1024 * 1024;
|
|
46
|
+
const RESULT_MEDIA_TYPE_RE =
|
|
47
|
+
/^[a-z0-9][a-z0-9!#$&^_.+-]{0,126}\/[a-z0-9][a-z0-9!#$&^_.+-]{0,126}$/u;
|
|
37
48
|
|
|
38
49
|
function digest(domain, value) {
|
|
39
50
|
return `sha256:${createHash("sha256")
|
|
@@ -480,6 +491,14 @@ function runTargetCommand(profile, cliArgs, deps = {}, options = {}) {
|
|
|
480
491
|
((file, args, spawnOptions) =>
|
|
481
492
|
executionBroker.spawnSync(file, args, spawnOptions));
|
|
482
493
|
try {
|
|
494
|
+
const maxBuffer = Number(options.maxBuffer ?? MAX_PROBE_BYTES);
|
|
495
|
+
if (
|
|
496
|
+
!Number.isSafeInteger(maxBuffer) ||
|
|
497
|
+
maxBuffer < 1 ||
|
|
498
|
+
maxBuffer > MAX_EXECUTION_LOCATION_RESULT_BUNDLE_BYTES
|
|
499
|
+
) {
|
|
500
|
+
throw new Error("target command output boundary is invalid");
|
|
501
|
+
}
|
|
483
502
|
const result = spawnSync(invocation.file, invocation.args, {
|
|
484
503
|
origin: "execution-location:target",
|
|
485
504
|
scope: "execution-location",
|
|
@@ -487,7 +506,7 @@ function runTargetCommand(profile, cliArgs, deps = {}, options = {}) {
|
|
|
487
506
|
shell: false,
|
|
488
507
|
encoding: "utf8",
|
|
489
508
|
timeout: options.interactive ? undefined : 30000,
|
|
490
|
-
maxBuffer: options.interactive ? undefined :
|
|
509
|
+
maxBuffer: options.interactive ? undefined : maxBuffer,
|
|
491
510
|
...(options.input == null ? {} : { input: options.input }),
|
|
492
511
|
stdio: options.interactive
|
|
493
512
|
? "inherit"
|
|
@@ -795,9 +814,11 @@ function transferTargetSessionStore(
|
|
|
795
814
|
receipt.targetFactsDigest !== receiptMaterial.targetFactsDigest ||
|
|
796
815
|
receipt.profileDigest !== receiptMaterial.profileDigest ||
|
|
797
816
|
receipt.targetEvidenceId !== receiptMaterial.targetEvidenceId ||
|
|
817
|
+
// Target prepare records a fresh observedAt, so its attestation digest is
|
|
818
|
+
// expected to differ from the earlier source-side probe. The receipt is
|
|
819
|
+
// rehashed here and the next target `location show` validates that digest
|
|
820
|
+
// against the canonical handoff binding before resume.
|
|
798
821
|
!SHA256_RE.test(receipt.attestationDigest || "") ||
|
|
799
|
-
(receipt.handoffAppended === true &&
|
|
800
|
-
receipt.attestationDigest !== attestation.attestationDigest) ||
|
|
801
822
|
typeof receipt.replicaInstalled !== "boolean" ||
|
|
802
823
|
typeof receipt.handoffAppended !== "boolean" ||
|
|
803
824
|
receipt.receiptDigest !== expectedReceiptDigest
|
|
@@ -839,6 +860,222 @@ function verifySourceAuthorityBeforeResume(handoff, readSourceAuthority) {
|
|
|
839
860
|
});
|
|
840
861
|
}
|
|
841
862
|
|
|
863
|
+
function normalizeResultCollectionItem(entry, label) {
|
|
864
|
+
const mediaType = String(entry?.mediaType || "").toLowerCase();
|
|
865
|
+
const filePath = safePath(entry?.path, `${label} path`);
|
|
866
|
+
if (!RESULT_MEDIA_TYPE_RE.test(mediaType)) {
|
|
867
|
+
throw new TypeError(`${label} media type is invalid`);
|
|
868
|
+
}
|
|
869
|
+
return { mediaType, path: filePath };
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
export function createExecutionLocationTargetResultCollectionRequest(
|
|
873
|
+
input = {},
|
|
874
|
+
) {
|
|
875
|
+
const profile = normalizeExecutionLocationProfile(input.profile);
|
|
876
|
+
const target = safeName(
|
|
877
|
+
input.target ?? profile.target,
|
|
878
|
+
"result collection target",
|
|
879
|
+
32,
|
|
880
|
+
);
|
|
881
|
+
if (target !== profile.target) {
|
|
882
|
+
throw new TypeError("result collection target does not match profile");
|
|
883
|
+
}
|
|
884
|
+
const requestId = safeName(
|
|
885
|
+
input.requestId,
|
|
886
|
+
"result collection request id",
|
|
887
|
+
128,
|
|
888
|
+
);
|
|
889
|
+
const sessionId = safeName(input.sessionId, "result collection session id");
|
|
890
|
+
const resultId = safeName(input.resultId, "result id", 128);
|
|
891
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(resultId)) {
|
|
892
|
+
throw new TypeError("result id is invalid");
|
|
893
|
+
}
|
|
894
|
+
const targetFactsDigest = String(
|
|
895
|
+
input.expectedTargetFactsDigest || "",
|
|
896
|
+
).toLowerCase();
|
|
897
|
+
const handoffId = String(input.expectedHandoffId || "").toLowerCase();
|
|
898
|
+
if (!SHA256_RE.test(targetFactsDigest)) {
|
|
899
|
+
throw new TypeError("expected target facts digest is invalid");
|
|
900
|
+
}
|
|
901
|
+
if (!SHA256_RE.test(handoffId)) {
|
|
902
|
+
throw new TypeError("expected result handoff id is invalid");
|
|
903
|
+
}
|
|
904
|
+
const artifacts = (input.artifacts ?? []).map((entry, index) =>
|
|
905
|
+
normalizeResultCollectionItem(entry, `result artifact ${index}`),
|
|
906
|
+
);
|
|
907
|
+
const evidence = (input.evidence ?? []).map((entry, index) =>
|
|
908
|
+
normalizeResultCollectionItem(entry, `result evidence ${index}`),
|
|
909
|
+
);
|
|
910
|
+
if (artifacts.length + evidence.length > 64) {
|
|
911
|
+
throw new TypeError("result collection item list is invalid");
|
|
912
|
+
}
|
|
913
|
+
const material = {
|
|
914
|
+
schema: EXECUTION_LOCATION_TARGET_RESULT_COLLECTION_REQUEST_SCHEMA,
|
|
915
|
+
requestId,
|
|
916
|
+
sessionId,
|
|
917
|
+
target,
|
|
918
|
+
profileDigest: profile.profileDigest,
|
|
919
|
+
targetFactsDigest,
|
|
920
|
+
handoffId,
|
|
921
|
+
resultId,
|
|
922
|
+
summaryPath: safePath(input.summaryPath, "result summary path"),
|
|
923
|
+
diffPath: safePath(input.diffPath, "result diff path"),
|
|
924
|
+
artifacts,
|
|
925
|
+
evidence,
|
|
926
|
+
};
|
|
927
|
+
return Object.freeze({
|
|
928
|
+
...material,
|
|
929
|
+
requestDigest: digest(
|
|
930
|
+
"chainlesschain.execution-location.target-result-collection-request.v1\0",
|
|
931
|
+
material,
|
|
932
|
+
),
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
export function collectExecutionLocationTargetResult(input = {}, deps = {}) {
|
|
937
|
+
const profile = normalizeExecutionLocationProfile(input.profile);
|
|
938
|
+
validateProfileHandoff(profile, input.handoff);
|
|
939
|
+
const expectedTargetFactsDigest = safeString(
|
|
940
|
+
input.expectedTargetFactsDigest,
|
|
941
|
+
"expected target facts digest",
|
|
942
|
+
80,
|
|
943
|
+
).toLowerCase();
|
|
944
|
+
if (!SHA256_RE.test(expectedTargetFactsDigest)) {
|
|
945
|
+
throw new Error("expected target facts digest is invalid");
|
|
946
|
+
}
|
|
947
|
+
const sourceBefore = verifySourceAuthorityBeforeResume(
|
|
948
|
+
input.handoff,
|
|
949
|
+
input.readSourceAuthority,
|
|
950
|
+
);
|
|
951
|
+
const attestation = attestExecutionLocationTarget(
|
|
952
|
+
{ profile, handoff: input.handoff },
|
|
953
|
+
deps,
|
|
954
|
+
);
|
|
955
|
+
if (attestation.targetFactsDigest !== expectedTargetFactsDigest) {
|
|
956
|
+
throw new Error("target facts digest changed before result collection");
|
|
957
|
+
}
|
|
958
|
+
const resultId = safeName(input.resultId, "result id", 128);
|
|
959
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/u.test(resultId)) {
|
|
960
|
+
throw new TypeError("result id is invalid");
|
|
961
|
+
}
|
|
962
|
+
const expectedHandoffId = String(input.expectedHandoffId || "");
|
|
963
|
+
if (!SHA256_RE.test(expectedHandoffId)) {
|
|
964
|
+
throw new TypeError("expected result handoff id is invalid");
|
|
965
|
+
}
|
|
966
|
+
const summaryPath = safePath(input.summaryPath, "result summary path");
|
|
967
|
+
const diffPath = safePath(input.diffPath, "result diff path");
|
|
968
|
+
const artifactInput = input.artifacts ?? [];
|
|
969
|
+
const evidenceInput = input.evidence ?? [];
|
|
970
|
+
if (!Array.isArray(artifactInput) || !Array.isArray(evidenceInput)) {
|
|
971
|
+
throw new TypeError("result collection item list is invalid");
|
|
972
|
+
}
|
|
973
|
+
const artifacts = artifactInput.map((entry, index) =>
|
|
974
|
+
normalizeResultCollectionItem(entry, `result artifact ${index}`),
|
|
975
|
+
);
|
|
976
|
+
const evidence = evidenceInput.map((entry, index) =>
|
|
977
|
+
normalizeResultCollectionItem(entry, `result evidence ${index}`),
|
|
978
|
+
);
|
|
979
|
+
if (artifacts.length + evidence.length > 64) {
|
|
980
|
+
throw new TypeError("result collection item list is invalid");
|
|
981
|
+
}
|
|
982
|
+
const request = createExecutionLocationTargetResultCollectionRequest({
|
|
983
|
+
requestId: input.requestId,
|
|
984
|
+
sessionId: input.handoff?.session?.sessionId,
|
|
985
|
+
target: profile.target,
|
|
986
|
+
profile,
|
|
987
|
+
expectedTargetFactsDigest,
|
|
988
|
+
expectedHandoffId,
|
|
989
|
+
resultId,
|
|
990
|
+
summaryPath,
|
|
991
|
+
diffPath,
|
|
992
|
+
artifacts,
|
|
993
|
+
evidence,
|
|
994
|
+
});
|
|
995
|
+
const args = [
|
|
996
|
+
"session",
|
|
997
|
+
"location",
|
|
998
|
+
"result-pack",
|
|
999
|
+
input.handoff.session.sessionId,
|
|
1000
|
+
"--result-id",
|
|
1001
|
+
resultId,
|
|
1002
|
+
"--summary",
|
|
1003
|
+
summaryPath,
|
|
1004
|
+
"--diff",
|
|
1005
|
+
diffPath,
|
|
1006
|
+
];
|
|
1007
|
+
for (const entry of artifacts) {
|
|
1008
|
+
args.push("--artifact", `${entry.mediaType}=${entry.path}`);
|
|
1009
|
+
}
|
|
1010
|
+
for (const entry of evidence) {
|
|
1011
|
+
args.push("--evidence", `${entry.mediaType}=${entry.path}`);
|
|
1012
|
+
}
|
|
1013
|
+
args.push("--json");
|
|
1014
|
+
const raw = runTargetCommand(profile, args, deps, {
|
|
1015
|
+
maxBuffer: MAX_EXECUTION_LOCATION_RESULT_BUNDLE_BYTES,
|
|
1016
|
+
});
|
|
1017
|
+
let bundleInput;
|
|
1018
|
+
try {
|
|
1019
|
+
bundleInput = JSON.parse(String(raw));
|
|
1020
|
+
} catch {
|
|
1021
|
+
throw new Error("target result bundle output is not one exact JSON object");
|
|
1022
|
+
}
|
|
1023
|
+
const bundle = normalizeExecutionLocationResultBundle(bundleInput);
|
|
1024
|
+
const sourceAfter = verifySourceAuthorityBeforeResume(
|
|
1025
|
+
input.handoff,
|
|
1026
|
+
input.readSourceAuthority,
|
|
1027
|
+
);
|
|
1028
|
+
const verification = verifyExecutionLocationResultBundle({
|
|
1029
|
+
bundle,
|
|
1030
|
+
sourceAuthority: sourceAfter,
|
|
1031
|
+
expectedHandoffId,
|
|
1032
|
+
});
|
|
1033
|
+
if (
|
|
1034
|
+
bundle.session.handoffId !== expectedHandoffId ||
|
|
1035
|
+
bundle.session.target.profileDigest !== profile.profileDigest ||
|
|
1036
|
+
bundle.session.target.targetEvidenceId !== profile.evidenceId ||
|
|
1037
|
+
bundle.session.target.targetFactsDigest !== expectedTargetFactsDigest ||
|
|
1038
|
+
sourceBefore.headHash !== sourceAfter.headHash ||
|
|
1039
|
+
sourceBefore.eventCount !== sourceAfter.eventCount
|
|
1040
|
+
) {
|
|
1041
|
+
throw new Error(
|
|
1042
|
+
"target result bundle does not match the accepted handoff authority",
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
const material = {
|
|
1046
|
+
schema: EXECUTION_LOCATION_TARGET_RESULT_COLLECTION_SCHEMA,
|
|
1047
|
+
requestId: request.requestId,
|
|
1048
|
+
requestDigest: request.requestDigest,
|
|
1049
|
+
resultId,
|
|
1050
|
+
target: profile.target,
|
|
1051
|
+
profileDigest: profile.profileDigest,
|
|
1052
|
+
targetFactsDigest: expectedTargetFactsDigest,
|
|
1053
|
+
collectionAttestationDigest: attestation.attestationDigest,
|
|
1054
|
+
handoffId: bundle.session.handoffId,
|
|
1055
|
+
sourceAuthority: sourceAfter,
|
|
1056
|
+
targetHeadHash: bundle.session.target.headHash,
|
|
1057
|
+
targetEventCount: bundle.session.target.eventCount,
|
|
1058
|
+
bundleDigest: bundle.bundleDigest,
|
|
1059
|
+
verificationDigest: verification.verificationDigest,
|
|
1060
|
+
applied: false,
|
|
1061
|
+
continuity: "single-fixed-command-response",
|
|
1062
|
+
gaps: [
|
|
1063
|
+
"returned-result-bytes-not-durable",
|
|
1064
|
+
"cross-host-concurrent-writer-fencing-not-durable",
|
|
1065
|
+
"returned-result-not-applied",
|
|
1066
|
+
],
|
|
1067
|
+
};
|
|
1068
|
+
return Object.freeze({
|
|
1069
|
+
...material,
|
|
1070
|
+
bundle,
|
|
1071
|
+
verification,
|
|
1072
|
+
collectionDigest: digest(
|
|
1073
|
+
"chainlesschain.execution-location.target-result-collection.v1\0",
|
|
1074
|
+
material,
|
|
1075
|
+
),
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
|
|
842
1079
|
export function resumeExecutionLocationTarget(input = {}, deps = {}) {
|
|
843
1080
|
const profile = normalizeExecutionLocationProfile(input.profile);
|
|
844
1081
|
validateProfileHandoff(profile, input.handoff);
|
|
@@ -15,6 +15,9 @@ export const MANAGED_TOOL_CHECKPOINT_ERROR = Object.freeze({
|
|
|
15
15
|
SETTLEMENT_FAILED: "MANAGED_TOOL_CHECKPOINT_SETTLEMENT_FAILED",
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
export const MANAGED_TOOL_CHECKPOINT_BINDING_SCHEMA =
|
|
19
|
+
"cc-managed-tool-checkpoint-binding/v1";
|
|
20
|
+
|
|
18
21
|
const DIRECT_FILE_ONLY_TOOLS = new Set([
|
|
19
22
|
"write_file",
|
|
20
23
|
"edit_file",
|
|
@@ -33,6 +36,14 @@ const DEFAULT_READ_ONLY_TOOLS = new Set([
|
|
|
33
36
|
"search_sessions",
|
|
34
37
|
]);
|
|
35
38
|
|
|
39
|
+
export function managedToolCheckpointRequired(toolName, readOnly = undefined) {
|
|
40
|
+
const normalized = boundedBinding(toolName, "unknown-tool");
|
|
41
|
+
return !(
|
|
42
|
+
readOnly === true ||
|
|
43
|
+
(readOnly !== false && DEFAULT_READ_ONLY_TOOLS.has(normalized))
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
36
47
|
function checkpointError(code, message, details = {}, cause = null) {
|
|
37
48
|
const error = new Error(message, cause ? { cause } : undefined);
|
|
38
49
|
error.name = "ManagedToolCheckpointError";
|
|
@@ -69,6 +80,41 @@ function skippedCheckpoint(reason, toolName) {
|
|
|
69
80
|
});
|
|
70
81
|
}
|
|
71
82
|
|
|
83
|
+
export function managedToolCheckpointBinding(handle) {
|
|
84
|
+
if (!handle || handle.skipped === true) return null;
|
|
85
|
+
const prepared = handle.prepared;
|
|
86
|
+
if (
|
|
87
|
+
!prepared ||
|
|
88
|
+
prepared.id !== handle.transactionId ||
|
|
89
|
+
prepared.checkpointId !== handle.checkpointId ||
|
|
90
|
+
typeof prepared.checkpoint?.digest !== "string" ||
|
|
91
|
+
typeof prepared.stateDigest !== "string" ||
|
|
92
|
+
!Object.values(WORKSPACE_TRANSACTION_COVERAGE).includes(
|
|
93
|
+
prepared.coverage,
|
|
94
|
+
) ||
|
|
95
|
+
!Object.values(WORKSPACE_TRANSACTION_COVERAGE).includes(
|
|
96
|
+
prepared.fileCoverage,
|
|
97
|
+
) ||
|
|
98
|
+
typeof prepared.externalSideEffects !== "boolean"
|
|
99
|
+
) {
|
|
100
|
+
throw checkpointError(
|
|
101
|
+
MANAGED_TOOL_CHECKPOINT_ERROR.INVALID_ARGUMENT,
|
|
102
|
+
"managed tool checkpoint prepared binding is malformed",
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return Object.freeze({
|
|
106
|
+
schema: MANAGED_TOOL_CHECKPOINT_BINDING_SCHEMA,
|
|
107
|
+
authority: "process-broker-workspace-transaction-prepared",
|
|
108
|
+
transactionId: handle.transactionId,
|
|
109
|
+
checkpointId: handle.checkpointId,
|
|
110
|
+
checkpointDigest: prepared.checkpoint.digest,
|
|
111
|
+
preparedStateDigest: prepared.stateDigest,
|
|
112
|
+
coverage: prepared.coverage,
|
|
113
|
+
fileCoverage: prepared.fileCoverage,
|
|
114
|
+
externalSideEffects: prepared.externalSideEffects,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
72
118
|
/**
|
|
73
119
|
* Prepare one managed checkpoint before a mutating agent tool call.
|
|
74
120
|
*
|
|
@@ -79,10 +125,7 @@ function skippedCheckpoint(reason, toolName) {
|
|
|
79
125
|
export function beginManagedToolCheckpoint(options = {}) {
|
|
80
126
|
if (options.enabled !== true) return null;
|
|
81
127
|
const toolName = boundedBinding(options.toolName, "unknown-tool");
|
|
82
|
-
|
|
83
|
-
options.readOnly === true ||
|
|
84
|
-
(options.readOnly !== false && DEFAULT_READ_ONLY_TOOLS.has(toolName));
|
|
85
|
-
if (readOnly) return null;
|
|
128
|
+
if (!managedToolCheckpointRequired(toolName, options.readOnly)) return null;
|
|
86
129
|
if (
|
|
87
130
|
typeof options.unmanagedWriterReason === "string" &&
|
|
88
131
|
options.unmanagedWriterReason.trim()
|
|
@@ -24,6 +24,10 @@ import {
|
|
|
24
24
|
reattestMcpStdioPackageMaterialization,
|
|
25
25
|
resolveMcpStdioPackageMaterialization,
|
|
26
26
|
} from "./mcp-stdio-package-materialization.js";
|
|
27
|
+
import {
|
|
28
|
+
isMcpStdioCapsuleNativeCodePolicy,
|
|
29
|
+
mcpStdioCapsuleNativeCodePolicyDigest,
|
|
30
|
+
} from "./mcp-stdio-native-code-policy.js";
|
|
27
31
|
import {
|
|
28
32
|
isMcpStdioCodeInjectionEnvironmentKey,
|
|
29
33
|
sanitizeMcpStdioHostEnvironment,
|
|
@@ -48,11 +52,13 @@ export const MCP_STDIO_RUNTIME_KIND_INVALID_CODE =
|
|
|
48
52
|
export const MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND =
|
|
49
53
|
"strict-mcp-node-capsule";
|
|
50
54
|
export const MCP_STDIO_CAPSULE_CODE_SNAPSHOT_BOUNDARY = "code-snapshot";
|
|
55
|
+
export const MCP_STDIO_CAPSULE_NATIVE_ADDON_BOUNDARY = "native-addon-loading";
|
|
51
56
|
export const MCP_STDIO_CAPSULE_REQUIRED_BOUNDARIES = Object.freeze([
|
|
52
57
|
MCP_STDIO_CAPSULE_CODE_SNAPSHOT_BOUNDARY,
|
|
53
58
|
"filesystem",
|
|
54
59
|
"network",
|
|
55
60
|
"process-tree",
|
|
61
|
+
MCP_STDIO_CAPSULE_NATIVE_ADDON_BOUNDARY,
|
|
56
62
|
]);
|
|
57
63
|
|
|
58
64
|
const STORE_LABEL = "MCP stdio executable identity";
|
|
@@ -852,6 +858,10 @@ function issueCapsuleSandboxExecutionContract({
|
|
|
852
858
|
materialization,
|
|
853
859
|
}) {
|
|
854
860
|
if (!materialization) return null;
|
|
861
|
+
const nativeCodePolicy = materialization.identity?.capsule?.nativeCodePolicy;
|
|
862
|
+
if (!isMcpStdioCapsuleNativeCodePolicy(nativeCodePolicy)) {
|
|
863
|
+
throw new Error("MCP materialized capsule native-code policy is invalid");
|
|
864
|
+
}
|
|
855
865
|
const capsuleRoot = attestCapsuleRoot(materialization.capsuleRoot);
|
|
856
866
|
const entryIdentity = attestation.identity.entrypoints.find(
|
|
857
867
|
(entry) => entry.argIndex === 0,
|
|
@@ -878,6 +888,7 @@ function issueCapsuleSandboxExecutionContract({
|
|
|
878
888
|
attestation.identity.command,
|
|
879
889
|
path.resolve(process.execPath),
|
|
880
890
|
),
|
|
891
|
+
nativeCodePolicy: Object.freeze({ ...nativeCodePolicy }),
|
|
881
892
|
});
|
|
882
893
|
issuedCapsuleSandboxContracts.set(
|
|
883
894
|
contract,
|
|
@@ -888,6 +899,8 @@ function issueCapsuleSandboxExecutionContract({
|
|
|
888
899
|
cwd: capsuleRoot.realPath,
|
|
889
900
|
identityDigest: attestation.identityDigest,
|
|
890
901
|
requiredBoundaries: MCP_STDIO_CAPSULE_REQUIRED_BOUNDARIES,
|
|
902
|
+
nativeCodePolicyDigest:
|
|
903
|
+
mcpStdioCapsuleNativeCodePolicyDigest(nativeCodePolicy),
|
|
891
904
|
}),
|
|
892
905
|
);
|
|
893
906
|
return contract;
|
|
@@ -918,6 +931,9 @@ export function consumeMcpStdioCapsuleSandboxExecutionContract(
|
|
|
918
931
|
issued.requiredBoundaries.every((boundary) =>
|
|
919
932
|
requiredBoundaries.includes(boundary),
|
|
920
933
|
) &&
|
|
934
|
+
isMcpStdioCapsuleNativeCodePolicy(contract.nativeCodePolicy) &&
|
|
935
|
+
mcpStdioCapsuleNativeCodePolicyDigest(contract.nativeCodePolicy) ===
|
|
936
|
+
issued.nativeCodePolicyDigest &&
|
|
921
937
|
args.length === issued.args.length &&
|
|
922
938
|
args.every((value, index) => value === issued.args[index])
|
|
923
939
|
);
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Materialized MCP capsules are JavaScript-only products. They do not admit
|
|
5
|
+
* package-provided native addons: esbuild emits one CJS file, retains only
|
|
6
|
+
* Node builtins as externals, and the immutable capsule prelude replaces
|
|
7
|
+
* process.dlopen before package code runs. Platform runtime libraries and V8's
|
|
8
|
+
* own executable memory remain part of the trusted Node/OS runtime base and are
|
|
9
|
+
* deliberately not represented as an arbitrary shared-library closure.
|
|
10
|
+
*/
|
|
11
|
+
export const MCP_STDIO_CAPSULE_NATIVE_CODE_POLICY = Object.freeze({
|
|
12
|
+
schema: "chainlesschain.mcp-stdio-native-code-policy/v1",
|
|
13
|
+
contractVersion: 1,
|
|
14
|
+
mode: "deny-package-native-addons",
|
|
15
|
+
capsuleFormat: "single-bundled-cjs",
|
|
16
|
+
nativeAddonLoading: "denied",
|
|
17
|
+
nativeAddonDenialMechanism:
|
|
18
|
+
"immutable-process-dlopen-guard-plus-bundled-js-only-v1",
|
|
19
|
+
hostRuntimeSharedLibraries: "platform-runtime-tcb",
|
|
20
|
+
anonymousExecutableMemory: "node-runtime-tcb",
|
|
21
|
+
sharedLibraryClosure: false,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const POLICY_KEYS = Object.freeze(
|
|
25
|
+
Object.keys(MCP_STDIO_CAPSULE_NATIVE_CODE_POLICY).sort(),
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
function canonicalPolicy(value) {
|
|
29
|
+
return JSON.stringify(
|
|
30
|
+
Object.fromEntries(POLICY_KEYS.map((key) => [key, value[key]])),
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const MCP_STDIO_CAPSULE_NATIVE_CODE_POLICY_DIGEST = crypto
|
|
35
|
+
.createHash("sha256")
|
|
36
|
+
.update(canonicalPolicy(MCP_STDIO_CAPSULE_NATIVE_CODE_POLICY))
|
|
37
|
+
.digest("hex");
|
|
38
|
+
|
|
39
|
+
export function isMcpStdioCapsuleNativeCodePolicy(value) {
|
|
40
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
41
|
+
const keys = Object.keys(value).sort();
|
|
42
|
+
return (
|
|
43
|
+
keys.length === POLICY_KEYS.length &&
|
|
44
|
+
keys.every((key, index) => key === POLICY_KEYS[index]) &&
|
|
45
|
+
POLICY_KEYS.every(
|
|
46
|
+
(key) => value[key] === MCP_STDIO_CAPSULE_NATIVE_CODE_POLICY[key],
|
|
47
|
+
)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function mcpStdioCapsuleNativeCodePolicyDigest(value) {
|
|
52
|
+
if (!isMcpStdioCapsuleNativeCodePolicy(value)) {
|
|
53
|
+
throw new TypeError("MCP capsule native-code policy is invalid");
|
|
54
|
+
}
|
|
55
|
+
return crypto
|
|
56
|
+
.createHash("sha256")
|
|
57
|
+
.update(canonicalPolicy(value))
|
|
58
|
+
.digest("hex");
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function mcpStdioCapsuleNativeCodeEvidence(value) {
|
|
62
|
+
const digest = mcpStdioCapsuleNativeCodePolicyDigest(value);
|
|
63
|
+
return Object.freeze({
|
|
64
|
+
nativeCodePolicyBound: true,
|
|
65
|
+
nativeCodePolicySchema: value.schema,
|
|
66
|
+
nativeCodePolicyDigest: digest,
|
|
67
|
+
nativeCodePolicyMode: value.mode,
|
|
68
|
+
capsuleNativeCodeFormat: value.capsuleFormat,
|
|
69
|
+
nativeAddonLoading: value.nativeAddonLoading,
|
|
70
|
+
nativeAddonDenialMechanism: value.nativeAddonDenialMechanism,
|
|
71
|
+
hostRuntimeSharedLibraries: value.hostRuntimeSharedLibraries,
|
|
72
|
+
anonymousExecutableMemory: value.anonymousExecutableMemory,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
@@ -25,6 +25,10 @@ import {
|
|
|
25
25
|
writeSecurityStore,
|
|
26
26
|
} from "./durable-security-store.js";
|
|
27
27
|
import { sanitizeMcpStdioHostEnvironment } from "./mcp-stdio-environment.js";
|
|
28
|
+
import {
|
|
29
|
+
isMcpStdioCapsuleNativeCodePolicy,
|
|
30
|
+
MCP_STDIO_CAPSULE_NATIVE_CODE_POLICY,
|
|
31
|
+
} from "./mcp-stdio-native-code-policy.js";
|
|
28
32
|
|
|
29
33
|
export const MCP_STDIO_PACKAGE_MATERIALIZATION_REQUIRED_CODE =
|
|
30
34
|
"CC_MCP_STDIO_PACKAGE_MATERIALIZATION_REQUIRED";
|
|
@@ -36,9 +40,9 @@ export const MCP_STDIO_PACKAGE_MATERIALIZATION_CHANGED_CODE =
|
|
|
36
40
|
"CC_MCP_STDIO_PACKAGE_MATERIALIZATION_CHANGED";
|
|
37
41
|
|
|
38
42
|
const MATERIALIZATION_SCHEMA =
|
|
39
|
-
"chainlesschain.mcp-stdio-package-materialization/
|
|
40
|
-
const MATERIALIZATION_VERSION =
|
|
41
|
-
const CAPSULE_SCHEMA = "chainlesschain.mcp-stdio-node-capsule/
|
|
43
|
+
"chainlesschain.mcp-stdio-package-materialization/v6";
|
|
44
|
+
const MATERIALIZATION_VERSION = 6;
|
|
45
|
+
const CAPSULE_SCHEMA = "chainlesschain.mcp-stdio-node-capsule/v5";
|
|
42
46
|
const CAPSULE_RELATIVE_PATH = "capsule/server.cjs";
|
|
43
47
|
const CAPSULE_BUILDER = "esbuild-wasm";
|
|
44
48
|
const CAPSULE_BUILDER_VERSION = "0.28.1";
|
|
@@ -1504,6 +1508,7 @@ async function buildCapsule({
|
|
|
1504
1508
|
? CAPSULE_EXECUTION_CONTEXT_ISOLATION
|
|
1505
1509
|
: "not-required",
|
|
1506
1510
|
}),
|
|
1511
|
+
nativeCodePolicy: MCP_STDIO_CAPSULE_NATIVE_CODE_POLICY,
|
|
1507
1512
|
});
|
|
1508
1513
|
}
|
|
1509
1514
|
|
|
@@ -1563,6 +1568,7 @@ function validateManifest(manifest) {
|
|
|
1563
1568
|
) ||
|
|
1564
1569
|
manifest.capsule?.builtinPolicy?.schema !== CAPSULE_BUILTIN_POLICY_SCHEMA ||
|
|
1565
1570
|
manifest.capsule?.builtinPolicy?.mode !== "static-external-only" ||
|
|
1571
|
+
!isMcpStdioCapsuleNativeCodePolicy(manifest.capsule?.nativeCodePolicy) ||
|
|
1566
1572
|
!Array.isArray(manifest.capsule?.builtinPolicy?.allowedBuiltins) ||
|
|
1567
1573
|
manifest.capsule.builtinPolicy.allowedBuiltins.some(
|
|
1568
1574
|
(name) => typeof name !== "string" || !NODE_BUILTINS.has(name),
|
|
@@ -1743,6 +1749,9 @@ function verifyPublishedGeneration(root, record, expectedFingerprint) {
|
|
|
1743
1749
|
...manifest.capsule.builtinPolicy.executionContextBuiltins,
|
|
1744
1750
|
]),
|
|
1745
1751
|
}),
|
|
1752
|
+
nativeCodePolicy: Object.freeze({
|
|
1753
|
+
...manifest.capsule.nativeCodePolicy,
|
|
1754
|
+
}),
|
|
1746
1755
|
}),
|
|
1747
1756
|
closureDigest: manifest.closureDigest,
|
|
1748
1757
|
fileCount: manifest.fileCount,
|