chainlesschain 0.162.197 → 0.162.200
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/bin/chainlesschain.js +14 -6
- package/package.json +4 -1
- package/scripts/command-lifecycle-report.mjs +94 -0
- package/src/assets/web-panel/assets/{AIOps-D3Gu1a5d.js → AIOps-DcQ0bWKy.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DrwAoKaz.js → ActionButton-GecwfFPt.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-C7Q-gd_3.js → Analytics-CD6iSt9v.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-DgBtae-n.js → AppLayout-CDEtuEYf.js} +5 -5
- package/src/assets/web-panel/assets/{Artifacts-pQ6LcA-W.js → Artifacts-DS3jAjeW.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-DK61tocB.js → Audit-CcSJA048.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BOKgDFRh.js → BackgroundAgents-DRo9Morb.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-Bo9G4vTP.js → Backup-Vw5MrWft.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-Do_dE9_v.js → BaseInput-DNHIu823.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-COVvZzOL.js → Chat-DvAsO8-b.js} +4 -4
- package/src/assets/web-panel/assets/ChatBubbleRenderer-9aDuObay.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-Z9MJMolt.js → Checkbox-CKCa7tvn.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-BVzWKVbf.js → Codegen-CIFvZdaT.js} +1 -1
- package/src/assets/web-panel/assets/{Col-C8MnYcbT.js → Col-C79yz7bK.js} +1 -1
- package/src/assets/web-panel/assets/{Community-DQxqw15l.js → Community-DVvZskLJ.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-BAUmrh3y.js → Compact-oaew61hV.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-jPAkQ3zK.js → Compliance-DqA7wmRx.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-BBQyxbh8.js → Cowork-B-qGadxa.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-W5koq8Z5.js → Cron-CUlCl4sS.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-BQhnu5hS.js → Crosschain-CNOlr9DU.js} +1 -1
- package/src/assets/web-panel/assets/{DID-DD7PlI18.js → DID-DJqFCT_3.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-w_ILuwKI.js → Dashboard-CznGpphf.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-qiDUAyAo.js → Dropdown-_cJw218E.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-PDeBcI5H.js → EmailListRenderer-Dr-1BZ9C.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-SuArscRM.js → FamilyGuardDashboard-Dxf4xtSk.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BCovZaUn.js → Federation-DOiG3i_1.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-DjlFdVFk.js → FormItemContext-BzbMcFB9.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DoEZ7fcS.js → GenericCardRenderer-VbBrYttP.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CV0-6GPI.js → Git-CLG8E6ED.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-B_SFN50w.js → Governance-LGJQfk_q.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-heI0Eo6k.js → Inference-DlQKx9lF.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-Cz5INS5p.js → KnowledgeGraph-DU8vEouV.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BSFxiHkg.js → Logs-FZIQOdln.js} +2 -2
- package/src/assets/web-panel/assets/MarkdownRenderer-BJNWIrbw.js +1 -0
- package/src/assets/web-panel/assets/{Marketplace-0TWTpE7k.js → Marketplace-C_xd-zZI.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-CV4-wBLm.js → McpTools-q-YktphS.js} +5 -5
- package/src/assets/web-panel/assets/{Memory-x5bH5rw5.js → Memory-Cq9OhDin.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-DaBmUu9G.js → MobileBridge-B03_R98T.js} +1 -1
- package/src/assets/web-panel/assets/MobileProjects-DZrk-qmF.js +1 -0
- package/src/assets/web-panel/assets/{Mtc-B_zKEBif.js → Mtc-BidCKW28.js} +5 -5
- package/src/assets/web-panel/assets/{MtcAudit-BCfKD2yg.js → MtcAudit-r-iaMVM7.js} +2 -2
- package/src/assets/web-panel/assets/{Multisig-DgYfj6c_.js → Multisig-CgTUFvff.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-Dz09lFUm.js → NLProgramming-B7NvzfAV.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-Cuj6ugBE.js → Notes-80CWNqJI.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-DK2WXjhg.js → NotificationSettings-0H6xdiY3.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-D1IAOQoo.js → OrderTableRenderer-CKP4AFWy.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-9fqnPvTw.js → Organization-B8sxCV_h.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-n5xHkhow.js → Overflow-CW9JBBhQ.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-B5AUWwH-.js → P2P-bdSQV7oZ.js} +2 -2
- package/src/assets/web-panel/assets/{PdhVaultBrowser-CoUDV6dy.js → PdhVaultBrowser-DQad42nW.js} +4 -4
- package/src/assets/web-panel/assets/{Permissions-DPRmQf_H.js → Permissions-CueexxTR.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-B37bsbEN.js → PersonalDataHub-fqxflhR8.js} +6 -6
- package/src/assets/web-panel/assets/{Pipeline-CCAuPqu9.js → Pipeline-KFwwnIMC.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-B81msZdv.js → Privacy-ClnD9buY.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-B-Py2NbF.js → ProjectInit-CZEz6sm3.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-CYsneiRB.js → ProjectSettings-B6NzpmOI.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-Y975Mh6R.js → Projects-DYyuwPCs.js} +1 -1
- package/src/assets/web-panel/assets/Providers-C3tz_jdh.js +1 -0
- package/src/assets/web-panel/assets/{QrScannerModal-Bj_6gJ0l.js → QrScannerModal-BzuOBbqB.js} +1 -1
- package/src/assets/web-panel/assets/{QuickAsk-BgpBCMPE.js → QuickAsk-CmNO9qSj.js} +1 -1
- package/src/assets/web-panel/assets/{Recommend-DhUW3YUA.js → Recommend-VJNj3_NF.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-DdeyfbkA.js → RemoteSession-CrbdbSBF.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-fxW421xd.js → Reputation-DTyMd45j.js} +1 -1
- package/src/assets/web-panel/assets/{Row-De73w1og.js → Row-DHrQ-Icz.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-3US_Q_lj.js → RssFeed-DqWxY9c5.js} +2 -2
- package/src/assets/web-panel/assets/{Search-DbZ_DU74.js → Search-ctF1Ks3J.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DoIU1vMF.js → Security-BrQz8uo5.js} +4 -4
- package/src/assets/web-panel/assets/{Services-DB_RGqpc.js → Services-D4scVFar.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-DnzLaayC.js → Skeleton-oUScaOjv.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-VzVXHENF.js → Skills-CL-y0eLt.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DMfvjCAI.js → Sla-DQExhwXj.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-DQQOYWbF.js → SpeechSettings-iNp_I7kN.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Bmx3FG1P.js → SyncSettings-CTDlMo0A.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-DOQyfb-2.js → Tasks-4kb8l3sc.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-D6hTRT7c.js → Templates-BXcL9oXW.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-CTPQZAzs.js → Tenant-DLE8eS0D.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-B7vII3oH.js → Terminal-DGpUZPPK.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BkiFJeXV.js → TimelineRenderer-C1pWXGPC.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-BPPdQMNo.js → Tokens-BYfbfqhZ.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BxG8JAEI.js → Trigger-K9YfLOCw.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-DHD7nMpM.js → Trust-Ctkq77Hy.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-B4BJpU47.js → UkeySign-C6_CSe9J.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-CRiGpFx2.js → VideoEditing-Be3rpOWs.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-BSDSNiem.js → Wallet-D0UIplxk.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-DLTUh5Zv.js → WebAuthn-CF9bM9I3.js} +5 -5
- package/src/assets/web-panel/assets/{WorkflowEditor-tW2MwjhD.js → WorkflowEditor-D0H1XVPY.js} +1 -1
- package/src/assets/web-panel/assets/{chat-SgsLQ3FC.js → chat-Cgzzbe0o.js} +1 -1
- package/src/assets/web-panel/assets/{colors-BHjjLIKO.js → colors-BwNxEVS0.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-VceErdKq.js → compact-item-D60Z4Hhs.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-BZ332MYl.js → createContext-MFk58XB0.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BJiw369i.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CBTjJOjn.js → hasIn-CRj2SvGO.js} +1 -1
- package/src/assets/web-panel/assets/{index-DaCCy6lq.js → index--s45_1cb.js} +1 -1
- package/src/assets/web-panel/assets/{index-CMVvxIS8.js → index--tquQ2ZG.js} +1 -1
- package/src/assets/web-panel/assets/{index-BhXZEUAc.js → index-1T1rhokn.js} +1 -1
- package/src/assets/web-panel/assets/{index-BQSmZGgs.js → index-B-M82_rx.js} +1 -1
- package/src/assets/web-panel/assets/{index-BeiqkxJG.js → index-BE_el1Zs.js} +1 -1
- package/src/assets/web-panel/assets/{index-29wVzi-k.js → index-BhRkR7IO.js} +1 -1
- package/src/assets/web-panel/assets/{index-iYQNU9za.js → index-Bo0y96-K.js} +1 -1
- package/src/assets/web-panel/assets/{index-BRWhLbWF.js → index-CJgu5JUK.js} +1 -1
- package/src/assets/web-panel/assets/{index-BPXFLYdW.js → index-CLWwdebO.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cr4rjlW5.js → index-CNAK5QG_.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaIS_TNX.js → index-CQjJjPRD.js} +1 -1
- package/src/assets/web-panel/assets/{index-1n7xjKDU.js → index-CTDbAfae.js} +1 -1
- package/src/assets/web-panel/assets/{index-BETEjuNr.js → index-CVI_9sRK.js} +1 -1
- package/src/assets/web-panel/assets/{index-By5jBtkV.js → index-CY14oMQK.js} +1 -1
- package/src/assets/web-panel/assets/{index-DgPvuIn2.js → index-CbiTJkZf.js} +1 -1
- package/src/assets/web-panel/assets/index-CiMouosn.js +1 -0
- package/src/assets/web-panel/assets/{index-CawpdGTW.js → index-CqWpxMqx.js} +1 -1
- package/src/assets/web-panel/assets/{index-_PHrIO4O.js → index-CvB8lYUR.js} +1 -1
- package/src/assets/web-panel/assets/{index-BOtvPdHt.js → index-D51XwtCY.js} +1 -1
- package/src/assets/web-panel/assets/{index-CrUgDQkf.js → index-D6HvK_1O.js} +1 -1
- package/src/assets/web-panel/assets/{index-BY1wexYG.js → index-D9jVIwLJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-C_B9rFQE.js → index-DA4tE98u.js} +1 -1
- package/src/assets/web-panel/assets/{index-B5KAGxNo.js → index-DBwOtXw0.js} +1 -1
- package/src/assets/web-panel/assets/{index-BC1xuQgX.js → index-DKdNzTIb.js} +1 -1
- package/src/assets/web-panel/assets/{index-B2u26AS3.js → index-DRySdmvN.js} +1 -1
- package/src/assets/web-panel/assets/{index-DePOeMDM.js → index-DWzyTev7.js} +1 -1
- package/src/assets/web-panel/assets/index-DXcKlwy7.js +1 -0
- package/src/assets/web-panel/assets/{index-BTlc-Bve.js → index-DYjs7jAP.js} +1 -1
- package/src/assets/web-panel/assets/{index-CLc19alH.js → index-DbROzMBp.js} +1 -1
- package/src/assets/web-panel/assets/{index-fU7wNHDB.js → index-DhFtk5PR.js} +1 -1
- package/src/assets/web-panel/assets/{index-D_SePDWj.js → index-Di2AbMLg.js} +1 -1
- package/src/assets/web-panel/assets/{index-vIXOpcjD.js → index-DvmocQsM.js} +1 -1
- package/src/assets/web-panel/assets/{index-BcUenmCX.js → index-Dw-o0zEF.js} +1 -1
- package/src/assets/web-panel/assets/{index-DUkVN794.js → index-DysPoP38.js} +1 -1
- package/src/assets/web-panel/assets/{index-CtjLcCNU.js → index-LX9pJxm_.js} +1 -1
- package/src/assets/web-panel/assets/{index-B40dQn0G.js → index-OI_fXWx0.js} +3 -3
- package/src/assets/web-panel/assets/{index-FJ3zC9LK.js → index-eDTOX8Xj.js} +1 -1
- package/src/assets/web-panel/assets/{index-DdefYBSw.js → index-gWKDsTzF.js} +1 -1
- package/src/assets/web-panel/assets/{index-CpumS98o.js → index-q_GDUVAA.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-D1oZNz0D.js → initDefaultProps-C61kZqEd.js} +1 -1
- package/src/assets/web-panel/assets/{motion-C8k6doMO.js → motion-DZnT5U1L.js} +1 -1
- package/src/assets/web-panel/assets/{move-DJ4qSbYt.js → move-L8wzwbel.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-CdpJD85j.js → mtc-parser-DLdYSejc.js} +1 -1
- package/src/assets/web-panel/assets/{omit-B0V4slKA.js → omit-D53cbS59.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-Di5NiW1F.js → pickAttrs-Bbc5HPtu.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-B5OMHgEM.js → placementArrow-BkvmO860.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-C6U9IWql.js → responsiveObserve-u2y1ryS1.js} +1 -1
- package/src/assets/web-panel/assets/{slide-BMyTH3rN.js → slide-BBqj7svU.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-C7d6BG7Z.js → statusUtils-GN0mqu2d.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-CR50QnQy.js → styleChecker-BvwPKoBT.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-DBEeoMb8.js → useFlexGapSupport-CCt8tnfY.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-3r099cjv.js → useFs-DXAxl2SV.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-C5IYNdTK.js → usePersonalDataHub-DihlR2dj.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-DmEOLRHf.js → vnode-D7BOX2gi.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-DnpUiVCB.js → zoom-CVbO-nL7.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +4 -4
- package/src/commands/agent.js +3 -3
- package/src/commands/background-session.js +145 -0
- package/src/commands/mcp.js +244 -7
- package/src/commands/serve.js +1 -1
- package/src/commands/session-show.js +129 -0
- package/src/commands/session.js +97 -145
- package/src/commands/skill.js +87 -50
- package/src/data/changelog.json +40 -1
- package/src/gateways/ws/session-protocol.js +14 -4
- package/src/gateways/ws/ws-agent-handler.js +39 -1
- package/src/harness/jsonl-session-store.js +1547 -127
- package/src/harness/mcp-client.js +2690 -409
- package/src/harness/session-index.js +80 -80
- package/src/harness/session-list-index.js +210 -7
- package/src/lazy-dispatch.js +76 -8
- package/src/lib/abort-utils.js +68 -0
- package/src/lib/agent-core.js +1 -59
- package/src/lib/background-interaction-journal.js +2 -2
- package/src/lib/chat-core.js +24 -6
- package/src/lib/command-lifecycle-report.js +516 -0
- package/src/lib/cowork-mcp-tools.js +47 -2
- package/src/lib/cowork-task-runner.js +11 -3
- package/src/lib/doctor-checkup.js +9 -7
- package/src/lib/learning/skill-improver.js +21 -2
- package/src/lib/mcp-call-ledger-store.js +116 -3
- package/src/lib/mcp-call-ledger.js +59 -14
- package/src/lib/mcp-client.js +1 -0
- package/src/lib/mcp-stdio-environment.js +48 -0
- package/src/lib/mcp-stdio-executable-identity.js +1133 -0
- package/src/lib/mcp-stdio-execution-authority.js +363 -0
- package/src/lib/mcp-stdio-package-materialization.js +1424 -0
- package/src/lib/mcp-tool-metadata.js +436 -0
- package/src/lib/mcp-tool-result.js +367 -0
- package/src/lib/observability/index.js +71 -0
- package/src/lib/packer/native-update-state.js +979 -1
- package/src/lib/packer/pack-update-applier.js +1050 -125
- package/src/lib/packer/pkg-config-generator.js +1 -0
- package/src/lib/paths.js +53 -0
- package/src/lib/pr-link-ledger.js +8 -27
- package/src/lib/pr-link-store.js +26 -0
- package/src/lib/process-execution-broker/index.js +192 -35
- package/src/lib/process-execution-broker/platform-sandbox.js +291 -24
- package/src/lib/process-tree-termination.js +253 -0
- package/src/lib/recent-session.js +17 -17
- package/src/lib/secure-file-identity.js +47 -0
- package/src/lib/secure-fs.js +21 -2
- package/src/lib/session-anti-rollback-anchor.js +766 -0
- package/src/lib/session-host-lease.js +492 -0
- package/src/lib/session-host-snapshot.js +9 -5
- package/src/lib/session-persistence-failure.js +109 -0
- package/src/lib/session-picker.js +26 -3
- package/src/lib/session-projection.js +5 -1
- package/src/lib/session-search.js +25 -11
- package/src/lib/session-tail.js +31 -1
- package/src/lib/side-effect-ledger-store.js +2 -2
- package/src/lib/skill-budget.js +222 -0
- package/src/lib/skill-execution-authority.js +385 -0
- package/src/lib/skill-execution-identity.js +39 -2
- package/src/lib/skill-loader.js +322 -86
- package/src/lib/skill-mcp.js +43 -1
- package/src/lib/turn-binding-store.js +2 -2
- package/src/repl/agent-repl.js +483 -77
- package/src/repl/bg-dashboard.js +81 -28
- package/src/repl/chat-repl.js +77 -12
- package/src/runtime/agent-core.js +428 -113
- package/src/runtime/agent-runtime.js +26 -3
- package/src/runtime/cleanup-deadline.js +143 -0
- package/src/runtime/headless-runner.js +494 -149
- package/src/runtime/headless-stream.js +504 -75
- package/src/runtime/mcp-config.js +157 -10
- package/src/runtime/mcp-tool-search.js +0 -0
- package/src/runtime/output-backpressure.js +419 -0
- package/src/runtime/pipe-safety.js +56 -21
- package/src/assets/web-panel/assets/ChatBubbleRenderer-BUUyJ5QO.js +0 -1
- package/src/assets/web-panel/assets/MarkdownRenderer-1mNozZ8v.js +0 -1
- package/src/assets/web-panel/assets/MobileProjects-DqnoFPgR.js +0 -1
- package/src/assets/web-panel/assets/Providers-uO-10aP1.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DosMaL-k.js +0 -1
- package/src/assets/web-panel/assets/index-0O5ePnUq.js +0 -1
- package/src/assets/web-panel/assets/index-ChAzPigF.js +0 -1
- package/src/lib/skill-process-broker.js +0 -85
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
* the selected backend; it does not merely describe a configured intent.
|
|
38
38
|
*/
|
|
39
39
|
export const SANDBOX_BOUNDARIES = Object.freeze({
|
|
40
|
+
CODE_SNAPSHOT: "code-snapshot",
|
|
40
41
|
FILESYSTEM: "filesystem",
|
|
41
42
|
NETWORK: "network",
|
|
42
43
|
PROCESS_EXEC: "process-exec",
|
|
@@ -105,6 +106,7 @@ const WINDOWS_IDENTITY_WAIT = new Int32Array(new SharedArrayBuffer(4));
|
|
|
105
106
|
const WINDOWS_RESTRICTED_TOKEN_BACKEND = "windows-job-restricted-token";
|
|
106
107
|
const WINDOWS_APPCONTAINER_BACKEND =
|
|
107
108
|
"windows-appcontainer-job-restricted-token";
|
|
109
|
+
const MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND = "strict-mcp-node-capsule";
|
|
108
110
|
const WINDOWS_ADAPTER_IDLE_TTL_MS = 60_000;
|
|
109
111
|
// Every native helper operation starts a trusted System32 PowerShell host and
|
|
110
112
|
// byte-loads the checked-in assembly. Hosted Windows runners can spend well
|
|
@@ -163,6 +165,11 @@ const LINUX_ATTESTATION_HASH_CHUNK_BYTES = 1024 * 1024;
|
|
|
163
165
|
const LINUX_ENTRY_SNAPSHOT_MECHANISM =
|
|
164
166
|
"verified-o_tmpfile-copy-bwrap-ro-bind-data-v1";
|
|
165
167
|
const LINUX_ENTRY_SNAPSHOT_SOURCE_MODE = 0o400;
|
|
168
|
+
const LINUX_EXECUTABLE_SNAPSHOT_SOURCE_MODE = 0o500;
|
|
169
|
+
const LINUX_MCP_CAPSULE_BACKEND = "linux-fd-code-snapshot";
|
|
170
|
+
const LINUX_MCP_RUNTIME_SNAPSHOT_SCOPE = "mcp-node-runtime-executable";
|
|
171
|
+
const LINUX_MCP_CAPSULE_SNAPSHOT_MECHANISM =
|
|
172
|
+
"verified-o_tmpfile-copy-inherited-fd-exec-v1";
|
|
166
173
|
const LINUX_NODE_ENTRY_SNAPSHOT_SCOPE = "plugin-entry-source";
|
|
167
174
|
const LINUX_NATIVE_ENTRY_SNAPSHOT_SCOPE = "plugin-entry-executable";
|
|
168
175
|
const LINUX_NODE_PLUGIN_TREE_SNAPSHOT_SCOPE = "all-pinned-plugin-regular-files";
|
|
@@ -1884,13 +1891,18 @@ function windowsSandboxHostEnvironment(runtime) {
|
|
|
1884
1891
|
function windowsPluginNodeEntrySnapshot(invocation, sandboxOpts, spawnOpts) {
|
|
1885
1892
|
const contract = sandboxOpts.executionContract;
|
|
1886
1893
|
if (!contract) return { locks: null, reason: null };
|
|
1887
|
-
|
|
1894
|
+
const capsuleContract =
|
|
1895
|
+
contract.kind === MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND;
|
|
1896
|
+
if (contract.kind !== "strict-plugin-node-bin" && !capsuleContract) {
|
|
1888
1897
|
return {
|
|
1889
1898
|
locks: null,
|
|
1890
1899
|
reason: "windows_plugin_execution_contract_unsupported",
|
|
1891
1900
|
};
|
|
1892
1901
|
}
|
|
1893
|
-
if (
|
|
1902
|
+
if (
|
|
1903
|
+
(!capsuleContract && sandboxOpts.sync !== true) ||
|
|
1904
|
+
spawnOpts?.detached === true
|
|
1905
|
+
) {
|
|
1894
1906
|
return {
|
|
1895
1907
|
locks: null,
|
|
1896
1908
|
reason: "windows_plugin_launch_path_lock_requires_sync_foreground",
|
|
@@ -2586,10 +2598,34 @@ export function applyWindowsSandbox(
|
|
|
2586
2598
|
? {
|
|
2587
2599
|
...(appContainerRuntimeProbe || nodeSnapshotRuntimeProbe),
|
|
2588
2600
|
contentSnapshot: true,
|
|
2589
|
-
contentSnapshotScope:
|
|
2601
|
+
contentSnapshotScope:
|
|
2602
|
+
sandboxOpts.executionContract?.kind ===
|
|
2603
|
+
MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND
|
|
2604
|
+
? "mcp-capsule-entry-source"
|
|
2605
|
+
: "plugin-entry-source",
|
|
2590
2606
|
contentSnapshotMechanism:
|
|
2591
2607
|
"verified-handle-inherited-pipe-module-compile-v1",
|
|
2592
2608
|
handleAtomic: false,
|
|
2609
|
+
...(sandboxOpts.executionContract?.kind ===
|
|
2610
|
+
MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND
|
|
2611
|
+
? {
|
|
2612
|
+
runtimeAttestedSha256: entrySnapshot.locks.find(
|
|
2613
|
+
({ role }) => role === "runtime",
|
|
2614
|
+
)?.sha256,
|
|
2615
|
+
runtimeAttestedBytes: entrySnapshot.locks.find(
|
|
2616
|
+
({ role }) => role === "runtime",
|
|
2617
|
+
)?.bytes,
|
|
2618
|
+
entrySnapshotSha256: entrySnapshot.locks.find(
|
|
2619
|
+
({ role }) => role === "entry",
|
|
2620
|
+
)?.sha256,
|
|
2621
|
+
entrySnapshotBytes: entrySnapshot.locks.find(
|
|
2622
|
+
({ role }) => role === "entry",
|
|
2623
|
+
)?.bytes,
|
|
2624
|
+
entrySnapshotAtomic: true,
|
|
2625
|
+
runtimeLaunchAtomic: false,
|
|
2626
|
+
sharedLibraryClosure: false,
|
|
2627
|
+
}
|
|
2628
|
+
: {}),
|
|
2593
2629
|
}
|
|
2594
2630
|
: appContainerRuntimeProbe;
|
|
2595
2631
|
return createSandboxPlan({
|
|
@@ -2599,13 +2635,20 @@ export function applyWindowsSandbox(
|
|
|
2599
2635
|
policyAttested: requiresAppContainer ? true : null,
|
|
2600
2636
|
policyDigest: appContainerPolicyDigest,
|
|
2601
2637
|
runtimeProbe: entrySnapshotRuntimeProbe,
|
|
2602
|
-
guarantees:
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2638
|
+
guarantees: [
|
|
2639
|
+
...(requiresAppContainer
|
|
2640
|
+
? appContainerGuarantees
|
|
2641
|
+
: [
|
|
2642
|
+
SANDBOX_BOUNDARIES.PROCESS_TREE,
|
|
2643
|
+
SANDBOX_BOUNDARIES.RESOURCE_LIMITS,
|
|
2644
|
+
SANDBOX_BOUNDARIES.PRIVILEGE_REDUCTION,
|
|
2645
|
+
]),
|
|
2646
|
+
...(entrySnapshot.locks &&
|
|
2647
|
+
sandboxOpts.executionContract?.kind ===
|
|
2648
|
+
MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND
|
|
2649
|
+
? [SANDBOX_BOUNDARIES.CODE_SNAPSHOT]
|
|
2650
|
+
: []),
|
|
2651
|
+
],
|
|
2609
2652
|
command: helperInvocation.command,
|
|
2610
2653
|
args: helperInvocation.args,
|
|
2611
2654
|
options,
|
|
@@ -3042,7 +3085,10 @@ function validateLinuxPluginContract(
|
|
|
3042
3085
|
sync,
|
|
3043
3086
|
{ sealedEntry = false } = {},
|
|
3044
3087
|
) {
|
|
3045
|
-
const
|
|
3088
|
+
const capsuleContract =
|
|
3089
|
+
contract?.kind === MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND;
|
|
3090
|
+
const nodeContract =
|
|
3091
|
+
contract?.kind === "strict-plugin-node-bin" || capsuleContract;
|
|
3046
3092
|
const legacyStaticNativeContract =
|
|
3047
3093
|
contract?.kind === "strict-plugin-native-static-elf-bin";
|
|
3048
3094
|
const nativeContract =
|
|
@@ -3060,7 +3106,7 @@ function validateLinuxPluginContract(
|
|
|
3060
3106
|
if (
|
|
3061
3107
|
(sync !== true && sync !== false) ||
|
|
3062
3108
|
spawnOpts?.shell !== false ||
|
|
3063
|
-
spawnOpts?.detached === true ||
|
|
3109
|
+
(spawnOpts?.detached === true && !capsuleContract) ||
|
|
3064
3110
|
!linuxStdioIsNarrow(spawnOpts?.stdio) ||
|
|
3065
3111
|
spawnOpts?.serialization !== undefined ||
|
|
3066
3112
|
spawnOpts?.argv0 !== undefined ||
|
|
@@ -3274,6 +3320,7 @@ function linuxEntrySnapshotContract(targetRuntime) {
|
|
|
3274
3320
|
return {
|
|
3275
3321
|
scope: LINUX_NATIVE_ENTRY_SNAPSHOT_SCOPE,
|
|
3276
3322
|
targetMode: LINUX_NATIVE_ENTRY_SNAPSHOT_TARGET_MODE,
|
|
3323
|
+
sourceMode: LINUX_ENTRY_SNAPSHOT_SOURCE_MODE,
|
|
3277
3324
|
minimumBytes: LINUX_ELF64_HEADER_BYTES,
|
|
3278
3325
|
errorPrefix: "native_entry_snapshot",
|
|
3279
3326
|
};
|
|
@@ -3282,6 +3329,7 @@ function linuxEntrySnapshotContract(targetRuntime) {
|
|
|
3282
3329
|
return {
|
|
3283
3330
|
scope: LINUX_NODE_ENTRY_SNAPSHOT_SCOPE,
|
|
3284
3331
|
targetMode: LINUX_NODE_ENTRY_SNAPSHOT_TARGET_MODE,
|
|
3332
|
+
sourceMode: LINUX_ENTRY_SNAPSHOT_SOURCE_MODE,
|
|
3285
3333
|
minimumBytes: 0,
|
|
3286
3334
|
errorPrefix: "node_entry_snapshot",
|
|
3287
3335
|
};
|
|
@@ -3296,11 +3344,22 @@ function linuxNodePluginTreeFileSnapshotContract(sourceMode) {
|
|
|
3296
3344
|
return {
|
|
3297
3345
|
scope: LINUX_NODE_PLUGIN_TREE_SNAPSHOT_SCOPE,
|
|
3298
3346
|
targetMode: (sourceMode & 0o111) !== 0 ? "0500" : "0400",
|
|
3347
|
+
sourceMode: LINUX_ENTRY_SNAPSHOT_SOURCE_MODE,
|
|
3299
3348
|
minimumBytes: 0,
|
|
3300
3349
|
errorPrefix: "node_plugin_tree_snapshot",
|
|
3301
3350
|
};
|
|
3302
3351
|
}
|
|
3303
3352
|
|
|
3353
|
+
function linuxMcpRuntimeSnapshotContract() {
|
|
3354
|
+
return {
|
|
3355
|
+
scope: LINUX_MCP_RUNTIME_SNAPSHOT_SCOPE,
|
|
3356
|
+
targetMode: "0500",
|
|
3357
|
+
sourceMode: LINUX_EXECUTABLE_SNAPSHOT_SOURCE_MODE,
|
|
3358
|
+
minimumBytes: 1,
|
|
3359
|
+
errorPrefix: "mcp_node_runtime_snapshot",
|
|
3360
|
+
};
|
|
3361
|
+
}
|
|
3362
|
+
|
|
3304
3363
|
function createLinuxRegularFileSnapshot(
|
|
3305
3364
|
runtime,
|
|
3306
3365
|
entryMount,
|
|
@@ -3311,10 +3370,16 @@ function createLinuxRegularFileSnapshot(
|
|
|
3311
3370
|
let probeFd;
|
|
3312
3371
|
let finalFd;
|
|
3313
3372
|
try {
|
|
3373
|
+
const snapshotSourceMode = snapshotContract?.sourceMode;
|
|
3314
3374
|
if (
|
|
3315
3375
|
!snapshotContract ||
|
|
3316
3376
|
typeof snapshotContract.scope !== "string" ||
|
|
3317
3377
|
typeof snapshotContract.targetMode !== "string" ||
|
|
3378
|
+
!Number.isSafeInteger(snapshotSourceMode) ||
|
|
3379
|
+
![
|
|
3380
|
+
LINUX_ENTRY_SNAPSHOT_SOURCE_MODE,
|
|
3381
|
+
LINUX_EXECUTABLE_SNAPSHOT_SOURCE_MODE,
|
|
3382
|
+
].includes(snapshotSourceMode) ||
|
|
3318
3383
|
!Number.isSafeInteger(snapshotContract.minimumBytes) ||
|
|
3319
3384
|
typeof snapshotContract.errorPrefix !== "string"
|
|
3320
3385
|
) {
|
|
@@ -3369,7 +3434,8 @@ function createLinuxRegularFileSnapshot(
|
|
|
3369
3434
|
throw snapshotError("source_mode_changed");
|
|
3370
3435
|
}
|
|
3371
3436
|
if (
|
|
3372
|
-
snapshotContract.scope === LINUX_NATIVE_ENTRY_SNAPSHOT_SCOPE
|
|
3437
|
+
(snapshotContract.scope === LINUX_NATIVE_ENTRY_SNAPSHOT_SCOPE ||
|
|
3438
|
+
snapshotContract.scope === LINUX_MCP_RUNTIME_SNAPSHOT_SCOPE) &&
|
|
3373
3439
|
(sourceFileMode & 0o111) === 0
|
|
3374
3440
|
) {
|
|
3375
3441
|
throw snapshotError("source_mode_changed");
|
|
@@ -3382,11 +3448,7 @@ function createLinuxRegularFileSnapshot(
|
|
|
3382
3448
|
Number(constants.O_TMPFILE ?? LINUX_O_TMPFILE) |
|
|
3383
3449
|
Number(constants.O_NOFOLLOW || 0) |
|
|
3384
3450
|
Number(constants.O_NONBLOCK || 0);
|
|
3385
|
-
writerFd = runtime.fs.openSync(
|
|
3386
|
-
"/tmp",
|
|
3387
|
-
writerFlags,
|
|
3388
|
-
LINUX_ENTRY_SNAPSHOT_SOURCE_MODE,
|
|
3389
|
-
);
|
|
3451
|
+
writerFd = runtime.fs.openSync("/tmp", writerFlags, snapshotSourceMode);
|
|
3390
3452
|
|
|
3391
3453
|
const sourceDigest = crypto.createHash("sha256");
|
|
3392
3454
|
const chunk = Buffer.allocUnsafe(
|
|
@@ -3455,15 +3517,14 @@ function createLinuxRegularFileSnapshot(
|
|
|
3455
3517
|
throw snapshotError("identity_changed");
|
|
3456
3518
|
}
|
|
3457
3519
|
|
|
3458
|
-
runtime.fs.fchmodSync(writerFd,
|
|
3520
|
+
runtime.fs.fchmodSync(writerFd, snapshotSourceMode);
|
|
3459
3521
|
runtime.fs.fsyncSync(writerFd);
|
|
3460
3522
|
const sealedBeforeRead = runtime.fs.fstatSync(writerFd);
|
|
3461
3523
|
if (
|
|
3462
3524
|
!sealedBeforeRead.isFile() ||
|
|
3463
3525
|
Number(sealedBeforeRead.nlink) !== 0 ||
|
|
3464
3526
|
Number(sealedBeforeRead.size) !== entryIdentity.bytes ||
|
|
3465
|
-
(Number(sealedBeforeRead.mode) & 0o777) !==
|
|
3466
|
-
LINUX_ENTRY_SNAPSHOT_SOURCE_MODE
|
|
3527
|
+
(Number(sealedBeforeRead.mode) & 0o777) !== snapshotSourceMode
|
|
3467
3528
|
) {
|
|
3468
3529
|
throw snapshotError("readonly_mode_unattested");
|
|
3469
3530
|
}
|
|
@@ -3513,7 +3574,7 @@ function createLinuxRegularFileSnapshot(
|
|
|
3513
3574
|
}),
|
|
3514
3575
|
sourceMtimeMs: Number(entryIdentity.mtimeMs),
|
|
3515
3576
|
sourceFileMode: sourceFileMode.toString(8).padStart(4, "0"),
|
|
3516
|
-
sourceMode:
|
|
3577
|
+
sourceMode: snapshotSourceMode.toString(8).padStart(4, "0"),
|
|
3517
3578
|
targetMode: snapshotContract.targetMode,
|
|
3518
3579
|
});
|
|
3519
3580
|
const descriptor = (fd) => {
|
|
@@ -3581,12 +3642,13 @@ function attestLinuxRegularFileSnapshot(
|
|
|
3581
3642
|
snapshotContract,
|
|
3582
3643
|
) {
|
|
3583
3644
|
const errorPrefix = snapshotContract.errorPrefix;
|
|
3645
|
+
const snapshotSourceMode = snapshotContract.sourceMode;
|
|
3584
3646
|
const before = runtime.fs.fstatSync(mount?.fd);
|
|
3585
3647
|
if (
|
|
3586
3648
|
attestation?.scope !== snapshotContract.scope ||
|
|
3587
3649
|
attestation?.mechanism !== LINUX_ENTRY_SNAPSHOT_MECHANISM ||
|
|
3588
3650
|
attestation?.sourceMode !==
|
|
3589
|
-
|
|
3651
|
+
snapshotSourceMode.toString(8).padStart(4, "0") ||
|
|
3590
3652
|
typeof attestation?.sourceFileMode !== "string" ||
|
|
3591
3653
|
!/^[0-7]{4}$/.test(attestation.sourceFileMode) ||
|
|
3592
3654
|
attestation?.targetMode !== snapshotContract.targetMode ||
|
|
@@ -3595,7 +3657,7 @@ function attestLinuxRegularFileSnapshot(
|
|
|
3595
3657
|
mount?.contentSnapshot !== attestation ||
|
|
3596
3658
|
!before.isFile() ||
|
|
3597
3659
|
Number(before.nlink) !== 0 ||
|
|
3598
|
-
(Number(before.mode) & 0o777) !==
|
|
3660
|
+
(Number(before.mode) & 0o777) !== snapshotSourceMode ||
|
|
3599
3661
|
String(before.dev) !== String(mount?.snapshotIdentity?.fileId?.dev) ||
|
|
3600
3662
|
String(before.ino) !== String(mount?.snapshotIdentity?.fileId?.ino) ||
|
|
3601
3663
|
Number(before.size) !== Number(attestation?.bytes) ||
|
|
@@ -3624,6 +3686,200 @@ function attestLinuxEntrySnapshot(runtime, mount, attestation, targetRuntime) {
|
|
|
3624
3686
|
);
|
|
3625
3687
|
}
|
|
3626
3688
|
|
|
3689
|
+
function linuxIdentityExpectedStat(identity) {
|
|
3690
|
+
return {
|
|
3691
|
+
dev: identity?.fileId?.dev,
|
|
3692
|
+
ino: identity?.fileId?.ino,
|
|
3693
|
+
size: identity?.bytes,
|
|
3694
|
+
mtimeMs: identity?.mtimeMs,
|
|
3695
|
+
};
|
|
3696
|
+
}
|
|
3697
|
+
|
|
3698
|
+
function applyLinuxMcpCapsuleCodeSnapshot(
|
|
3699
|
+
command,
|
|
3700
|
+
args,
|
|
3701
|
+
spawnOpts,
|
|
3702
|
+
sandboxOpts,
|
|
3703
|
+
runtime,
|
|
3704
|
+
base,
|
|
3705
|
+
) {
|
|
3706
|
+
const contract = sandboxOpts.executionContract;
|
|
3707
|
+
const validation = validateLinuxPluginContract(
|
|
3708
|
+
command,
|
|
3709
|
+
args,
|
|
3710
|
+
spawnOpts,
|
|
3711
|
+
contract,
|
|
3712
|
+
runtime,
|
|
3713
|
+
sandboxOpts.sync,
|
|
3714
|
+
);
|
|
3715
|
+
const unavailable = (reason, runtimeProbe = null) =>
|
|
3716
|
+
createSandboxPlan({
|
|
3717
|
+
...base,
|
|
3718
|
+
backend: null,
|
|
3719
|
+
candidateBackend: LINUX_MCP_CAPSULE_BACKEND,
|
|
3720
|
+
policyAttested: false,
|
|
3721
|
+
runtimeProbe: runtimeProbe
|
|
3722
|
+
? {
|
|
3723
|
+
kind: "linux-mcp-capsule-code-snapshot-v1",
|
|
3724
|
+
attempted: runtimeProbe.attempted !== false,
|
|
3725
|
+
probeRuntime: "node",
|
|
3726
|
+
targetRuntime: "node",
|
|
3727
|
+
...runtimeProbe,
|
|
3728
|
+
}
|
|
3729
|
+
: null,
|
|
3730
|
+
reason,
|
|
3731
|
+
guarantees: [],
|
|
3732
|
+
});
|
|
3733
|
+
if (
|
|
3734
|
+
contract?.kind !== MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND ||
|
|
3735
|
+
!validation.ok
|
|
3736
|
+
) {
|
|
3737
|
+
return unavailable("linux_mcp_capsule_execution_contract_invalid", {
|
|
3738
|
+
attempted: false,
|
|
3739
|
+
runnable: false,
|
|
3740
|
+
reason: validation.reason,
|
|
3741
|
+
contentSnapshot: false,
|
|
3742
|
+
handleAtomic: false,
|
|
3743
|
+
});
|
|
3744
|
+
}
|
|
3745
|
+
|
|
3746
|
+
const invocation = normalizeWrappedInvocation(
|
|
3747
|
+
command,
|
|
3748
|
+
args,
|
|
3749
|
+
spawnOpts,
|
|
3750
|
+
runtime.platform,
|
|
3751
|
+
);
|
|
3752
|
+
let runtimePin;
|
|
3753
|
+
let entryPin;
|
|
3754
|
+
let runtimeSnapshot;
|
|
3755
|
+
let entrySnapshot;
|
|
3756
|
+
try {
|
|
3757
|
+
runtimePin = pinLinuxRegularFile(
|
|
3758
|
+
runtime,
|
|
3759
|
+
contract.runtimeIdentity.realPath,
|
|
3760
|
+
contract.runtimeIdentity.realPath,
|
|
3761
|
+
linuxIdentityExpectedStat(contract.runtimeIdentity),
|
|
3762
|
+
{ requireSingleLink: true },
|
|
3763
|
+
);
|
|
3764
|
+
entryPin = pinLinuxRegularFile(
|
|
3765
|
+
runtime,
|
|
3766
|
+
contract.entryIdentity.realPath,
|
|
3767
|
+
contract.entryIdentity.realPath,
|
|
3768
|
+
linuxIdentityExpectedStat(contract.entryIdentity),
|
|
3769
|
+
{ requireSingleLink: true },
|
|
3770
|
+
);
|
|
3771
|
+
runtimeSnapshot = createLinuxRegularFileSnapshot(
|
|
3772
|
+
runtime,
|
|
3773
|
+
runtimePin,
|
|
3774
|
+
contract.runtimeIdentity,
|
|
3775
|
+
linuxMcpRuntimeSnapshotContract(),
|
|
3776
|
+
);
|
|
3777
|
+
entrySnapshot = createLinuxEntrySnapshot(
|
|
3778
|
+
runtime,
|
|
3779
|
+
entryPin,
|
|
3780
|
+
contract.entryIdentity,
|
|
3781
|
+
"node",
|
|
3782
|
+
);
|
|
3783
|
+
attestLinuxRegularFileSnapshot(
|
|
3784
|
+
runtime,
|
|
3785
|
+
runtimeSnapshot.finalMount,
|
|
3786
|
+
runtimeSnapshot.attestation,
|
|
3787
|
+
linuxMcpRuntimeSnapshotContract(),
|
|
3788
|
+
);
|
|
3789
|
+
attestLinuxEntrySnapshot(
|
|
3790
|
+
runtime,
|
|
3791
|
+
entrySnapshot.finalMount,
|
|
3792
|
+
entrySnapshot.attestation,
|
|
3793
|
+
"node",
|
|
3794
|
+
);
|
|
3795
|
+
} catch (error) {
|
|
3796
|
+
closeLinuxPinnedMounts(runtime, [
|
|
3797
|
+
runtimePin,
|
|
3798
|
+
entryPin,
|
|
3799
|
+
runtimeSnapshot?.probeMount,
|
|
3800
|
+
runtimeSnapshot?.finalMount,
|
|
3801
|
+
entrySnapshot?.probeMount,
|
|
3802
|
+
entrySnapshot?.finalMount,
|
|
3803
|
+
]);
|
|
3804
|
+
return unavailable("linux_mcp_capsule_code_snapshot_unavailable", {
|
|
3805
|
+
runnable: false,
|
|
3806
|
+
reason: error.message || "snapshot_unattested",
|
|
3807
|
+
contentSnapshot: false,
|
|
3808
|
+
handleAtomic: false,
|
|
3809
|
+
});
|
|
3810
|
+
}
|
|
3811
|
+
|
|
3812
|
+
closeLinuxPinnedMounts(runtime, [
|
|
3813
|
+
runtimePin,
|
|
3814
|
+
entryPin,
|
|
3815
|
+
runtimeSnapshot.probeMount,
|
|
3816
|
+
entrySnapshot.probeMount,
|
|
3817
|
+
]);
|
|
3818
|
+
const descriptors = [runtimeSnapshot.finalMount, entrySnapshot.finalMount];
|
|
3819
|
+
const runtimeFd = 3;
|
|
3820
|
+
const entryFd = 4;
|
|
3821
|
+
const snapshotIdentity = Object.freeze({
|
|
3822
|
+
runtimeSnapshotSha256: runtimeSnapshot.attestation.sha256,
|
|
3823
|
+
runtimeSnapshotBytes: runtimeSnapshot.attestation.bytes,
|
|
3824
|
+
entrySnapshotSha256: entrySnapshot.attestation.sha256,
|
|
3825
|
+
entrySnapshotBytes: entrySnapshot.attestation.bytes,
|
|
3826
|
+
});
|
|
3827
|
+
const policyDigest = sha256(
|
|
3828
|
+
JSON.stringify({
|
|
3829
|
+
version: 1,
|
|
3830
|
+
backend: LINUX_MCP_CAPSULE_BACKEND,
|
|
3831
|
+
contractKind: contract.kind,
|
|
3832
|
+
requiredBoundaries: [
|
|
3833
|
+
...new Set(sandboxOpts.requiredBoundaries || []),
|
|
3834
|
+
].sort(),
|
|
3835
|
+
identity: snapshotIdentity,
|
|
3836
|
+
cwd: invocation.options.cwd,
|
|
3837
|
+
passthroughArgsDigest: sha256(JSON.stringify(invocation.args.slice(1))),
|
|
3838
|
+
}),
|
|
3839
|
+
);
|
|
3840
|
+
let closed = false;
|
|
3841
|
+
const cleanup = () => {
|
|
3842
|
+
if (closed) return;
|
|
3843
|
+
closed = true;
|
|
3844
|
+
closeLinuxPinnedMounts(runtime, descriptors);
|
|
3845
|
+
};
|
|
3846
|
+
return createSandboxPlan({
|
|
3847
|
+
...base,
|
|
3848
|
+
applied: true,
|
|
3849
|
+
enforcement: LINUX_MCP_CAPSULE_BACKEND,
|
|
3850
|
+
backend: LINUX_MCP_CAPSULE_BACKEND,
|
|
3851
|
+
candidateBackend: null,
|
|
3852
|
+
policyAttested: true,
|
|
3853
|
+
policyDigest,
|
|
3854
|
+
runtimeProbe: {
|
|
3855
|
+
kind: "linux-mcp-capsule-code-snapshot-v1",
|
|
3856
|
+
attempted: true,
|
|
3857
|
+
runnable: true,
|
|
3858
|
+
reason: null,
|
|
3859
|
+
probeRuntime: "node",
|
|
3860
|
+
targetRuntime: "node",
|
|
3861
|
+
contentSnapshot: true,
|
|
3862
|
+
contentSnapshotScope: "mcp-capsule-entry-and-node-runtime",
|
|
3863
|
+
contentSnapshotMechanism: LINUX_MCP_CAPSULE_SNAPSHOT_MECHANISM,
|
|
3864
|
+
handleAtomic: true,
|
|
3865
|
+
sharedLibraryClosure: false,
|
|
3866
|
+
...snapshotIdentity,
|
|
3867
|
+
},
|
|
3868
|
+
reason: null,
|
|
3869
|
+
guarantees: [SANDBOX_BOUNDARIES.CODE_SNAPSHOT],
|
|
3870
|
+
command: `/proc/self/fd/${runtimeFd}`,
|
|
3871
|
+
args: [`/proc/self/fd/${entryFd}`, ...invocation.args.slice(1)],
|
|
3872
|
+
options: {
|
|
3873
|
+
...invocation.options,
|
|
3874
|
+
shell: false,
|
|
3875
|
+
stdio: Object.freeze(
|
|
3876
|
+
linuxStdioWithPinnedMounts(invocation.options.stdio, descriptors),
|
|
3877
|
+
),
|
|
3878
|
+
},
|
|
3879
|
+
cleanup,
|
|
3880
|
+
});
|
|
3881
|
+
}
|
|
3882
|
+
|
|
3627
3883
|
function buildLinuxNodePluginTreeSnapshotAttestation(mounts, entryDestination) {
|
|
3628
3884
|
const members = [];
|
|
3629
3885
|
const destinations = new Set();
|
|
@@ -5439,6 +5695,17 @@ export function applyLinuxSandbox(
|
|
|
5439
5695
|
boundary === SANDBOX_BOUNDARIES.PROCESS_TREE,
|
|
5440
5696
|
);
|
|
5441
5697
|
|
|
5698
|
+
if (requiredBoundaries.includes(SANDBOX_BOUNDARIES.CODE_SNAPSHOT)) {
|
|
5699
|
+
return applyLinuxMcpCapsuleCodeSnapshot(
|
|
5700
|
+
command,
|
|
5701
|
+
args,
|
|
5702
|
+
spawnOpts,
|
|
5703
|
+
sandboxOpts,
|
|
5704
|
+
runtime,
|
|
5705
|
+
base,
|
|
5706
|
+
);
|
|
5707
|
+
}
|
|
5708
|
+
|
|
5442
5709
|
if (requiresStrongLinuxBoundary) {
|
|
5443
5710
|
if (isLinuxGenericWorkspaceContract(sandboxOpts.executionContract)) {
|
|
5444
5711
|
return applyLinuxGenericWorkspaceSandbox(
|