chainlesschain 0.163.0 → 0.163.2

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.
Files changed (179) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/.build-hash +1 -1
  3. package/src/assets/web-panel/assets/{AIOps-CSy9BB6Z.js → AIOps-DnGsmsqJ.js} +1 -1
  4. package/src/assets/web-panel/assets/{ActionButton-CFyrEVfq.js → ActionButton-CrO6fcQ7.js} +1 -1
  5. package/src/assets/web-panel/assets/{Analytics-8419vb47.js → Analytics-DsBdOaP2.js} +3 -3
  6. package/src/assets/web-panel/assets/{AppLayout-CHu3Hkdx.js → AppLayout-DmQslKUB.js} +5 -5
  7. package/src/assets/web-panel/assets/{Artifacts-DJnt57Fs.js → Artifacts-BvyrT_QQ.js} +1 -1
  8. package/src/assets/web-panel/assets/{Audit-CHMq9ajE.js → Audit-prndoLiC.js} +1 -1
  9. package/src/assets/web-panel/assets/{BackgroundAgents-Cyfa4ub2.js → BackgroundAgents-DOTFyA55.js} +1 -1
  10. package/src/assets/web-panel/assets/{Backup-ACXUrUv7.js → Backup-9zOnPp_8.js} +1 -1
  11. package/src/assets/web-panel/assets/{BaseInput-DjC-3qRE.js → BaseInput-C4PC6sAG.js} +1 -1
  12. package/src/assets/web-panel/assets/{Chat-7_VDQ851.js → Chat-BBAF-W9v.js} +6 -6
  13. package/src/assets/web-panel/assets/{ChatBubbleRenderer-B4zct0dY.js → ChatBubbleRenderer-CWhvvloO.js} +1 -1
  14. package/src/assets/web-panel/assets/{Checkbox-DxbDl_rk.js → Checkbox-BI9iculd.js} +1 -1
  15. package/src/assets/web-panel/assets/{Codegen-BvZa5854.js → Codegen-3DP9BCKb.js} +1 -1
  16. package/src/assets/web-panel/assets/{Col-CX5Ow2Zl.js → Col-df-2TnJX.js} +1 -1
  17. package/src/assets/web-panel/assets/{Community-wFun-jSg.js → Community-CHs8gG_A.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compact-C6vJDuSn.js → Compact-CDfF6q7V.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compliance-Cm4sBytH.js → Compliance-CthrDnO7.js} +1 -1
  20. package/src/assets/web-panel/assets/{Cowork-DiEcMwE8.js → Cowork-HjIqsWJw.js} +2 -2
  21. package/src/assets/web-panel/assets/{Cron-RbeexsSQ.js → Cron-BKc196fb.js} +2 -2
  22. package/src/assets/web-panel/assets/{Crosschain-BBsyCKOp.js → Crosschain-CJnjdc8W.js} +1 -1
  23. package/src/assets/web-panel/assets/{DID-DE36g7Hz.js → DID-BHUy-8Q2.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dashboard-CdfLSTz1.js → Dashboard-QDB7sKeY.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dropdown-CyaT6SyW.js → Dropdown-DStcVK11.js} +1 -1
  26. package/src/assets/web-panel/assets/{EmailListRenderer-Nv_66bkM.js → EmailListRenderer-BwSUskMJ.js} +1 -1
  27. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Di-Sb-Ad.js → FamilyGuardDashboard-DgF_kurT.js} +1 -1
  28. package/src/assets/web-panel/assets/{Federation-B3mdht-U.js → Federation-k8wvv-wN.js} +1 -1
  29. package/src/assets/web-panel/assets/{FormItemContext-BeP93u4f.js → FormItemContext-C11qoq2r.js} +1 -1
  30. package/src/assets/web-panel/assets/{GenericCardRenderer-CETLayUr.js → GenericCardRenderer-BIIpr9kg.js} +1 -1
  31. package/src/assets/web-panel/assets/{Git-Bsat6hgI.js → Git-BlA1exTe.js} +2 -2
  32. package/src/assets/web-panel/assets/{Governance-YVmA7SwN.js → Governance-CYa1ZYM4.js} +1 -1
  33. package/src/assets/web-panel/assets/{Inference-DCa94nGl.js → Inference-6_kKVIt6.js} +1 -1
  34. package/src/assets/web-panel/assets/{KnowledgeGraph-CIKEU7T0.js → KnowledgeGraph-CB4AwxYy.js} +1 -1
  35. package/src/assets/web-panel/assets/{Logs-DUxP0MnS.js → Logs-xf7nHFAe.js} +2 -2
  36. package/src/assets/web-panel/assets/MarkdownRenderer-Bf3DEqP6.js +1 -0
  37. package/src/assets/web-panel/assets/{Marketplace-BU0X2lqu.js → Marketplace-aPg8e4Jt.js} +1 -1
  38. package/src/assets/web-panel/assets/{McpTools-BSsg58nZ.js → McpTools-C-TNlVUf.js} +5 -5
  39. package/src/assets/web-panel/assets/{Memory-CjqNIXlO.js → Memory-DMTPIpGa.js} +2 -2
  40. package/src/assets/web-panel/assets/{MobileBridge-DSsa4doG.js → MobileBridge-BxyvveRq.js} +1 -1
  41. package/src/assets/web-panel/assets/MobileProjects-DyPCrAyQ.js +1 -0
  42. package/src/assets/web-panel/assets/{Mtc-Du080G7t.js → Mtc-BdhqNXp6.js} +6 -6
  43. package/src/assets/web-panel/assets/{MtcAudit-JzQk-arw.js → MtcAudit-Cz-HFxzW.js} +5 -5
  44. package/src/assets/web-panel/assets/{Multisig-BMVT5Uln.js → Multisig-CIUaFNsx.js} +3 -3
  45. package/src/assets/web-panel/assets/{NLProgramming-D_38QYjs.js → NLProgramming-CWe6-J17.js} +1 -1
  46. package/src/assets/web-panel/assets/{Notes-DvbdjNm5.js → Notes-vYAKeviU.js} +3 -3
  47. package/src/assets/web-panel/assets/{NotificationSettings-DVHCW6ii.js → NotificationSettings-DQL9-2d7.js} +1 -1
  48. package/src/assets/web-panel/assets/{OrderTableRenderer-DmMBFD3g.js → OrderTableRenderer-DnXj1jBn.js} +1 -1
  49. package/src/assets/web-panel/assets/{Organization-DC-9pAmP.js → Organization-B3spU8AN.js} +2 -2
  50. package/src/assets/web-panel/assets/{Overflow-BRxWq0Qq.js → Overflow-DgEwo7vm.js} +1 -1
  51. package/src/assets/web-panel/assets/{P2P-CUdzhyLH.js → P2P-hujMRH8X.js} +2 -2
  52. package/src/assets/web-panel/assets/{PdhVaultBrowser-CwG21s9P.js → PdhVaultBrowser-C_qhdg9h.js} +3 -3
  53. package/src/assets/web-panel/assets/{Permissions-6bHd4zgK.js → Permissions-vp7LMcSf.js} +4 -4
  54. package/src/assets/web-panel/assets/{PersonalDataHub-BXgTDCba.js → PersonalDataHub-Dxr5Hgnq.js} +4 -4
  55. package/src/assets/web-panel/assets/{Pipeline-BFhKCBNj.js → Pipeline-DEPZqqH4.js} +1 -1
  56. package/src/assets/web-panel/assets/{Privacy-Byz9IqUF.js → Privacy-DTpDiKPe.js} +1 -1
  57. package/src/assets/web-panel/assets/{ProjectInit-B9LNoyoN.js → ProjectInit-jDJsRWmF.js} +2 -2
  58. package/src/assets/web-panel/assets/{ProjectSettings-DEj4eVdl.js → ProjectSettings-Dhor5RWH.js} +2 -2
  59. package/src/assets/web-panel/assets/{Projects-BAAvus06.js → Projects-08xUDZGt.js} +1 -1
  60. package/src/assets/web-panel/assets/Providers-BGs47s1a.js +1 -0
  61. package/src/assets/web-panel/assets/{QrScannerModal-CeDey0SJ.js → QrScannerModal-CjIw-wIb.js} +1 -1
  62. package/src/assets/web-panel/assets/{QuickAsk-exUvRIgX.js → QuickAsk-DX6jcqoi.js} +1 -1
  63. package/src/assets/web-panel/assets/{Recommend-4hJWmtSI.js → Recommend-DopXkhar.js} +1 -1
  64. package/src/assets/web-panel/assets/{RemoteSession-BmYUpl0m.js → RemoteSession-BLvqJE9c.js} +2 -2
  65. package/src/assets/web-panel/assets/{Reputation-B_txYAyY.js → Reputation-DhRj2Me7.js} +1 -1
  66. package/src/assets/web-panel/assets/{Row-BPtqOqGh.js → Row-DQ53vuPq.js} +1 -1
  67. package/src/assets/web-panel/assets/{RssFeed-CyWTxmq0.js → RssFeed-BslvwiBD.js} +3 -3
  68. package/src/assets/web-panel/assets/{Search-cItU1tmC.js → Search-DJKBDNKZ.js} +1 -1
  69. package/src/assets/web-panel/assets/{Security-B0Z9_BUt.js → Security-COhpxHER.js} +4 -4
  70. package/src/assets/web-panel/assets/{Services-Dzpz2uFp.js → Services-dbulD6cI.js} +2 -2
  71. package/src/assets/web-panel/assets/{Skeleton-CBtoylP8.js → Skeleton-ciIVNfhC.js} +1 -1
  72. package/src/assets/web-panel/assets/{Skills-Cw9RJiVn.js → Skills-AiRTkTCk.js} +1 -1
  73. package/src/assets/web-panel/assets/{Sla-D2vLfvgl.js → Sla-DDMcWYBc.js} +1 -1
  74. package/src/assets/web-panel/assets/{SpeechSettings-I9dKbcOU.js → SpeechSettings-BPxWbpXO.js} +1 -1
  75. package/src/assets/web-panel/assets/{SyncSettings-BOju53RT.js → SyncSettings-BoEOXCyg.js} +2 -2
  76. package/src/assets/web-panel/assets/Tasks-CEYFJwmr.js +1 -0
  77. package/src/assets/web-panel/assets/{Templates-C2ttpPql.js → Templates-UowY8Ixe.js} +1 -1
  78. package/src/assets/web-panel/assets/{Tenant-XQ6Qg8-Q.js → Tenant-DauSLQXN.js} +1 -1
  79. package/src/assets/web-panel/assets/{Terminal-DYB9dUnS.js → Terminal-DBj7Jneq.js} +2 -2
  80. package/src/assets/web-panel/assets/{TimelineRenderer-gShtO4I8.js → TimelineRenderer-UMrPwoZC.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tokens-BvoJTCJg.js → Tokens-4ea96-bn.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trigger-BwYRTMY_.js → Trigger--ISCqt4b.js} +1 -1
  83. package/src/assets/web-panel/assets/{Trust-C5rt6fCF.js → Trust-D4GVimRJ.js} +1 -1
  84. package/src/assets/web-panel/assets/{UkeySign-DPBrHUgL.js → UkeySign-Ci-nXRQc.js} +1 -1
  85. package/src/assets/web-panel/assets/{VideoEditing-BcxywO_K.js → VideoEditing-Cjk7mKPw.js} +1 -1
  86. package/src/assets/web-panel/assets/{Wallet-CZvTpsPz.js → Wallet-BgOLOO3Z.js} +4 -4
  87. package/src/assets/web-panel/assets/{WebAuthn-LI_jAuOx.js → WebAuthn-CCX0K29i.js} +4 -4
  88. package/src/assets/web-panel/assets/{WorkflowEditor-B2a6bANB.js → WorkflowEditor-Ch3zgIsE.js} +1 -1
  89. package/src/assets/web-panel/assets/{chat-B6DPMfRB.js → chat-DKOU_2Vb.js} +1 -1
  90. package/src/assets/web-panel/assets/{colors-IpLhw9T8.js → colors-6OVo4u3C.js} +1 -1
  91. package/src/assets/web-panel/assets/{compact-item-BzodimsI.js → compact-item-BH78Hlsq.js} +1 -1
  92. package/src/assets/web-panel/assets/{createContext-DL2jaWH5.js → createContext-CFRpSbbC.js} +1 -1
  93. package/src/assets/web-panel/assets/devWarning-DEMblAIm.js +1 -0
  94. package/src/assets/web-panel/assets/{hasIn-C4Geudre.js → hasIn-DNQhgcVi.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-CVFXYmUe.js → index--rq90rL9.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-CaKKxqCI.js → index-7TC3S8SN.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BaTvPxY0.js → index-AuBhLqOm.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CcgoKNXN.js → index-BDSR7ecX.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-C3LzRvkw.js → index-BHa4WyTZ.js} +1 -1
  100. package/src/assets/web-panel/assets/index-BTvq-36D.js +1 -0
  101. package/src/assets/web-panel/assets/{index-DvEnrn8M.js → index-BYrnm5Ob.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-F-SCUTee.js → index-B_Z-YoxX.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CAjyUjZl.js → index-BaVE6E8y.js} +25 -25
  104. package/src/assets/web-panel/assets/{index-CQPOCB4h.js → index-Bb6kDrUx.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DZtKnnTW.js → index-BepBTpa8.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-BX4pKudW.js → index-BkN3iTTp.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-COxGCo8v.js → index-BnnXQot_.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CeUnSSEP.js → index-BujsOZfc.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DlABpgCv.js → index-BxRy5LPR.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-CQBPhJlk.js → index-CFPJ8yzF.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Dl_QAtzq.js → index-CNuCHHQT.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BbWRxWM2.js → index-CaYqY35Z.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DGBRBg3D.js → index-CkNEMANR.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DvOzjf2F.js → index-CkqHgG-b.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DHdD0Y7h.js → index-CrcLHN2F.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B5Sn7CtW.js → index-Cu3L4r5l.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DnBybYhx.js → index-D3RtTT4K.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CnwHp5Oi.js → index-D84id2Y4.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-EjW1R_a7.js → index-DKN2noIF.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-C_SxaIPI.js → index-DaDgdJYj.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Bi6Zkv5M.js → index-Du0rnksC.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-CczBR6Du.js → index-DvHGtNnF.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-CTlmw_cr.js → index-Eag8e_mA.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DREx4gaS.js → index-HNGGVF6o.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BRj6YKuI.js → index-Y9MJv28e.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-DZU7Y67X.js → index-bKm3TUDp.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-BvKoSvko.js → index-caye7AOE.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DXQ2OtXt.js → index-cdf7fd7d.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DMY1waPC.js → index-dDkoL4Pe.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BeZhISVl.js → index-hPY0fFrd.js} +1 -1
  131. package/src/assets/web-panel/assets/index-hUpvk6Jl.js +1 -0
  132. package/src/assets/web-panel/assets/{index-DoyIjk6r.js → index-nbfHl1oV.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-B6w4fpSI.js → index-sm7W8AXy.js} +1 -1
  134. package/src/assets/web-panel/assets/{initDefaultProps-CW5mTl3w.js → initDefaultProps-BZ9w6jPL.js} +1 -1
  135. package/src/assets/web-panel/assets/{motion-BtjIT9np.js → motion-BnwUiOho.js} +1 -1
  136. package/src/assets/web-panel/assets/{move-DZv4fZAV.js → move-ByUKJnNm.js} +1 -1
  137. package/src/assets/web-panel/assets/{mtc-parser-BwCix1O-.js → mtc-parser-V7yK1KEl.js} +1 -1
  138. package/src/assets/web-panel/assets/{omit-BW72HDUD.js → omit-BEXBBt4j.js} +1 -1
  139. package/src/assets/web-panel/assets/{pickAttrs-DBW2jcMc.js → pickAttrs-qDm_46Gi.js} +1 -1
  140. package/src/assets/web-panel/assets/{placementArrow-D3YmWlIS.js → placementArrow-BIbhEo_0.js} +1 -1
  141. package/src/assets/web-panel/assets/{responsiveObserve-CL4-a-9Q.js → responsiveObserve-NbPbDgA_.js} +1 -1
  142. package/src/assets/web-panel/assets/{slide-Cw9zIbXQ.js → slide-BnUWglZ0.js} +1 -1
  143. package/src/assets/web-panel/assets/{statusUtils-mMLVioo-.js → statusUtils-BX8_wZI5.js} +1 -1
  144. package/src/assets/web-panel/assets/{styleChecker-BK8857AH.js → styleChecker-BV4OycQX.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFlexGapSupport-C1iSaJij.js → useFlexGapSupport-Od_H5llY.js} +1 -1
  146. package/src/assets/web-panel/assets/{useFs-D3riGOaP.js → useFs-BWI-PyiX.js} +1 -1
  147. package/src/assets/web-panel/assets/{usePersonalDataHub-Bwqvmz4X.js → usePersonalDataHub-BqMuhG3g.js} +1 -1
  148. package/src/assets/web-panel/assets/{vnode-Byk4zzkf.js → vnode-DNd23z6f.js} +1 -1
  149. package/src/assets/web-panel/assets/{zoom-D7INFTp2.js → zoom-Cjaxnm7l.js} +1 -1
  150. package/src/assets/web-panel/index.html +1 -1
  151. package/src/commands/mcp.js +29 -1
  152. package/src/commands/pack.js +4 -4
  153. package/src/data/changelog.json +27 -1
  154. package/src/harness/mcp-client.js +15 -2
  155. package/src/harness/prompt-compressor.js +22 -4
  156. package/src/lib/cowork-mcp-tools.js +1 -0
  157. package/src/lib/cowork-task-templates.js +1 -0
  158. package/src/lib/mcp-stdio-executable-identity.js +75 -11
  159. package/src/lib/mcp-stdio-execution-authority.js +5 -0
  160. package/src/lib/packer/index.js +1 -1
  161. package/src/lib/packer/native-prebuild-collector.js +3 -3
  162. package/src/lib/packer/pack-update-checker.js +2 -2
  163. package/src/lib/packer/pkg-config-generator.js +12 -11
  164. package/src/lib/packer/web-panel-builder.js +6 -3
  165. package/src/lib/process-execution-broker/index.js +321 -23
  166. package/src/lib/process-execution-broker/platform-sandbox.js +494 -21
  167. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  168. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  169. package/src/lib/process-execution-broker/windows-sandbox.cs +5 -4
  170. package/src/lib/session-tail.js +56 -24
  171. package/src/lib/skill-mcp.js +10 -0
  172. package/src/runtime/mcp-config.js +3 -0
  173. package/src/assets/web-panel/assets/MarkdownRenderer-Mw5o3e7M.js +0 -1
  174. package/src/assets/web-panel/assets/MobileProjects-DLl1qzid.js +0 -1
  175. package/src/assets/web-panel/assets/Providers-Bu_pQsk6.js +0 -1
  176. package/src/assets/web-panel/assets/Tasks-C3LBy_7x.js +0 -1
  177. package/src/assets/web-panel/assets/devWarning-CZB0EDsa.js +0 -1
  178. package/src/assets/web-panel/assets/index-CI7k8Sk9.js +0 -1
  179. package/src/assets/web-panel/assets/index-DPTHBSR8.js +0 -1
@@ -36,7 +36,9 @@ const require = createRequire(import.meta.url);
36
36
  // platform-sandbox.js exports: applySandbox, postSpawnSandbox
37
37
  import {
38
38
  applySandbox as _applySandbox,
39
+ consumeWindowsMcpCodeSnapshotPlanBinding,
39
40
  postSpawnSandbox as _postSpawnSandbox,
41
+ MCP_STDIO_FD_ENTRY_BOOTSTRAP_SHA256,
40
42
  SANDBOX_BOUNDARIES,
41
43
  } from "./platform-sandbox.js";
42
44
  import {
@@ -60,6 +62,9 @@ const SUPPORTED_SANDBOX_PROFILES = new Set([
60
62
  "strict",
61
63
  "network-only",
62
64
  ]);
65
+ // Broker-private admission state. Public runtime-probe fields are audit
66
+ // evidence, not authority to invoke a privileged post-spawn closure.
67
+ const admittedWindowsMcpCodeSnapshotPlans = new WeakSet();
63
68
 
64
69
  // 延迟导入避免循环依赖
65
70
  let _traceCtx = null;
@@ -1065,7 +1070,7 @@ class ProcessExecutionBroker extends EventEmitter {
1065
1070
  return error;
1066
1071
  }
1067
1072
 
1068
- _validateSandboxPlan(plan) {
1073
+ _validateSandboxPlan(plan, launchContext = {}) {
1069
1074
  if (!plan || typeof plan !== "object") {
1070
1075
  throw this._sandboxError(
1071
1076
  "invalid_sandbox_plan",
@@ -1159,6 +1164,7 @@ class ProcessExecutionBroker extends EventEmitter {
1159
1164
  let sanitizedNetworkPolicy = null;
1160
1165
  let sanitizedProcessTreePolicy = null;
1161
1166
  let sanitizedPtyPolicy = null;
1167
+ let windowsPlanBindingConsumed = false;
1162
1168
  if (plan.runtimeProbe !== null && plan.runtimeProbe !== undefined) {
1163
1169
  if (
1164
1170
  typeof plan.runtimeProbe !== "object" ||
@@ -1179,6 +1185,10 @@ class ProcessExecutionBroker extends EventEmitter {
1179
1185
  "targetRuntime",
1180
1186
  "contentSnapshotScope",
1181
1187
  "contentSnapshotMechanism",
1188
+ "runtimeLaunchMechanism",
1189
+ "planBindingMechanism",
1190
+ "runtimeLaunchPath",
1191
+ "entrySnapshotPath",
1182
1192
  "pluginTreeContentSnapshotScope",
1183
1193
  "pluginTreeContentSnapshotMechanism",
1184
1194
  "pluginTreeSnapshotConsistency",
@@ -1207,6 +1217,7 @@ class ProcessExecutionBroker extends EventEmitter {
1207
1217
  "sharedLibraryClosure",
1208
1218
  "entrySnapshotAtomic",
1209
1219
  "runtimeLaunchAtomic",
1220
+ "mcpCapsuleCodeSnapshot",
1210
1221
  ]) {
1211
1222
  if (
1212
1223
  plan.runtimeProbe[field] !== undefined &&
@@ -1242,6 +1253,7 @@ class ProcessExecutionBroker extends EventEmitter {
1242
1253
  "runtimeSnapshotSha256",
1243
1254
  "runtimeAttestedSha256",
1244
1255
  "entrySnapshotSha256",
1256
+ "planBindingDigest",
1245
1257
  ]) {
1246
1258
  if (
1247
1259
  plan.runtimeProbe[field] !== undefined &&
@@ -1254,6 +1266,22 @@ class ProcessExecutionBroker extends EventEmitter {
1254
1266
  );
1255
1267
  }
1256
1268
  }
1269
+ const planBindingDeclared =
1270
+ plan.runtimeProbe.planBindingMechanism !== undefined ||
1271
+ plan.runtimeProbe.planBindingDigest !== undefined;
1272
+ if (
1273
+ planBindingDeclared &&
1274
+ (plan.platform !== "win32" ||
1275
+ !guarantees.includes(SANDBOX_BOUNDARIES.CODE_SNAPSHOT) ||
1276
+ plan.runtimeProbe.planBindingMechanism !==
1277
+ "windows-mcp-code-snapshot-plan-binding-v1" ||
1278
+ !/^[a-f0-9]{64}$/.test(plan.runtimeProbe.planBindingDigest || ""))
1279
+ ) {
1280
+ throw this._sandboxError(
1281
+ "invalid_sandbox_plan",
1282
+ "Sandbox runtime probe plan binding must use the typed Windows MCP code-snapshot contract",
1283
+ );
1284
+ }
1257
1285
  if (
1258
1286
  plan.runtimeProbe.pluginTreeContentSnapshotDigest !== undefined &&
1259
1287
  (typeof plan.runtimeProbe.pluginTreeContentSnapshotDigest !==
@@ -1559,15 +1587,97 @@ class ProcessExecutionBroker extends EventEmitter {
1559
1587
  SANDBOX_BOUNDARIES.CODE_SNAPSHOT,
1560
1588
  );
1561
1589
  if (codeSnapshotGuaranteed) {
1590
+ const executionContract = launchContext.executionContract;
1591
+ const launchArgs = Array.isArray(launchContext.args)
1592
+ ? launchContext.args
1593
+ : [];
1594
+ const windowsPlanBindingDeclared =
1595
+ plan.platform === "win32" &&
1596
+ (plan.runtimeProbe.planBindingMechanism !== undefined ||
1597
+ plan.runtimeProbe.planBindingDigest !== undefined);
1598
+ // Consume before evaluating any other Windows evidence. A genuine
1599
+ // one-launch plan is therefore burned by its first admission attempt,
1600
+ // including an attempt with a mismatched command or contract.
1601
+ windowsPlanBindingConsumed = windowsPlanBindingDeclared
1602
+ ? consumeWindowsMcpCodeSnapshotPlanBinding(plan, {
1603
+ command: launchContext.command,
1604
+ args: launchArgs,
1605
+ cwd: launchContext.cwd,
1606
+ shell: launchContext.shell,
1607
+ detached: launchContext.detached,
1608
+ executionContract,
1609
+ profile: launchContext.profile,
1610
+ requiredBoundaries: launchContext.requiredBoundaries,
1611
+ sync: launchContext.sync,
1612
+ })
1613
+ : false;
1614
+ const passthroughArgsMatch = (candidateArgs) =>
1615
+ candidateArgs.length === Math.max(0, launchArgs.length - 1) &&
1616
+ candidateArgs.every(
1617
+ (candidateArg, index) => candidateArg === launchArgs[index + 1],
1618
+ );
1619
+ const contractBoundSnapshotEvidence =
1620
+ executionContract?.contractVersion === 1 &&
1621
+ executionContract.kind === MCP_STDIO_CAPSULE_SANDBOX_CONTRACT_KIND &&
1622
+ typeof launchContext.command === "string" &&
1623
+ launchContext.command === executionContract.runtimePath &&
1624
+ launchContext.command ===
1625
+ executionContract.runtimeIdentity?.realPath &&
1626
+ launchArgs.length >= 1 &&
1627
+ launchArgs[0] === executionContract.entryIdentity?.realPath &&
1628
+ /^[a-f0-9]{64}$/.test(
1629
+ executionContract.runtimeIdentity?.sha256 || "",
1630
+ ) &&
1631
+ Number.isSafeInteger(executionContract.runtimeIdentity?.bytes) &&
1632
+ executionContract.runtimeIdentity.bytes > 0 &&
1633
+ /^[a-f0-9]{64}$/.test(
1634
+ executionContract.entryIdentity?.sha256 || "",
1635
+ ) &&
1636
+ Number.isSafeInteger(executionContract.entryIdentity?.bytes) &&
1637
+ executionContract.entryIdentity.bytes >= 0 &&
1638
+ plan.runtimeProbe.entrySnapshotSha256 ===
1639
+ executionContract.entryIdentity.sha256 &&
1640
+ plan.runtimeProbe.entrySnapshotBytes ===
1641
+ executionContract.entryIdentity.bytes;
1642
+ const linuxRuntimeSnapshotContractBound =
1643
+ plan.runtimeProbe.runtimeSnapshotSha256 ===
1644
+ executionContract?.runtimeIdentity?.sha256 &&
1645
+ plan.runtimeProbe.runtimeSnapshotBytes ===
1646
+ executionContract?.runtimeIdentity?.bytes &&
1647
+ plan.runtimeProbe.runtimeAttestedSha256 === undefined &&
1648
+ plan.runtimeProbe.runtimeAttestedBytes === undefined;
1649
+ const windowsRuntimeAttestationContractBound =
1650
+ plan.runtimeProbe.runtimeAttestedSha256 ===
1651
+ executionContract?.runtimeIdentity?.sha256 &&
1652
+ plan.runtimeProbe.runtimeAttestedBytes ===
1653
+ executionContract?.runtimeIdentity?.bytes &&
1654
+ plan.runtimeProbe.runtimeSnapshotSha256 === undefined &&
1655
+ plan.runtimeProbe.runtimeSnapshotBytes === undefined;
1656
+ const contractEntryRelative = executionContract
1657
+ ? path.posix.relative(
1658
+ executionContract.pluginRoot,
1659
+ executionContract.entryIdentity.realPath,
1660
+ )
1661
+ : null;
1662
+ const expectedLinuxBubblewrapEntry =
1663
+ contractEntryRelative &&
1664
+ contractEntryRelative !== ".." &&
1665
+ !contractEntryRelative.startsWith("../") &&
1666
+ !path.posix.isAbsolute(contractEntryRelative)
1667
+ ? path.posix.join("/opt/chainless/plugin", contractEntryRelative)
1668
+ : null;
1562
1669
  const exactSnapshotEvidence =
1563
1670
  plan.applied === true &&
1564
1671
  candidateBackend === null &&
1672
+ contractBoundSnapshotEvidence &&
1565
1673
  plan.runtimeProbe.attempted === true &&
1566
1674
  plan.runtimeProbe.runnable === true &&
1567
1675
  plan.runtimeProbe.reason === null &&
1568
1676
  plan.runtimeProbe.probeRuntime === "node" &&
1569
1677
  plan.runtimeProbe.targetRuntime === "node" &&
1570
1678
  plan.runtimeProbe.contentSnapshot === true &&
1679
+ plan.runtimeProbe.entrySnapshotAtomic === true &&
1680
+ plan.runtimeProbe.runtimeLaunchAtomic === true &&
1571
1681
  plan.runtimeProbe.sharedLibraryClosure === false &&
1572
1682
  /^[a-f0-9]{64}$/.test(plan.runtimeProbe.entrySnapshotSha256 || "") &&
1573
1683
  Number.isSafeInteger(plan.runtimeProbe.entrySnapshotBytes) &&
@@ -1583,8 +1693,15 @@ class ProcessExecutionBroker extends EventEmitter {
1583
1693
  plan.runtimeProbe.contentSnapshotScope ===
1584
1694
  "mcp-capsule-entry-and-node-runtime" &&
1585
1695
  plan.runtimeProbe.contentSnapshotMechanism ===
1586
- "verified-o_tmpfile-copy-inherited-fd-exec-v1" &&
1696
+ "verified-o_tmpfile-copy-inherited-fd-module-compile-v1" &&
1587
1697
  plan.runtimeProbe.handleAtomic === true &&
1698
+ plan.runtimeProbe.entrySnapshotAtomic === true &&
1699
+ plan.runtimeProbe.runtimeLaunchAtomic === true &&
1700
+ plan.runtimeProbe.runtimeLaunchMechanism ===
1701
+ "inherited-executable-fd-v1" &&
1702
+ plan.runtimeProbe.entrySnapshotBootstrapSha256 ===
1703
+ MCP_STDIO_FD_ENTRY_BOOTSTRAP_SHA256 &&
1704
+ linuxRuntimeSnapshotContractBound &&
1588
1705
  /^[a-f0-9]{64}$/.test(
1589
1706
  plan.runtimeProbe.runtimeSnapshotSha256 || "",
1590
1707
  ) &&
@@ -1592,7 +1709,53 @@ class ProcessExecutionBroker extends EventEmitter {
1592
1709
  plan.runtimeProbe.runtimeSnapshotBytes > 0 &&
1593
1710
  plan.runtimeProbe.runtimeSnapshotBytes <= 256 * 1024 * 1024 &&
1594
1711
  /^\/proc\/self\/fd\/\d+$/.test(plan.command) &&
1595
- /^\/proc\/self\/fd\/\d+$/.test(plan.args[0] || "");
1712
+ plan.args[0] === "-e" &&
1713
+ crypto
1714
+ .createHash("sha256")
1715
+ .update(plan.args[1] || "")
1716
+ .digest("hex") === MCP_STDIO_FD_ENTRY_BOOTSTRAP_SHA256 &&
1717
+ plan.args[2] === "--" &&
1718
+ passthroughArgsMatch(plan.args.slice(3));
1719
+ const linuxBubblewrapTargetSeparator = plan.args.indexOf("--");
1720
+ const linuxBubblewrapSnapshotEvidence =
1721
+ plan.platform === "linux" &&
1722
+ backend === "linux-bwrap" &&
1723
+ plan.enforcement === "linux-bwrap" &&
1724
+ policyAttested === true &&
1725
+ policyDigest !== null &&
1726
+ plan.runtimeProbe.kind === "linux-bwrap-plugin-node-policy-v1" &&
1727
+ plan.runtimeProbe.mcpCapsuleCodeSnapshot === true &&
1728
+ plan.runtimeProbe.contentSnapshotScope === "plugin-entry-source" &&
1729
+ plan.runtimeProbe.contentSnapshotMechanism ===
1730
+ "verified-o_tmpfile-copy-bwrap-ro-bind-data-v1" &&
1731
+ plan.runtimeProbe.handleAtomic === false &&
1732
+ plan.runtimeProbe.entrySnapshotAtomic === true &&
1733
+ plan.runtimeProbe.runtimeLaunchAtomic === true &&
1734
+ plan.runtimeProbe.runtimeLaunchMechanism ===
1735
+ "bwrap-descriptor-mount-node-runtime-exec-v1" &&
1736
+ plan.runtimeProbe.supervisorDescriptorBound === true &&
1737
+ plan.runtimeProbe.pluginTreeContentSnapshot === true &&
1738
+ plan.runtimeProbe.runtimeLaunchPath ===
1739
+ "/opt/chainless/runtime/node" &&
1740
+ expectedLinuxBubblewrapEntry !== null &&
1741
+ plan.runtimeProbe.entrySnapshotPath ===
1742
+ expectedLinuxBubblewrapEntry &&
1743
+ linuxRuntimeSnapshotContractBound &&
1744
+ /^[a-f0-9]{64}$/.test(
1745
+ plan.runtimeProbe.runtimeSnapshotSha256 || "",
1746
+ ) &&
1747
+ Number.isSafeInteger(plan.runtimeProbe.runtimeSnapshotBytes) &&
1748
+ plan.runtimeProbe.runtimeSnapshotBytes > 0 &&
1749
+ plan.runtimeProbe.runtimeSnapshotBytes <= 256 * 1024 * 1024 &&
1750
+ /^\/proc\/self\/fd\/\d+$/.test(plan.command) &&
1751
+ linuxBubblewrapTargetSeparator >= 0 &&
1752
+ plan.args[linuxBubblewrapTargetSeparator + 1] ===
1753
+ plan.runtimeProbe.runtimeLaunchPath &&
1754
+ plan.args[linuxBubblewrapTargetSeparator + 2] ===
1755
+ plan.runtimeProbe.entrySnapshotPath &&
1756
+ passthroughArgsMatch(
1757
+ plan.args.slice(linuxBubblewrapTargetSeparator + 3),
1758
+ );
1596
1759
  const windowsSnapshotEvidence =
1597
1760
  plan.platform === "win32" &&
1598
1761
  [
@@ -1600,26 +1763,40 @@ class ProcessExecutionBroker extends EventEmitter {
1600
1763
  "windows-appcontainer-job-restricted-token",
1601
1764
  ].includes(backend) &&
1602
1765
  plan.enforcement === backend &&
1603
- [
1604
- "windows-plugin-node-entry-snapshot-v1",
1605
- "windows-appcontainer-launch-attestation-v1",
1606
- ].includes(plan.runtimeProbe.kind) &&
1766
+ ((backend === "windows-job-restricted-token" &&
1767
+ plan.runtimeProbe.kind ===
1768
+ "windows-plugin-node-entry-snapshot-v1") ||
1769
+ (backend === "windows-appcontainer-job-restricted-token" &&
1770
+ plan.runtimeProbe.kind ===
1771
+ "windows-appcontainer-launch-attestation-v1" &&
1772
+ policyAttested === true &&
1773
+ policyDigest !== null)) &&
1607
1774
  plan.runtimeProbe.contentSnapshotScope ===
1608
1775
  "mcp-capsule-entry-source" &&
1609
1776
  plan.runtimeProbe.contentSnapshotMechanism ===
1610
1777
  "verified-handle-inherited-pipe-module-compile-v1" &&
1611
1778
  plan.runtimeProbe.handleAtomic === false &&
1612
1779
  plan.runtimeProbe.entrySnapshotAtomic === true &&
1613
- plan.runtimeProbe.runtimeLaunchAtomic === false &&
1780
+ plan.runtimeProbe.runtimeLaunchAtomic === true &&
1781
+ plan.runtimeProbe.runtimeLaunchMechanism ===
1782
+ "filter-oplock-locked-createprocess-suspended-image-v1" &&
1783
+ plan.runtimeProbe.planBindingMechanism ===
1784
+ "windows-mcp-code-snapshot-plan-binding-v1" &&
1785
+ /^[a-f0-9]{64}$/.test(plan.runtimeProbe.planBindingDigest || "") &&
1786
+ windowsRuntimeAttestationContractBound &&
1614
1787
  /^[a-f0-9]{64}$/.test(
1615
1788
  plan.runtimeProbe.runtimeAttestedSha256 || "",
1616
1789
  ) &&
1617
1790
  Number.isSafeInteger(plan.runtimeProbe.runtimeAttestedBytes) &&
1618
1791
  plan.runtimeProbe.runtimeAttestedBytes > 0 &&
1619
- plan.runtimeProbe.runtimeAttestedBytes <= 256 * 1024 * 1024;
1792
+ plan.runtimeProbe.runtimeAttestedBytes <= 256 * 1024 * 1024 &&
1793
+ launchContext.builtInSandboxAdapter === true &&
1794
+ windowsPlanBindingConsumed;
1620
1795
  if (
1621
1796
  !exactSnapshotEvidence ||
1622
- (!linuxSnapshotEvidence && !windowsSnapshotEvidence)
1797
+ (!linuxSnapshotEvidence &&
1798
+ !linuxBubblewrapSnapshotEvidence &&
1799
+ !windowsSnapshotEvidence)
1623
1800
  ) {
1624
1801
  throw this._sandboxError(
1625
1802
  "invalid_sandbox_plan",
@@ -1907,6 +2084,22 @@ class ProcessExecutionBroker extends EventEmitter {
1907
2084
  ...(plan.runtimeProbe.handleAtomic !== undefined
1908
2085
  ? { handleAtomic: plan.runtimeProbe.handleAtomic }
1909
2086
  : {}),
2087
+ ...(plan.runtimeProbe.entrySnapshotAtomic !== undefined
2088
+ ? { entrySnapshotAtomic: plan.runtimeProbe.entrySnapshotAtomic }
2089
+ : {}),
2090
+ ...(plan.runtimeProbe.runtimeLaunchAtomic !== undefined
2091
+ ? { runtimeLaunchAtomic: plan.runtimeProbe.runtimeLaunchAtomic }
2092
+ : {}),
2093
+ ...(plan.runtimeProbe.runtimeLaunchMechanism !== undefined
2094
+ ? {
2095
+ runtimeLaunchMechanism: plan.runtimeProbe.runtimeLaunchMechanism,
2096
+ }
2097
+ : {}),
2098
+ ...(plan.runtimeProbe.sharedLibraryClosure !== undefined
2099
+ ? {
2100
+ sharedLibraryClosure: plan.runtimeProbe.sharedLibraryClosure,
2101
+ }
2102
+ : {}),
1910
2103
  ...(plan.runtimeProbe.contentSnapshotScope !== undefined
1911
2104
  ? {
1912
2105
  contentSnapshotScope: plan.runtimeProbe.contentSnapshotScope,
@@ -1918,12 +2111,35 @@ class ProcessExecutionBroker extends EventEmitter {
1918
2111
  plan.runtimeProbe.contentSnapshotMechanism,
1919
2112
  }
1920
2113
  : {}),
2114
+ ...(plan.runtimeProbe.planBindingMechanism !== undefined
2115
+ ? {
2116
+ planBindingMechanism: plan.runtimeProbe.planBindingMechanism,
2117
+ planBindingDigest: plan.runtimeProbe.planBindingDigest,
2118
+ }
2119
+ : {}),
1921
2120
  ...(plan.runtimeProbe.runtimeSnapshotSha256 !== undefined
1922
2121
  ? {
1923
2122
  runtimeSnapshotSha256: plan.runtimeProbe.runtimeSnapshotSha256,
1924
2123
  runtimeSnapshotBytes: plan.runtimeProbe.runtimeSnapshotBytes,
1925
2124
  entrySnapshotSha256: plan.runtimeProbe.entrySnapshotSha256,
1926
2125
  entrySnapshotBytes: plan.runtimeProbe.entrySnapshotBytes,
2126
+ entrySnapshotAtomic: plan.runtimeProbe.entrySnapshotAtomic,
2127
+ runtimeLaunchAtomic: plan.runtimeProbe.runtimeLaunchAtomic,
2128
+ runtimeLaunchMechanism: plan.runtimeProbe.runtimeLaunchMechanism,
2129
+ ...(plan.runtimeProbe.runtimeLaunchPath !== undefined
2130
+ ? { runtimeLaunchPath: plan.runtimeProbe.runtimeLaunchPath }
2131
+ : {}),
2132
+ ...(plan.runtimeProbe.entrySnapshotPath !== undefined
2133
+ ? { entrySnapshotPath: plan.runtimeProbe.entrySnapshotPath }
2134
+ : {}),
2135
+ ...(plan.runtimeProbe.mcpCapsuleCodeSnapshot !== undefined
2136
+ ? {
2137
+ mcpCapsuleCodeSnapshot:
2138
+ plan.runtimeProbe.mcpCapsuleCodeSnapshot,
2139
+ }
2140
+ : {}),
2141
+ entrySnapshotBootstrapSha256:
2142
+ plan.runtimeProbe.entrySnapshotBootstrapSha256,
1927
2143
  sharedLibraryClosure: plan.runtimeProbe.sharedLibraryClosure,
1928
2144
  }
1929
2145
  : {}),
@@ -1935,6 +2151,7 @@ class ProcessExecutionBroker extends EventEmitter {
1935
2151
  entrySnapshotBytes: plan.runtimeProbe.entrySnapshotBytes,
1936
2152
  entrySnapshotAtomic: plan.runtimeProbe.entrySnapshotAtomic,
1937
2153
  runtimeLaunchAtomic: plan.runtimeProbe.runtimeLaunchAtomic,
2154
+ runtimeLaunchMechanism: plan.runtimeProbe.runtimeLaunchMechanism,
1938
2155
  sharedLibraryClosure: plan.runtimeProbe.sharedLibraryClosure,
1939
2156
  }
1940
2157
  : {}),
@@ -1984,6 +2201,15 @@ class ProcessExecutionBroker extends EventEmitter {
1984
2201
  };
1985
2202
  }
1986
2203
  }
2204
+ if (
2205
+ guarantees.includes(SANDBOX_BOUNDARIES.CODE_SNAPSHOT) &&
2206
+ runtimeProbe === null
2207
+ ) {
2208
+ throw this._sandboxError(
2209
+ "invalid_sandbox_plan",
2210
+ "Code snapshot guarantee requires typed atomic MCP capsule evidence",
2211
+ );
2212
+ }
1987
2213
  if (backend === "linux-bwrap-workspace" && !genericWorkspaceProbe) {
1988
2214
  throw this._sandboxError(
1989
2215
  "invalid_sandbox_plan",
@@ -2001,7 +2227,7 @@ class ProcessExecutionBroker extends EventEmitter {
2001
2227
  "Required post-spawn enforcement must declare sync or async mode",
2002
2228
  );
2003
2229
  }
2004
- return {
2230
+ const validatedPlan = {
2005
2231
  ...plan,
2006
2232
  args: [...plan.args],
2007
2233
  options: { ...plan.options },
@@ -2021,6 +2247,15 @@ class ProcessExecutionBroker extends EventEmitter {
2021
2247
  : {}),
2022
2248
  postSpawn: { ...postSpawn },
2023
2249
  };
2250
+ if (windowsPlanBindingConsumed) {
2251
+ const upstreamCleanup = validatedPlan.cleanup;
2252
+ validatedPlan.cleanup = (...args) => {
2253
+ admittedWindowsMcpCodeSnapshotPlans.delete(validatedPlan);
2254
+ return upstreamCleanup?.(...args);
2255
+ };
2256
+ admittedWindowsMcpCodeSnapshotPlans.add(validatedPlan);
2257
+ }
2258
+ return validatedPlan;
2024
2259
  }
2025
2260
 
2026
2261
  _assertRequiredSandboxBoundaries(plan, requiredBoundaries) {
@@ -2055,10 +2290,20 @@ class ProcessExecutionBroker extends EventEmitter {
2055
2290
  },
2056
2291
  );
2057
2292
  }
2058
- return {
2293
+ const assertedPlan = {
2059
2294
  ...plan,
2060
2295
  requiredBoundaries: [...requiredBoundaries],
2061
2296
  };
2297
+ if (admittedWindowsMcpCodeSnapshotPlans.has(plan)) {
2298
+ admittedWindowsMcpCodeSnapshotPlans.delete(plan);
2299
+ const upstreamCleanup = assertedPlan.cleanup;
2300
+ assertedPlan.cleanup = (...args) => {
2301
+ admittedWindowsMcpCodeSnapshotPlans.delete(assertedPlan);
2302
+ return upstreamCleanup?.(...args);
2303
+ };
2304
+ admittedWindowsMcpCodeSnapshotPlans.add(assertedPlan);
2305
+ }
2306
+ return assertedPlan;
2062
2307
  }
2063
2308
 
2064
2309
  _prepareSandboxPlan(
@@ -2112,17 +2357,44 @@ class ProcessExecutionBroker extends EventEmitter {
2112
2357
  // Keep the legacy string profile in argument four. The built-in adapter
2113
2358
  // reserves argument five for runtime injection, so the typed request is
2114
2359
  // additive in argument six and legacy injected adapters can ignore it.
2115
- const rawPlan = this._sandboxAdapter.applySandbox(
2116
- command,
2117
- args || [],
2118
- options,
2119
- profile,
2120
- undefined,
2121
- adapterRequest,
2122
- );
2360
+ const sandboxAdapter = this._sandboxAdapter;
2361
+ const applySandboxAdapter = sandboxAdapter.applySandbox;
2362
+ const builtInSandboxAdapter = applySandboxAdapter === _applySandbox;
2363
+ // Never dispatch the built-in through a mutable Function property or a
2364
+ // global reflective helper after consulting an injected adapter getter.
2365
+ // The lexical import is the identity we checked and the implementation we
2366
+ // invoke. Legacy adapters retain their historical `this` receiver.
2367
+ const rawPlan = builtInSandboxAdapter
2368
+ ? _applySandbox(
2369
+ command,
2370
+ args || [],
2371
+ options,
2372
+ profile,
2373
+ undefined,
2374
+ adapterRequest,
2375
+ )
2376
+ : Reflect.apply(applySandboxAdapter, sandboxAdapter, [
2377
+ command,
2378
+ args || [],
2379
+ options,
2380
+ profile,
2381
+ undefined,
2382
+ adapterRequest,
2383
+ ]);
2123
2384
  let plan;
2124
2385
  try {
2125
- plan = this._validateSandboxPlan(rawPlan);
2386
+ plan = this._validateSandboxPlan(rawPlan, {
2387
+ command,
2388
+ args: Object.freeze([...(args || [])]),
2389
+ cwd: options.cwd,
2390
+ shell: options.shell,
2391
+ detached: options.detached,
2392
+ executionContract: sandboxPolicy.executionContract || null,
2393
+ profile,
2394
+ requiredBoundaries: Object.freeze([...requiredBoundaries]),
2395
+ sync,
2396
+ builtInSandboxAdapter,
2397
+ });
2126
2398
  plan = this._assertRequiredSandboxBoundaries(plan, requiredBoundaries);
2127
2399
 
2128
2400
  if (!plan.applied && strict) {
@@ -2135,7 +2407,12 @@ class ProcessExecutionBroker extends EventEmitter {
2135
2407
  }
2136
2408
 
2137
2409
  if (plan.applied && plan.postSpawn.required) {
2138
- if (typeof this._sandboxAdapter.postSpawnSandbox !== "function") {
2410
+ const builtInWindowsMcpPostSpawn =
2411
+ admittedWindowsMcpCodeSnapshotPlans.has(plan);
2412
+ if (
2413
+ !builtInWindowsMcpPostSpawn &&
2414
+ typeof this._sandboxAdapter.postSpawnSandbox !== "function"
2415
+ ) {
2139
2416
  throw this._sandboxError(
2140
2417
  "post_spawn_adapter_unavailable",
2141
2418
  "Required post-spawn sandbox adapter is unavailable",
@@ -2350,7 +2627,28 @@ class ProcessExecutionBroker extends EventEmitter {
2350
2627
 
2351
2628
  let postSpawnResult;
2352
2629
  try {
2353
- postSpawnResult = this._sandboxAdapter.postSpawnSandbox(proc, plan);
2630
+ const windowsMcpPlanBindingDeclared =
2631
+ plan.platform === "win32" &&
2632
+ plan.runtimeProbe?.planBindingMechanism ===
2633
+ "windows-mcp-code-snapshot-plan-binding-v1";
2634
+ const builtInWindowsMcpPlan =
2635
+ admittedWindowsMcpCodeSnapshotPlans.has(plan);
2636
+ if (windowsMcpPlanBindingDeclared && !builtInWindowsMcpPlan) {
2637
+ throw this._sandboxError(
2638
+ "windows_mcp_plan_binding_consumed",
2639
+ "Windows MCP sandbox plan binding is unavailable or already consumed",
2640
+ );
2641
+ }
2642
+ if (builtInWindowsMcpPlan) {
2643
+ // Burn the one-launch post-spawn authority before invoking untrusted
2644
+ // process-facing code. Success, failure, cleanup, and reentry all
2645
+ // observe the capability as consumed.
2646
+ admittedWindowsMcpCodeSnapshotPlans.delete(plan);
2647
+ }
2648
+ const postSpawnAdapter = builtInWindowsMcpPlan
2649
+ ? (child, boundPlan) => boundPlan.postSpawnWindows(child)
2650
+ : this._sandboxAdapter.postSpawnSandbox;
2651
+ postSpawnResult = postSpawnAdapter(proc, plan);
2354
2652
  } catch (error) {
2355
2653
  this._applySandboxAudit(auditEntry, plan, false);
2356
2654
  auditEntry.sandboxState = "failed";