chainlesschain 0.163.1 → 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 (169) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-Cn7quRgL.js → AIOps-DnGsmsqJ.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-YqMX3ueH.js → ActionButton-CrO6fcQ7.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-Bxmy1b7Y.js → Analytics-DsBdOaP2.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-DBOw69jE.js → AppLayout-DmQslKUB.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-mq1nyzN1.js → Artifacts-BvyrT_QQ.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-mMiKtZ0D.js → Audit-prndoLiC.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-WBUjpYVh.js → BackgroundAgents-DOTFyA55.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-c25OoJgs.js → Backup-9zOnPp_8.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-BbfWhZ4-.js → BaseInput-C4PC6sAG.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-CVVzsTwU.js → Chat-BBAF-W9v.js} +6 -6
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CVCjZJ04.js → ChatBubbleRenderer-CWhvvloO.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-C9o2HK-1.js → Checkbox-BI9iculd.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-B7X5LfKc.js → Codegen-3DP9BCKb.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-jpPj2Pur.js → Col-df-2TnJX.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-Dti6bHxN.js → Community-CHs8gG_A.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-S4ZsLt3W.js → Compact-CDfF6q7V.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-Bge0sQ3O.js → Compliance-CthrDnO7.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-C4XyzVI7.js → Cowork-HjIqsWJw.js} +2 -2
  20. package/src/assets/web-panel/assets/{Cron-CPR0v2xy.js → Cron-BKc196fb.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-DAX8lDaj.js → Crosschain-CJnjdc8W.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-fBHPa0QH.js → DID-BHUy-8Q2.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-vvaUTafU.js → Dashboard-QDB7sKeY.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-DyaQM63v.js → Dropdown-DStcVK11.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-CAF0wiU2.js → EmailListRenderer-BwSUskMJ.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-ia-WzDRs.js → FamilyGuardDashboard-DgF_kurT.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-Cz3gHoT5.js → Federation-k8wvv-wN.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CJQDJr4Q.js → FormItemContext-C11qoq2r.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-B05BZlQp.js → GenericCardRenderer-BIIpr9kg.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DT0YcQnI.js → Git-BlA1exTe.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-Bqbl6m5Q.js → Governance-CYa1ZYM4.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-BdebLR0N.js → Inference-6_kKVIt6.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-M36b8YYV.js → KnowledgeGraph-CB4AwxYy.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-5LN_XL43.js → Logs-xf7nHFAe.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-Bf3DEqP6.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-BkIin-QY.js → Marketplace-aPg8e4Jt.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Bkppx8Uj.js → McpTools-C-TNlVUf.js} +5 -5
  38. package/src/assets/web-panel/assets/{Memory-Qk9wg_Ib.js → Memory-DMTPIpGa.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-BsTDU3Aj.js → MobileBridge-BxyvveRq.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-CrZW5I28.js → MobileProjects-DyPCrAyQ.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-BMkmgtsA.js → Mtc-BdhqNXp6.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-6m4CC0Yn.js → MtcAudit-Cz-HFxzW.js} +5 -5
  43. package/src/assets/web-panel/assets/{Multisig-BZ8yB7QV.js → Multisig-CIUaFNsx.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-CxitAMIO.js → NLProgramming-CWe6-J17.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-Bv0msnHu.js → Notes-vYAKeviU.js} +4 -4
  46. package/src/assets/web-panel/assets/{NotificationSettings-DeVMqM3P.js → NotificationSettings-DQL9-2d7.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-CXBSWa3R.js → OrderTableRenderer-DnXj1jBn.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-b_G5Vs1Q.js → Organization-B3spU8AN.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-DW7riOmA.js → Overflow-DgEwo7vm.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-CtpQNYjL.js → P2P-hujMRH8X.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-Ba63yT4l.js → PdhVaultBrowser-C_qhdg9h.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-DnzyeB67.js → Permissions-vp7LMcSf.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-DbPZ7HWw.js → PersonalDataHub-Dxr5Hgnq.js} +3 -3
  54. package/src/assets/web-panel/assets/{Pipeline-gs_HOThJ.js → Pipeline-DEPZqqH4.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-CZlQ1EjE.js → Privacy-DTpDiKPe.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-DQp__Ccb.js → ProjectInit-jDJsRWmF.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-C7h2sOWZ.js → ProjectSettings-Dhor5RWH.js} +2 -2
  58. package/src/assets/web-panel/assets/{Projects-DdCpNRNt.js → Projects-08xUDZGt.js} +1 -1
  59. package/src/assets/web-panel/assets/Providers-BGs47s1a.js +1 -0
  60. package/src/assets/web-panel/assets/{QrScannerModal-B_8M1-FC.js → QrScannerModal-CjIw-wIb.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-Bpycr8WD.js → QuickAsk-DX6jcqoi.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-Z4TrcNzs.js → Recommend-DopXkhar.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-BD6TsJlS.js → RemoteSession-BLvqJE9c.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-IKxDXHEu.js → Reputation-DhRj2Me7.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-DbmR20tJ.js → Row-DQ53vuPq.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-CLjA5PPf.js → RssFeed-BslvwiBD.js} +2 -2
  67. package/src/assets/web-panel/assets/{Search-Bm3owbIU.js → Search-DJKBDNKZ.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CY4RyOuq.js → Security-COhpxHER.js} +3 -3
  69. package/src/assets/web-panel/assets/{Services-CYO9qrd_.js → Services-dbulD6cI.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-ClF51Go6.js → Skeleton-ciIVNfhC.js} +1 -1
  71. package/src/assets/web-panel/assets/Skills-AiRTkTCk.js +1 -0
  72. package/src/assets/web-panel/assets/{Sla-zqpDUxzP.js → Sla-DDMcWYBc.js} +1 -1
  73. package/src/assets/web-panel/assets/{SpeechSettings-DPSi8Qco.js → SpeechSettings-BPxWbpXO.js} +1 -1
  74. package/src/assets/web-panel/assets/{SyncSettings-CqABopsQ.js → SyncSettings-BoEOXCyg.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-4dbAJng4.js → Tasks-CEYFJwmr.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Dzl6f0M2.js → Templates-UowY8Ixe.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-XeZkw40a.js → Tenant-DauSLQXN.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-CYw2YzPm.js → Terminal-DBj7Jneq.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-Bc2pko4i.js → TimelineRenderer-UMrPwoZC.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-CfCenOHx.js → Tokens-4ea96-bn.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-DTz-_YqV.js → Trigger--ISCqt4b.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-CB3tt3Z6.js → Trust-D4GVimRJ.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-y1ykmMvU.js → UkeySign-Ci-nXRQc.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-UlZ_lX0e.js → VideoEditing-Cjk7mKPw.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-DMBaHTha.js → Wallet-BgOLOO3Z.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Cksm-hBI.js → WebAuthn-CCX0K29i.js} +4 -4
  87. package/src/assets/web-panel/assets/{WorkflowEditor-BhOa40sX.js → WorkflowEditor-Ch3zgIsE.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-DNbeSTDO.js → chat-DKOU_2Vb.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-9zz8gBmW.js → colors-6OVo4u3C.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-D7aoVv-5.js → compact-item-BH78Hlsq.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DYg7B8nd.js → createContext-CFRpSbbC.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DEMblAIm.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-BNbhkcoI.js → hasIn-DNQhgcVi.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-gNKj00Fx.js → index--rq90rL9.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-FlBuITVG.js → index-7TC3S8SN.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-nnmo3ipi.js → index-AuBhLqOm.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-Dn-JFqEi.js → index-BDSR7ecX.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DUWmZ059.js → index-BHa4WyTZ.js} +1 -1
  99. package/src/assets/web-panel/assets/index-BTvq-36D.js +1 -0
  100. package/src/assets/web-panel/assets/{index--TvoQ6UC.js → index-BYrnm5Ob.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CpEIwp4A.js → index-B_Z-YoxX.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DnTM8FWK.js → index-BaVE6E8y.js} +3 -3
  103. package/src/assets/web-panel/assets/{index-67GdrUx2.js → index-Bb6kDrUx.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BPojutcZ.js → index-BepBTpa8.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-CV06YdPO.js → index-BkN3iTTp.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CN6-OEgS.js → index-BnnXQot_.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DHskwmwI.js → index-BujsOZfc.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-B9zUawcE.js → index-BxRy5LPR.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-C8LC0nvw.js → index-CFPJ8yzF.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-DMrqEsOS.js → index-CNuCHHQT.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-Da0SysnX.js → index-CaYqY35Z.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Cq3l0L7C.js → index-CkNEMANR.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DIljkSt9.js → index-CkqHgG-b.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CYu-F-gp.js → index-CrcLHN2F.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DtQzs0hH.js → index-Cu3L4r5l.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-SmEIFaRm.js → index-D3RtTT4K.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-ZPDbEh-L.js → index-D84id2Y4.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CzDDeZBo.js → index-DKN2noIF.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-Bdxe0nrD.js → index-DaDgdJYj.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-uc8Rz96X.js → index-Du0rnksC.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-Cqy-hqD9.js → index-DvHGtNnF.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-B9TzVW7i.js → index-Eag8e_mA.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BRd1zkLB.js → index-HNGGVF6o.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-jS6NASar.js → index-Y9MJv28e.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DIMVe3HJ.js → index-bKm3TUDp.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-B8irlIUK.js → index-caye7AOE.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CRKukX1W.js → index-cdf7fd7d.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DeD1wWA8.js → index-dDkoL4Pe.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CA72qB1n.js → index-hPY0fFrd.js} +1 -1
  130. package/src/assets/web-panel/assets/index-hUpvk6Jl.js +1 -0
  131. package/src/assets/web-panel/assets/{index-_-Vt1Wqk.js → index-nbfHl1oV.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-m2pXS3W2.js → index-sm7W8AXy.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-D0mTMUGz.js → initDefaultProps-BZ9w6jPL.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-DK16p4-o.js → motion-BnwUiOho.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-DalC20HC.js → move-ByUKJnNm.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-B5RusszF.js → mtc-parser-V7yK1KEl.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-C9Mhitht.js → omit-BEXBBt4j.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-51xQLgwM.js → pickAttrs-qDm_46Gi.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-CJzIqp8u.js → placementArrow-BIbhEo_0.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-HQvC19u4.js → responsiveObserve-NbPbDgA_.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-C6hhabOp.js → slide-BnUWglZ0.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-Q1r48-oc.js → statusUtils-BX8_wZI5.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-UakVWrHs.js → styleChecker-BV4OycQX.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Dmv94cxx.js → useFlexGapSupport-Od_H5llY.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-DrxOnt_V.js → useFs-BWI-PyiX.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-BVf2M-Hg.js → usePersonalDataHub-BqMuhG3g.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-BzzW9qKH.js → vnode-DNd23z6f.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-C1ZvMgAZ.js → zoom-Cjaxnm7l.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/commands/mcp.js +29 -1
  151. package/src/data/changelog.json +15 -2
  152. package/src/harness/mcp-client.js +15 -2
  153. package/src/lib/cowork-mcp-tools.js +1 -0
  154. package/src/lib/cowork-task-templates.js +1 -0
  155. package/src/lib/mcp-stdio-executable-identity.js +75 -11
  156. package/src/lib/mcp-stdio-execution-authority.js +5 -0
  157. package/src/lib/process-execution-broker/index.js +316 -22
  158. package/src/lib/process-execution-broker/platform-sandbox.js +481 -20
  159. package/src/lib/process-execution-broker/windows-sandbox-helper.dll +0 -0
  160. package/src/lib/process-execution-broker/windows-sandbox-helper.exe +0 -0
  161. package/src/lib/process-execution-broker/windows-sandbox.cs +5 -4
  162. package/src/lib/skill-mcp.js +10 -0
  163. package/src/runtime/mcp-config.js +3 -0
  164. package/src/assets/web-panel/assets/MarkdownRenderer-BCb1Dm8l.js +0 -1
  165. package/src/assets/web-panel/assets/Providers-CyvtUkUf.js +0 -1
  166. package/src/assets/web-panel/assets/Skills-CCCEmSf5.js +0 -1
  167. package/src/assets/web-panel/assets/devWarning-uadaGF_y.js +0 -1
  168. package/src/assets/web-panel/assets/index-C7zhie9M.js +0 -1
  169. package/src/assets/web-panel/assets/index-Cmbg0Wbr.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" ||
@@ -1180,6 +1186,9 @@ class ProcessExecutionBroker extends EventEmitter {
1180
1186
  "contentSnapshotScope",
1181
1187
  "contentSnapshotMechanism",
1182
1188
  "runtimeLaunchMechanism",
1189
+ "planBindingMechanism",
1190
+ "runtimeLaunchPath",
1191
+ "entrySnapshotPath",
1183
1192
  "pluginTreeContentSnapshotScope",
1184
1193
  "pluginTreeContentSnapshotMechanism",
1185
1194
  "pluginTreeSnapshotConsistency",
@@ -1208,6 +1217,7 @@ class ProcessExecutionBroker extends EventEmitter {
1208
1217
  "sharedLibraryClosure",
1209
1218
  "entrySnapshotAtomic",
1210
1219
  "runtimeLaunchAtomic",
1220
+ "mcpCapsuleCodeSnapshot",
1211
1221
  ]) {
1212
1222
  if (
1213
1223
  plan.runtimeProbe[field] !== undefined &&
@@ -1243,6 +1253,7 @@ class ProcessExecutionBroker extends EventEmitter {
1243
1253
  "runtimeSnapshotSha256",
1244
1254
  "runtimeAttestedSha256",
1245
1255
  "entrySnapshotSha256",
1256
+ "planBindingDigest",
1246
1257
  ]) {
1247
1258
  if (
1248
1259
  plan.runtimeProbe[field] !== undefined &&
@@ -1255,6 +1266,22 @@ class ProcessExecutionBroker extends EventEmitter {
1255
1266
  );
1256
1267
  }
1257
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
+ }
1258
1285
  if (
1259
1286
  plan.runtimeProbe.pluginTreeContentSnapshotDigest !== undefined &&
1260
1287
  (typeof plan.runtimeProbe.pluginTreeContentSnapshotDigest !==
@@ -1560,15 +1587,97 @@ class ProcessExecutionBroker extends EventEmitter {
1560
1587
  SANDBOX_BOUNDARIES.CODE_SNAPSHOT,
1561
1588
  );
1562
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;
1563
1669
  const exactSnapshotEvidence =
1564
1670
  plan.applied === true &&
1565
1671
  candidateBackend === null &&
1672
+ contractBoundSnapshotEvidence &&
1566
1673
  plan.runtimeProbe.attempted === true &&
1567
1674
  plan.runtimeProbe.runnable === true &&
1568
1675
  plan.runtimeProbe.reason === null &&
1569
1676
  plan.runtimeProbe.probeRuntime === "node" &&
1570
1677
  plan.runtimeProbe.targetRuntime === "node" &&
1571
1678
  plan.runtimeProbe.contentSnapshot === true &&
1679
+ plan.runtimeProbe.entrySnapshotAtomic === true &&
1680
+ plan.runtimeProbe.runtimeLaunchAtomic === true &&
1572
1681
  plan.runtimeProbe.sharedLibraryClosure === false &&
1573
1682
  /^[a-f0-9]{64}$/.test(plan.runtimeProbe.entrySnapshotSha256 || "") &&
1574
1683
  Number.isSafeInteger(plan.runtimeProbe.entrySnapshotBytes) &&
@@ -1584,8 +1693,54 @@ class ProcessExecutionBroker extends EventEmitter {
1584
1693
  plan.runtimeProbe.contentSnapshotScope ===
1585
1694
  "mcp-capsule-entry-and-node-runtime" &&
1586
1695
  plan.runtimeProbe.contentSnapshotMechanism ===
1587
- "verified-o_tmpfile-copy-inherited-fd-exec-v1" &&
1696
+ "verified-o_tmpfile-copy-inherited-fd-module-compile-v1" &&
1588
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 &&
1705
+ /^[a-f0-9]{64}$/.test(
1706
+ plan.runtimeProbe.runtimeSnapshotSha256 || "",
1707
+ ) &&
1708
+ Number.isSafeInteger(plan.runtimeProbe.runtimeSnapshotBytes) &&
1709
+ plan.runtimeProbe.runtimeSnapshotBytes > 0 &&
1710
+ plan.runtimeProbe.runtimeSnapshotBytes <= 256 * 1024 * 1024 &&
1711
+ /^\/proc\/self\/fd\/\d+$/.test(plan.command) &&
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 &&
1589
1744
  /^[a-f0-9]{64}$/.test(
1590
1745
  plan.runtimeProbe.runtimeSnapshotSha256 || "",
1591
1746
  ) &&
@@ -1593,7 +1748,14 @@ class ProcessExecutionBroker extends EventEmitter {
1593
1748
  plan.runtimeProbe.runtimeSnapshotBytes > 0 &&
1594
1749
  plan.runtimeProbe.runtimeSnapshotBytes <= 256 * 1024 * 1024 &&
1595
1750
  /^\/proc\/self\/fd\/\d+$/.test(plan.command) &&
1596
- /^\/proc\/self\/fd\/\d+$/.test(plan.args[0] || "");
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
+ );
1597
1759
  const windowsSnapshotEvidence =
1598
1760
  plan.platform === "win32" &&
1599
1761
  [
@@ -1601,10 +1763,14 @@ class ProcessExecutionBroker extends EventEmitter {
1601
1763
  "windows-appcontainer-job-restricted-token",
1602
1764
  ].includes(backend) &&
1603
1765
  plan.enforcement === backend &&
1604
- [
1605
- "windows-plugin-node-entry-snapshot-v1",
1606
- "windows-appcontainer-launch-attestation-v1",
1607
- ].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)) &&
1608
1774
  plan.runtimeProbe.contentSnapshotScope ===
1609
1775
  "mcp-capsule-entry-source" &&
1610
1776
  plan.runtimeProbe.contentSnapshotMechanism ===
@@ -1614,15 +1780,23 @@ class ProcessExecutionBroker extends EventEmitter {
1614
1780
  plan.runtimeProbe.runtimeLaunchAtomic === true &&
1615
1781
  plan.runtimeProbe.runtimeLaunchMechanism ===
1616
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 &&
1617
1787
  /^[a-f0-9]{64}$/.test(
1618
1788
  plan.runtimeProbe.runtimeAttestedSha256 || "",
1619
1789
  ) &&
1620
1790
  Number.isSafeInteger(plan.runtimeProbe.runtimeAttestedBytes) &&
1621
1791
  plan.runtimeProbe.runtimeAttestedBytes > 0 &&
1622
- plan.runtimeProbe.runtimeAttestedBytes <= 256 * 1024 * 1024;
1792
+ plan.runtimeProbe.runtimeAttestedBytes <= 256 * 1024 * 1024 &&
1793
+ launchContext.builtInSandboxAdapter === true &&
1794
+ windowsPlanBindingConsumed;
1623
1795
  if (
1624
1796
  !exactSnapshotEvidence ||
1625
- (!linuxSnapshotEvidence && !windowsSnapshotEvidence)
1797
+ (!linuxSnapshotEvidence &&
1798
+ !linuxBubblewrapSnapshotEvidence &&
1799
+ !windowsSnapshotEvidence)
1626
1800
  ) {
1627
1801
  throw this._sandboxError(
1628
1802
  "invalid_sandbox_plan",
@@ -1910,6 +2084,22 @@ class ProcessExecutionBroker extends EventEmitter {
1910
2084
  ...(plan.runtimeProbe.handleAtomic !== undefined
1911
2085
  ? { handleAtomic: plan.runtimeProbe.handleAtomic }
1912
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
+ : {}),
1913
2103
  ...(plan.runtimeProbe.contentSnapshotScope !== undefined
1914
2104
  ? {
1915
2105
  contentSnapshotScope: plan.runtimeProbe.contentSnapshotScope,
@@ -1921,12 +2111,35 @@ class ProcessExecutionBroker extends EventEmitter {
1921
2111
  plan.runtimeProbe.contentSnapshotMechanism,
1922
2112
  }
1923
2113
  : {}),
2114
+ ...(plan.runtimeProbe.planBindingMechanism !== undefined
2115
+ ? {
2116
+ planBindingMechanism: plan.runtimeProbe.planBindingMechanism,
2117
+ planBindingDigest: plan.runtimeProbe.planBindingDigest,
2118
+ }
2119
+ : {}),
1924
2120
  ...(plan.runtimeProbe.runtimeSnapshotSha256 !== undefined
1925
2121
  ? {
1926
2122
  runtimeSnapshotSha256: plan.runtimeProbe.runtimeSnapshotSha256,
1927
2123
  runtimeSnapshotBytes: plan.runtimeProbe.runtimeSnapshotBytes,
1928
2124
  entrySnapshotSha256: plan.runtimeProbe.entrySnapshotSha256,
1929
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,
1930
2143
  sharedLibraryClosure: plan.runtimeProbe.sharedLibraryClosure,
1931
2144
  }
1932
2145
  : {}),
@@ -1988,6 +2201,15 @@ class ProcessExecutionBroker extends EventEmitter {
1988
2201
  };
1989
2202
  }
1990
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
+ }
1991
2213
  if (backend === "linux-bwrap-workspace" && !genericWorkspaceProbe) {
1992
2214
  throw this._sandboxError(
1993
2215
  "invalid_sandbox_plan",
@@ -2005,7 +2227,7 @@ class ProcessExecutionBroker extends EventEmitter {
2005
2227
  "Required post-spawn enforcement must declare sync or async mode",
2006
2228
  );
2007
2229
  }
2008
- return {
2230
+ const validatedPlan = {
2009
2231
  ...plan,
2010
2232
  args: [...plan.args],
2011
2233
  options: { ...plan.options },
@@ -2025,6 +2247,15 @@ class ProcessExecutionBroker extends EventEmitter {
2025
2247
  : {}),
2026
2248
  postSpawn: { ...postSpawn },
2027
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;
2028
2259
  }
2029
2260
 
2030
2261
  _assertRequiredSandboxBoundaries(plan, requiredBoundaries) {
@@ -2059,10 +2290,20 @@ class ProcessExecutionBroker extends EventEmitter {
2059
2290
  },
2060
2291
  );
2061
2292
  }
2062
- return {
2293
+ const assertedPlan = {
2063
2294
  ...plan,
2064
2295
  requiredBoundaries: [...requiredBoundaries],
2065
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;
2066
2307
  }
2067
2308
 
2068
2309
  _prepareSandboxPlan(
@@ -2116,17 +2357,44 @@ class ProcessExecutionBroker extends EventEmitter {
2116
2357
  // Keep the legacy string profile in argument four. The built-in adapter
2117
2358
  // reserves argument five for runtime injection, so the typed request is
2118
2359
  // additive in argument six and legacy injected adapters can ignore it.
2119
- const rawPlan = this._sandboxAdapter.applySandbox(
2120
- command,
2121
- args || [],
2122
- options,
2123
- profile,
2124
- undefined,
2125
- adapterRequest,
2126
- );
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
+ ]);
2127
2384
  let plan;
2128
2385
  try {
2129
- 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
+ });
2130
2398
  plan = this._assertRequiredSandboxBoundaries(plan, requiredBoundaries);
2131
2399
 
2132
2400
  if (!plan.applied && strict) {
@@ -2139,7 +2407,12 @@ class ProcessExecutionBroker extends EventEmitter {
2139
2407
  }
2140
2408
 
2141
2409
  if (plan.applied && plan.postSpawn.required) {
2142
- if (typeof this._sandboxAdapter.postSpawnSandbox !== "function") {
2410
+ const builtInWindowsMcpPostSpawn =
2411
+ admittedWindowsMcpCodeSnapshotPlans.has(plan);
2412
+ if (
2413
+ !builtInWindowsMcpPostSpawn &&
2414
+ typeof this._sandboxAdapter.postSpawnSandbox !== "function"
2415
+ ) {
2143
2416
  throw this._sandboxError(
2144
2417
  "post_spawn_adapter_unavailable",
2145
2418
  "Required post-spawn sandbox adapter is unavailable",
@@ -2354,7 +2627,28 @@ class ProcessExecutionBroker extends EventEmitter {
2354
2627
 
2355
2628
  let postSpawnResult;
2356
2629
  try {
2357
- 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);
2358
2652
  } catch (error) {
2359
2653
  this._applySandboxAudit(auditEntry, plan, false);
2360
2654
  auditEntry.sandboxState = "failed";