chainlesschain 0.166.102 → 0.166.103

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 (198) hide show
  1. package/package.json +1 -1
  2. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  3. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-CyHIMEd8.js → AIOps-BLrXpdnP.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-vuNxDpHm.js → ActionButton-C0xy9uFy.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-D0quEM0q.js → Analytics-C6EephQP.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-xRSVpbCs.js → AppLayout-ZCXdOD9y.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-ktfVAZBC.js → Artifacts-D4MfZ-pl.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-UJW6maH4.js → Audit-BQ8c3bBu.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-BYrfdCoT.js → BackgroundAgents-BOA7_ljM.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-IBgsJ7BK.js → Backup-60uiQjGT.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-BmP8_zxy.js → BaseInput-BDvEbGs_.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-urkw8_BF.js → Chat-B3IkAuFQ.js} +6 -6
  14. package/src/assets/web-panel/assets/ChatBubbleRenderer-n6BVStHf.js +1 -0
  15. package/src/assets/web-panel/assets/{Checkbox-CYboo-__.js → Checkbox-njGbfJWq.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-DaqR_Ay8.js → Codegen-CF7DtdxC.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-04BSIj_z.js → Col-C_3Zix40.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-DxFk7Trv.js → Community-CzU-ZC2d.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-mjgWlMCB.js → Compact-BgeqsPRh.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-CC5ee7QV.js → Compliance-6l7cwiqp.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-BK4BhHZd.js → Cowork-D4s905fI.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-CP6jAxq0.js → Cron-CGTYSxRS.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-DJPaViZS.js → Crosschain-BnSo-Yt3.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-BTLxkuOj.js → DID-Dm4vk2X1.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-Djkiqh3d.js → Dashboard-D7H-PZ_N.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-t_eUhqom.js → Dropdown-COslkgxn.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-7w6USx_J.js → EmailListRenderer-CJWEetmk.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-mU5IHEk5.js → EvolutionSettings-BbzebAWe.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BCh-VBBC.js → FamilyGuardDashboard-BsoTOXwk.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-Be_VpjI2.js → Federation-Ck5kM_5H.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-D_lzQ7PI.js → FormItemContext-gShxCqtF.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-LYu3KapV.js → GenericCardRenderer-DarN1G-z.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-BBeF-PP4.js → Git-CJfpLyP5.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-CoF8Kzg7.js → Governance-CVcJmpQz.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-C4DLMnXS.js → Inference-ComU_ig8.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-B2mlNewk.js → KnowledgeGraph-35hprFJy.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-DMZ_44Ya.js → Logs-BQDqBTz0.js} +2 -2
  38. package/src/assets/web-panel/assets/{MarkdownRenderer-Ck7Iv_9e.js → MarkdownRenderer-BpdGAVCC.js} +1 -1
  39. package/src/assets/web-panel/assets/{Marketplace-BqDzTew_.js → Marketplace-B9O9OKnn.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-BbwSbDN9.js → McpTools-VMKxA4Wc.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-DAaTWgrm.js → Memory-CcBbf3Bc.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-BjbTGxoR.js → MobileBridge-D7myz46N.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-DMODOBr-.js → MobileProjects-Da5KBXyx.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-DT9N2rCs.js → Mtc-x3NPZfuL.js} +5 -5
  45. package/src/assets/web-panel/assets/{MtcAudit-DagMfUVv.js → MtcAudit-CwnzptEC.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-C1BKP6nM.js → Multisig-CCAxf4Ye.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-B5LFh72i.js → NLProgramming-CptHKz-Q.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-Q77V3ltW.js → Notes-0uEp4DCJ.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-HxdpNIBs.js → NotificationSettings-DthvrOLd.js} +1 -1
  50. package/src/assets/web-panel/assets/OrderTableRenderer-CxXuPzZg.js +1 -0
  51. package/src/assets/web-panel/assets/{Organization-QL3NZ7uW.js → Organization-BWf2tmQQ.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-B_gqOKho.js → Overflow-BbvAtEth.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-BBJubU8Z.js → P2P-zBo6enit.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-CFnGd-2E.js → PdhVaultBrowser-D_LMQ4A4.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-BKkznIUM.js → Permissions-C1ucb2ck.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-DYK7ZAcd.js → PersonalDataHub-Bz64RddJ.js} +5 -5
  57. package/src/assets/web-panel/assets/{Pipeline-CoeKpjoN.js → Pipeline-DXJt3y3_.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-Diw4G-92.js → Privacy-DiZ8b_ut.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-CHBOFkma.js → ProjectInit-DfLKKrJ4.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-BJIsgdOf.js → ProjectSettings-Ct6kJuIY.js} +2 -2
  61. package/src/assets/web-panel/assets/Projects-BBUMlZ3m.js +1 -0
  62. package/src/assets/web-panel/assets/{Providers-o8QCimor.js → Providers-DYVQPHvc.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-z2W-zvhW.js → QrScannerModal-23Il7iPp.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-_yubhsna.js → QuickAsk-WgOZKrv1.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-CucgJwih.js → Recommend-CRIka6xT.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-EzfIIRg1.js → RemoteSession-DOy3GjVZ.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-_shttE67.js → Reputation-BXyi6xeR.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-DQA_S8-9.js → Row-CoMxuIcR.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-BOqWawXT.js → RssFeed-87hPkoM6.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-Dx1v2xOq.js → Search-B1EqFCO4.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-Bt4HHsT4.js → Security-HcC41eGs.js} +4 -4
  72. package/src/assets/web-panel/assets/{Services-sruHiQ-r.js → Services-BqLwmvCM.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-CiBxvmOJ.js → Skeleton-CIMmjW4r.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-De9qKODU.js → Skills-CgurezJU.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-B_6yn8Wp.js → Sla-CJuRuqPE.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-C2CafExS.js → SpeechSettings-BUwsbd1o.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-Dhh3Qmb0.js → SyncSettings-qo04TOX-.js} +2 -2
  78. package/src/assets/web-panel/assets/Tasks-QEFENVsp.js +1 -0
  79. package/src/assets/web-panel/assets/{Templates-D7WVTQQy.js → Templates-D1PTczPW.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-7ur9Yfxd.js → Tenant-Bi0FkEPR.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-BgzrOA6k.js → Terminal-DfSt3bIF.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-Dco20pT1.js → TimelineRenderer-B7bIVs4R.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-hN6qBPag.js → Tokens-B6w5XrMb.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-C4f_twAM.js → Trigger-XXVSDWiF.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-Wf1SMypp.js → Trust-DYvlgcK-.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-DUXSyg3N.js → UkeySign-XyYwJMBM.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-BvqsJaL0.js → VideoEditing-C47WbtHH.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-CgAbcjKl.js → Wallet-CYfqTj_C.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-DaLT0W3s.js → WebAuthn-3AduFn1l.js} +3 -3
  90. package/src/assets/web-panel/assets/{WorkflowEditor-CQqAXoaS.js → WorkflowEditor-DHYEHjMJ.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-BhlohFTB.js → chat-AeehErSw.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-D7HqXIL8.js → colors-DKXJ8paX.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-Bqk4FCLY.js → compact-item-BOlCiomD.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-CEmWrWf0.js → createContext-BAP6U85b.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-rGldFhxo.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-CDY0pFi2.js → hasIn-BLmeL1Xe.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-BHGOdvOQ.js → index-B0IjlB9m.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DmKdCWq1.js → index-BAS2QqLn.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-CqK0J4Sj.js → index-BRcJlKSa.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-B8L3_-sG.js → index-BSOenF5s.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CrsM-oiD.js → index-BTnp4Nt3.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BPmRkxeX.js → index-BhcpWl5z.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CVrwozwH.js → index-Bn54FU3i.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-C02yDu4f.js → index-Bpx54vfs.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-Chxt0t-A.js → index-Bs2O3f81.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-C3opQg47.js → index-Bt-FCVzh.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-DPBoWNwq.js → index-BuUwKmEI.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-Cur88hoN.js → index-C5AKY6bJ.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-XErJQ1yF.js → index-C8qi53Ki.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BxYO6nde.js → index-CFKzWIo8.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-CkqBoCiu.js → index-CRa4pAaM.js} +3 -3
  112. package/src/assets/web-panel/assets/{index-DGKRAO61.js → index-CaHhfpBi.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-e9oCy7_4.js → index-CdNSmvog.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BiLu-ImR.js → index-CgtaOzMo.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-lBAbMOzg.js → index-CiqeF0Pf.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-D0nfNmbq.js → index-ClpwxOXo.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BxXFRLTZ.js → index-Co7pjF53.js} +1 -1
  118. package/src/assets/web-panel/assets/index-Cw-lfvvV.js +1 -0
  119. package/src/assets/web-panel/assets/{index-Dwob5XoD.js → index-DE7cbDDe.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-DpI1LqJX.js → index-DQLQuwpA.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DuMt3ewl.js → index-DWYqOI1A.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-BXRooi-O.js → index-De2fPxdb.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-1HBam9t1.js → index-DpZqbc4w.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C9mvnSii.js → index-DsQ38fVY.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DEzL7s7P.js → index-Dv8-g1pY.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-o_lc3eww.js → index-EKNODw4P.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-6f6n0KFR.js → index-FPXLIXoy.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-DRcDWMwP.js → index-IlzfIRNh.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BNrvBWDS.js → index-OLKhib9T.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Cf1ha8l0.js → index-PEe9OWEQ.js} +1 -1
  131. package/src/assets/web-panel/assets/index-QBXRSyoZ.js +1 -0
  132. package/src/assets/web-panel/assets/{index-CYcjOnDX.js → index-T28naovw.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CkjgSHVz.js → index-ZMbXl5lo.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BuKGuH_y.js → index-urPvyUVk.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-aBHlgMrq.js → index-wyKpTsGM.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-CIeEUxIN.js → initDefaultProps-CDWa1rnn.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-IPIj1ZtP.js → motion-CX2Cnsd5.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-BfSeXZ-f.js → move-Bfe1NcEF.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-DX03-Xp4.js → mtc-parser-DbdqleHE.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-z9EannfX.js → omit-CE2K7NVv.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-DXKmRkqZ.js → pickAttrs-y_bZgxWG.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-k2HV7cIU.js → placementArrow-BOHR4zwr.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-bX7CsyWy.js → responsiveObserve-B8Jwq05-.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-NskjQLbJ.js → slide-BD7RJ3Kn.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-B3IoG-Er.js → statusUtils-BuxDJeDx.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-DHv_UilX.js → styleChecker-DgYQ2Q0o.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-DEqGB5Ng.js → useFlexGapSupport-DAHF0Fwi.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-Bl9CbrqZ.js → useFs-D4kDyLFp.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-O-Ukv93M.js → usePersonalDataHub-BHtSxW4A.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-hGCHTaZt.js → vnode-CHKtdqW0.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-BWhIVeKQ.js → zoom-CIZAMma9.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/commands/ask.js +6 -4
  154. package/src/commands/team.js +28 -19
  155. package/src/data/changelog.json +13 -0
  156. package/src/harness/prompt-compressor.js +2 -0
  157. package/src/lib/advisor-runtime.js +4 -2
  158. package/src/lib/agent-ipc-bus.js +2 -0
  159. package/src/lib/background-agent-keeper-client.js +3 -0
  160. package/src/lib/browser-automation.js +4 -0
  161. package/src/lib/cc-android-bridge.js +4 -0
  162. package/src/lib/chat-core.js +11 -9
  163. package/src/lib/cloud/cloud-client.js +10 -1
  164. package/src/lib/cowork-adapter.js +4 -3
  165. package/src/lib/decision-layer/providers.js +16 -11
  166. package/src/lib/evolution/governed-hub-llm.js +31 -16
  167. package/src/lib/evolution/governed-hub-resolver.js +4 -0
  168. package/src/lib/evolution/governed-skill-synthesis-process-grader.js +4 -0
  169. package/src/lib/evomap-client.js +14 -2
  170. package/src/lib/formal-budget-authority.js +191 -59
  171. package/src/lib/formal-budget-contract.js +7 -13
  172. package/src/lib/formal-budget-errors.js +31 -0
  173. package/src/lib/formal-budget-lineage-registry.js +612 -0
  174. package/src/lib/formal-budget-provider-scope.js +143 -0
  175. package/src/lib/formal-budget-transport.js +235 -100
  176. package/src/lib/gateway-client-resilience.js +5 -0
  177. package/src/lib/hub-llm-client.js +25 -16
  178. package/src/lib/llm-connection-probe.js +17 -10
  179. package/src/lib/llm-providers.js +4 -1
  180. package/src/lib/model-failure-policy.js +2 -0
  181. package/src/lib/plugin-runtime/marketplace-network.js +9 -5
  182. package/src/lib/process-execution-broker/credential-agent.js +7 -2
  183. package/src/lib/process-execution-broker/credential-transport.js +4 -0
  184. package/src/lib/process-execution-broker/index.js +8 -0
  185. package/src/lib/provider-stream.js +28 -13
  186. package/src/lib/sandbox-egress-worker.js +3 -0
  187. package/src/lib/stream-retry.js +2 -0
  188. package/src/lib/sub-agent-context.js +6 -3
  189. package/src/lib/web-fetch.js +2 -0
  190. package/src/lib/web-search.js +5 -0
  191. package/src/runtime/agent-core.js +30 -9
  192. package/src/assets/web-panel/assets/ChatBubbleRenderer-Cw44zZbh.js +0 -1
  193. package/src/assets/web-panel/assets/OrderTableRenderer-Dc0DpvBH.js +0 -1
  194. package/src/assets/web-panel/assets/Projects-GJjItXIk.js +0 -1
  195. package/src/assets/web-panel/assets/Tasks-Mvo5mTWm.js +0 -1
  196. package/src/assets/web-panel/assets/devWarning-YPX_TU7w.js +0 -1
  197. package/src/assets/web-panel/assets/index-D53szVZQ.js +0 -1
  198. package/src/assets/web-panel/assets/index-Ub2nJbV2.js +0 -1
@@ -1,4 +1,4 @@
1
- import{K as o}from"./index-CkqBoCiu.js";import{i as f}from"./motion-IPIj1ZtP.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
1
+ import{K as o}from"./index-CRa4pAaM.js";import{i as f}from"./motion-CX2Cnsd5.js";const c=new o("antZoomIn",{"0%":{transform:"scale(0.2)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),y=new o("antZoomOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.2)",opacity:0}}),a=new o("antZoomBigIn",{"0%":{transform:"scale(0.8)",opacity:0},"100%":{transform:"scale(1)",opacity:1}}),s=new o("antZoomBigOut",{"0%":{transform:"scale(1)"},"100%":{transform:"scale(0.8)",opacity:0}}),g=new o("antZoomUpIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 0%"}}),O=new o("antZoomUpOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 0%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 0%",opacity:0}}),l=new o("antZoomLeftIn",{"0%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"0% 50%"}}),u=new o("antZoomLeftOut",{"0%":{transform:"scale(1)",transformOrigin:"0% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"0% 50%",opacity:0}}),p=new o("antZoomRightIn",{"0%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"100% 50%"}}),z=new o("antZoomRightOut",{"0%":{transform:"scale(1)",transformOrigin:"100% 50%"},"100%":{transform:"scale(0.8)",transformOrigin:"100% 50%",opacity:0}}),K=new o("antZoomDownIn",{"0%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0},"100%":{transform:"scale(1)",transformOrigin:"50% 100%"}}),w=new o("antZoomDownOut",{"0%":{transform:"scale(1)",transformOrigin:"50% 100%"},"100%":{transform:"scale(0.8)",transformOrigin:"50% 100%",opacity:0}}),I={zoom:{inKeyframes:c,outKeyframes:y},"zoom-big":{inKeyframes:a,outKeyframes:s},"zoom-big-fast":{inKeyframes:a,outKeyframes:s},"zoom-left":{inKeyframes:l,outKeyframes:u},"zoom-right":{inKeyframes:p,outKeyframes:z},"zoom-up":{inKeyframes:g,outKeyframes:O},"zoom-down":{inKeyframes:K,outKeyframes:w}},h=(n,r)=>{const{antCls:m}=n,t=`${m}-${r}`,{inKeyframes:i,outKeyframes:e}=I[r];return[f(t,i,e,r==="zoom-big-fast"?n.motionDurationFast:n.motionDurationMid),{[`
2
2
  ${t}-enter,
3
3
  ${t}-appear
4
4
  `]:{transform:"scale(0)",opacity:0,animationTimingFunction:n.motionEaseOutCirc,"&-prepare":{transform:"none"}},[`${t}-leave`]:{animationTimingFunction:n.motionEaseInOutCirc}}]};export{h as i,c as z};
@@ -8,7 +8,7 @@
8
8
  // Injected by web-ui-server.js at serve time
9
9
  window.__CC_CONFIG__ = __CC_CONFIG_PLACEHOLDER__;
10
10
  </script>
11
- <script type="module" crossorigin src="./assets/index-CkqBoCiu.js"></script>
11
+ <script type="module" crossorigin src="./assets/index-CRa4pAaM.js"></script>
12
12
  <link rel="modulepreload" crossorigin href="./assets/vendor-Bn1JzzAn.js">
13
13
  <link rel="modulepreload" crossorigin href="./assets/icons-DG5UD-6K.js">
14
14
  <link rel="stylesheet" crossorigin href="./assets/index-Cq93VfoF.css">
@@ -21,6 +21,7 @@
21
21
  * used /api/generate, which broke against the Android server.
22
22
  */
23
23
 
24
+ import { providerFetch } from "../lib/formal-budget-provider-scope.js";
24
25
  import ora from "ora";
25
26
  import { randomUUID } from "node:crypto";
26
27
  import { types as utilTypes } from "node:util";
@@ -128,8 +129,9 @@ export async function queryLLM(
128
129
  // under vitest so it never pollutes spawned-bin test stderr.
129
130
  if (!process.env.VITEST && !process.env.VITEST_WORKER_ID) {
130
131
  try {
131
- const { maybeWarnDeprecatedModel } =
132
- await import("../lib/model-deprecation.js");
132
+ const { maybeWarnDeprecatedModel } = await import(
133
+ "../lib/model-deprecation.js"
134
+ );
133
135
  maybeWarnDeprecatedModel({ model });
134
136
  } catch {
135
137
  /* fail-open: a deprecation notice must never affect the query */
@@ -140,7 +142,7 @@ export async function queryLLM(
140
142
  const baseUrl = options.baseUrl || "http://localhost:11434";
141
143
  // Use /api/chat (modern Ollama API + only endpoint Android LocalLlmServer
142
144
  // implements). Non-streaming mode keeps the response shape simple.
143
- const response = await fetch(`${baseUrl}/api/chat`, {
145
+ const response = await providerFetch(`${baseUrl}/api/chat`, {
144
146
  method: "POST",
145
147
  headers: { "Content-Type": "application/json" },
146
148
  body: JSON.stringify({
@@ -183,7 +185,7 @@ export async function queryLLM(
183
185
  }
184
186
 
185
187
  const apiBase = options.baseUrl || providerDef.baseUrl;
186
- const response = await fetch(`${apiBase}/chat/completions`, {
188
+ const response = await providerFetch(`${apiBase}/chat/completions`, {
187
189
  method: "POST",
188
190
  headers: {
189
191
  "Content-Type": "application/json",
@@ -40,6 +40,7 @@ import {
40
40
  normalizeTeamScopes,
41
41
  } from "../lib/agent-team/team-scope-lock.js";
42
42
  import { executionBroker } from "../lib/process-execution-broker/index.js";
43
+ import { requireUnscopedDescendantControl } from "../lib/formal-budget-provider-scope.js";
43
44
  import {
44
45
  createCollaborationRun,
45
46
  createCollaborationRunId,
@@ -1025,7 +1026,9 @@ function planWaves(reg) {
1025
1026
 
1026
1027
  /** Real executor: run a task's shell `command`, success = exit 0. */
1027
1028
  export function makeShellRunTask() {
1028
- return function runTask({ task, signal = null }) {
1029
+ return function runTask(payload) {
1030
+ requireUnscopedDescendantControl();
1031
+ const { task, signal = null } = payload;
1029
1032
  const command = task.metadata?.command || task?.command;
1030
1033
  if (!command) {
1031
1034
  throw new Error(`task "${task.key}" has no \`command\` to --exec`);
@@ -1128,6 +1131,7 @@ export function makeShellRunTask() {
1128
1131
 
1129
1132
  /** Spawn a headless `cc agent -p` for one prompt in `cwd`; resolve on exit 0. */
1130
1133
  function spawnAgentProcess(prompt, cwd, opts = {}) {
1134
+ requireUnscopedDescendantControl();
1131
1135
  return new Promise((resolve, reject) => {
1132
1136
  const formalQualityHermetic = isFormalQualityHermeticRuntime(process.env);
1133
1137
  const parser = new TeamAgentStreamParser({
@@ -1445,6 +1449,7 @@ function spawnAgentProcess(prompt, cwd, opts = {}) {
1445
1449
  }
1446
1450
 
1447
1451
  export function spawnAgent(prompt, cwd, opts = {}) {
1452
+ requireUnscopedDescendantControl();
1448
1453
  if (!opts.messageBridge || isFormalQualityHermeticRuntime(process.env)) {
1449
1454
  return spawnAgentProcess(prompt, cwd, opts);
1450
1455
  }
@@ -1492,20 +1497,22 @@ function applyBudgetReservation(contract, budgetReservation) {
1492
1497
  }
1493
1498
 
1494
1499
  export function makeAgentRunTask(opts = {}) {
1495
- return function runTask({
1496
- key,
1497
- task,
1498
- holder,
1499
- inbox = [],
1500
- sendMessage = null,
1501
- messageAuthority = null,
1502
- recipientState = null,
1503
- requestFollowupWake = null,
1504
- requestHandoff = null,
1505
- mailbox = null,
1506
- budgetReservation = null,
1507
- signal = null,
1508
- }) {
1500
+ return function runTask(payload) {
1501
+ requireUnscopedDescendantControl();
1502
+ const {
1503
+ key,
1504
+ task,
1505
+ holder,
1506
+ inbox = [],
1507
+ sendMessage = null,
1508
+ messageAuthority = null,
1509
+ recipientState = null,
1510
+ requestFollowupWake = null,
1511
+ requestHandoff = null,
1512
+ mailbox = null,
1513
+ budgetReservation = null,
1514
+ signal = null,
1515
+ } = payload;
1509
1516
  const prompt = task.metadata?.prompt || task?.prompt;
1510
1517
  if (!prompt) {
1511
1518
  throw new Error(`task "${key}" has no \`prompt\` to --agent`);
@@ -3087,8 +3094,9 @@ export function registerTeamCommand(program, { logger } = {}) {
3087
3094
  let recorder = null;
3088
3095
  let collectorEnabled = false;
3089
3096
  try {
3090
- const { isOtlpCollectorEnabled } =
3091
- await import("../lib/observability/index.js");
3097
+ const { isOtlpCollectorEnabled } = await import(
3098
+ "../lib/observability/index.js"
3099
+ );
3092
3100
  collectorEnabled = isOtlpCollectorEnabled();
3093
3101
  } catch {
3094
3102
  collectorEnabled = false;
@@ -3096,8 +3104,9 @@ export function registerTeamCommand(program, { logger } = {}) {
3096
3104
  const workflowRunId = `team-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
3097
3105
  const workflowName = path.basename(options.tasks);
3098
3106
  if (options.otlp || collectorEnabled) {
3099
- const { TelemetryRecorder } =
3100
- await import("../lib/telemetry/span-recorder.js");
3107
+ const { TelemetryRecorder } = await import(
3108
+ "../lib/telemetry/span-recorder.js"
3109
+ );
3101
3110
  recorder = new TelemetryRecorder({
3102
3111
  defaultAttributes: {
3103
3112
  "workflow.run_id": workflowRunId,
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.166.103",
7
+ "cliVersions": ["0.166.103"],
8
+ "date": null,
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Fixed - cc CLI 0.166.103: reject ungoverned formal budget exits",
13
+ "body": "- Keep formal paid evaluation closed while budgeted requests lack production\n account, checkpoint and host isolation evidence.\n- Reject direct Agent tools, subprocess and worker launches, credential and\n network paths when entered from the formal budget scope; propagate rejection\n through parallel tool execution.\n- Bind the frozen all-Volcengine 36-task and 9-first-run plan to its exact\n model, endpoint and shared historical $99 budget without counting diagnostic\n calls as formal observations.\n- Pair VS Code 0.37.147 and JetBrains 0.4.165 with CLI 0.166.103 only after\n the exact release commit passes its complete Actions gates and npm readback."
14
+ }
15
+ ]
16
+ },
4
17
  {
5
18
  "productVersion": null,
6
19
  "cliVersion": "0.166.102",
@@ -17,6 +17,7 @@ import {
17
17
  } from "../lib/read-file-page.js";
18
18
  import { feature, featureVariant } from "../lib/feature-flags.js";
19
19
  import { isAbortError } from "../lib/abort-utils.js";
20
+ import { isFormalBudgetError } from "../lib/formal-budget-errors.js";
20
21
  import {
21
22
  CONTEXT_WINDOWS,
22
23
  getContextWindow,
@@ -680,6 +681,7 @@ export class PromptCompressor {
680
681
  // A durable-ledger write failure is authoritative too. Falling back here
681
682
  // would let the host continue after losing the model-call boundary.
682
683
  if (error?.runtimeLedgerPersistence === true) throw error;
684
+ if (isFormalBudgetError(error)) throw error;
683
685
  if (error?.code === "CC_AGENT_EVOLUTION_INGRESS_FAILED") throw error;
684
686
  // A workflow-bound query may already have reached the provider. An
685
687
  // extractive fallback would make the outer durable effect look completed
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { createHash, randomUUID } from "node:crypto";
11
11
  import { CostBudget } from "./cost-budget.js";
12
+ import { isFormalBudgetError } from "./formal-budget-errors.js";
12
13
  import { FREE_PROVIDERS, mergePricing } from "./llm-pricing.js";
13
14
  import { redactSecrets } from "./secret-scan.js";
14
15
  import { firstBalancedJson } from "./json-schema-output.js";
@@ -179,8 +180,8 @@ export function resolveAdvisorConfig({
179
180
  );
180
181
  const hasManagedAdvisorPolicy = Boolean(
181
182
  Object.keys(managedAdvisor).length > 0 ||
182
- managed?.advisorAllowedProviders !== undefined ||
183
- managed?.advisorAllowedModels !== undefined,
183
+ managed?.advisorAllowedProviders !== undefined ||
184
+ managed?.advisorAllowedModels !== undefined,
184
185
  );
185
186
  let policyReason = null;
186
187
  if (managedAdvisor.enabled === false) {
@@ -937,6 +938,7 @@ export class AdvisorRuntime {
937
938
  };
938
939
  } catch (error) {
939
940
  if (error?.runtimeLedgerPersistence === true) throw error;
941
+ if (isFormalBudgetError(error)) throw error;
940
942
  if (error?.code === "CC_AGENT_EVOLUTION_INGRESS_FAILED") throw error;
941
943
  const failure = {
942
944
  callId,
@@ -13,6 +13,7 @@ import { EventEmitter } from "node:events";
13
13
  import crypto from "node:crypto";
14
14
  import { EventRuntimeProducer } from "./event-runtime-producer.js";
15
15
  import { EventRuntimeStore } from "./event-runtime-store.js";
16
+ import { requireUnscopedDescendantControl } from "./formal-budget-provider-scope.js";
16
17
  import executionBroker from "./process-execution-broker/index.js";
17
18
  import {
18
19
  AGENT_IPC_DEFAULT_LIMITS,
@@ -284,6 +285,7 @@ class AgentIPCBus extends EventEmitter {
284
285
  * @returns {Promise<{process: ChildProcess, agentId: string}>}
285
286
  */
286
287
  async spawnAgentProcess(command, args = [], options = {}) {
288
+ requireUnscopedDescendantControl();
287
289
  const agentId = options.agentId || crypto.randomUUID();
288
290
  if (
289
291
  this._childTransports.has(agentId) ||
@@ -1,6 +1,7 @@
1
1
  import net from "node:net";
2
2
  import { randomBytes } from "node:crypto";
3
3
  import { createNdjsonReader } from "./background-session-transport.js";
4
+ import { requireUnscopedDescendantControl } from "./formal-budget-provider-scope.js";
4
5
  import {
5
6
  BACKGROUND_AGENT_KEEPER_ARM,
6
7
  BACKGROUND_AGENT_KEEPER_ARMED,
@@ -67,6 +68,7 @@ async function connectWithDeadline(pipePath, timeoutMs) {
67
68
  }
68
69
 
69
70
  export async function connectBackgroundAgentKeeper(options = {}) {
71
+ requireUnscopedDescendantControl();
70
72
  const hello = normalizeBackgroundAgentKeeperHello(options);
71
73
  const connectTimeoutMs = Math.max(
72
74
  1,
@@ -234,6 +236,7 @@ export async function connectBackgroundAgentKeeper(options = {}) {
234
236
 
235
237
  return Object.freeze({
236
238
  async arm(turn) {
239
+ requireUnscopedDescendantControl();
237
240
  const normalized = normalizeBackgroundAgentKeeperTurn(turn);
238
241
  if (activeTurn) {
239
242
  throw keeperError(
@@ -3,10 +3,13 @@
3
3
  * Uses built-in fetch for basic operations, optional playwright for screenshots.
4
4
  */
5
5
 
6
+ import { requireUnscopedExternalToolAccess } from "./formal-budget-provider-scope.js";
7
+
6
8
  /**
7
9
  * Fetch a URL and return the raw HTML.
8
10
  */
9
11
  export async function fetchPage(url, options = {}) {
12
+ requireUnscopedExternalToolAccess();
10
13
  const timeout = options.timeout || 30000;
11
14
  const controller = new AbortController();
12
15
  const timer = setTimeout(() => controller.abort(), timeout);
@@ -179,6 +182,7 @@ export function extractLinks(html, baseUrl) {
179
182
  * Returns null if playwright is not installed.
180
183
  */
181
184
  export async function takeScreenshot(url, outputPath, options = {}) {
185
+ requireUnscopedExternalToolAccess();
182
186
  try {
183
187
  const { chromium } = await import("playwright");
184
188
  const browser = await chromium.launch({ headless: true });
@@ -32,6 +32,7 @@
32
32
 
33
33
  import { readFileSync, existsSync } from "node:fs";
34
34
  import { join, dirname } from "node:path";
35
+ import { requireUnscopedExternalToolAccess } from "./formal-budget-provider-scope.js";
35
36
 
36
37
  const ANDROID_PREFIX = "/data/data/com.chainlesschain.android/";
37
38
 
@@ -72,6 +73,7 @@ function resolveBridgeConfigDir() {
72
73
  * (server not started yet, or running off-device without override).
73
74
  */
74
75
  export function loadBridgeConfig() {
76
+ requireUnscopedExternalToolAccess();
75
77
  const dir = resolveBridgeConfigDir();
76
78
  if (!dir) return null;
77
79
  try {
@@ -109,6 +111,7 @@ export class AndroidBridgeUnavailableError extends Error {
109
111
  * - Method name unknown (server returns {"error": "UNKNOWN_METHOD"})
110
112
  */
111
113
  export async function invoke(method, params = {}) {
114
+ requireUnscopedExternalToolAccess();
112
115
  if (typeof method !== "string" || method.length === 0) {
113
116
  throw new TypeError(
114
117
  "cc-android-bridge.invoke: method must be non-empty string",
@@ -170,6 +173,7 @@ export async function invoke(method, params = {}) {
170
173
  * Returns `{ available: boolean, reason?: string, port?: number }`.
171
174
  */
172
175
  export function caps() {
176
+ requireUnscopedExternalToolAccess();
173
177
  if (process.env.CC_ANDROID_BRIDGE_OVERRIDE === "1") {
174
178
  return { available: true, reason: "test-override" };
175
179
  }
@@ -1,3 +1,4 @@
1
+ import { providerFetch } from "./formal-budget-provider-scope.js";
1
2
  /**
2
3
  * Chat Core — transport-independent streaming chat logic
3
4
  *
@@ -21,6 +22,7 @@ import {
21
22
  waitForStreamRetry,
22
23
  } from "./stream-retry.js";
23
24
  import { throwIfAborted } from "./abort-utils.js";
25
+ import { isFormalBudgetError } from "./formal-budget-errors.js";
24
26
 
25
27
  // A streaming chat call must not hang forever if the API accepts the connection
26
28
  // but then goes silent (TCP up, no bytes). Abort the request if no data arrives
@@ -132,7 +134,7 @@ export async function streamOllama(
132
134
  guard.bump();
133
135
  let response;
134
136
  try {
135
- response = await fetch(`${baseUrl}/api/chat`, {
137
+ response = await providerFetch(`${baseUrl}/api/chat`, {
136
138
  method: "POST",
137
139
  headers: { "Content-Type": "application/json" },
138
140
  body: JSON.stringify({
@@ -146,7 +148,7 @@ export async function streamOllama(
146
148
  });
147
149
  } catch (e) {
148
150
  guard.stop();
149
- throw guard.stalled()
151
+ throw guard.stalled() && !isFormalBudgetError(e)
150
152
  ? new Error(
151
153
  `Ollama request stalled (no response in ${STREAM_STALL_MS / 1000}s)`,
152
154
  )
@@ -213,7 +215,7 @@ export async function streamOllama(
213
215
  }
214
216
  } catch (e) {
215
217
  throw attachStreamRetryMetadata(
216
- guard.stalled()
218
+ guard.stalled() && !isFormalBudgetError(e)
217
219
  ? new Error(
218
220
  `Ollama stream stalled (no data in ${STREAM_STALL_MS / 1000}s)`,
219
221
  )
@@ -247,7 +249,7 @@ export async function streamOpenAI(
247
249
  guard.bump();
248
250
  let response;
249
251
  try {
250
- response = await fetch(`${baseUrl}/chat/completions`, {
252
+ response = await providerFetch(`${baseUrl}/chat/completions`, {
251
253
  method: "POST",
252
254
  headers: {
253
255
  "Content-Type": "application/json",
@@ -267,7 +269,7 @@ export async function streamOpenAI(
267
269
  });
268
270
  } catch (e) {
269
271
  guard.stop();
270
- throw guard.stalled()
272
+ throw guard.stalled() && !isFormalBudgetError(e)
271
273
  ? new Error(
272
274
  `API request stalled (no response in ${STREAM_STALL_MS / 1000}s)`,
273
275
  )
@@ -344,7 +346,7 @@ export async function streamOpenAI(
344
346
  }
345
347
  } catch (e) {
346
348
  throw attachStreamRetryMetadata(
347
- guard.stalled()
349
+ guard.stalled() && !isFormalBudgetError(e)
348
350
  ? new Error(
349
351
  `API stream stalled (no data in ${STREAM_STALL_MS / 1000}s)`,
350
352
  )
@@ -392,7 +394,7 @@ export async function streamAnthropic(
392
394
  guard.bump();
393
395
  let response;
394
396
  try {
395
- response = await fetch(`${baseUrl}/messages`, {
397
+ response = await providerFetch(`${baseUrl}/messages`, {
396
398
  method: "POST",
397
399
  headers: {
398
400
  "Content-Type": "application/json",
@@ -412,7 +414,7 @@ export async function streamAnthropic(
412
414
  });
413
415
  } catch (e) {
414
416
  guard.stop();
415
- throw guard.stalled()
417
+ throw guard.stalled() && !isFormalBudgetError(e)
416
418
  ? new Error(
417
419
  `Anthropic request stalled (no response in ${STREAM_STALL_MS / 1000}s)`,
418
420
  )
@@ -486,7 +488,7 @@ export async function streamAnthropic(
486
488
  }
487
489
  } catch (e) {
488
490
  throw attachStreamRetryMetadata(
489
- guard.stalled()
491
+ guard.stalled() && !isFormalBudgetError(e)
490
492
  ? new Error(
491
493
  `Anthropic stream stalled (no data in ${STREAM_STALL_MS / 1000}s)`,
492
494
  )
@@ -28,6 +28,7 @@ import {
28
28
  import { join } from "node:path";
29
29
  import { getHomeDir } from "../paths.js";
30
30
  import { ResilientGatewayClient } from "../gateway-client-resilience.js";
31
+ import { requireUnscopedDescendantControl } from "../formal-budget-provider-scope.js";
31
32
 
32
33
  export const _deps = { fetch: (...a) => globalThis.fetch(...a) };
33
34
 
@@ -78,6 +79,7 @@ export class CloudClient {
78
79
  * @param {object} opts { baseUrl, token, deps? }
79
80
  */
80
81
  constructor(opts = {}) {
82
+ requireUnscopedDescendantControl();
81
83
  this.baseUrl = String(opts.baseUrl || "").replace(/\/+$/, "");
82
84
  if (!this.baseUrl) {
83
85
  throw new Error(
@@ -109,6 +111,7 @@ export class CloudClient {
109
111
  }
110
112
 
111
113
  async _json(method, path, body) {
114
+ requireUnscopedDescendantControl();
112
115
  const res = await this.deps.fetch(`${this.baseUrl}${path}`, {
113
116
  method,
114
117
  headers: this._headers(),
@@ -121,7 +124,9 @@ export class CloudClient {
121
124
  }
122
125
 
123
126
  /** Submit a job. `bundle` is a base64 git bundle of the branch. */
124
- async submit({ task, bundle, branch, baseSha }) {
127
+ async submit(payload) {
128
+ requireUnscopedDescendantControl();
129
+ const { task, bundle, branch, baseSha } = payload;
125
130
  const data = await this._json("POST", "/v1/jobs", {
126
131
  task,
127
132
  bundle,
@@ -133,10 +138,12 @@ export class CloudClient {
133
138
  }
134
139
 
135
140
  async status(jobId) {
141
+ requireUnscopedDescendantControl();
136
142
  return this._json("GET", `/v1/jobs/${encodeURIComponent(jobId)}`);
137
143
  }
138
144
 
139
145
  async result(jobId) {
146
+ requireUnscopedDescendantControl();
140
147
  return this._json("GET", `/v1/jobs/${encodeURIComponent(jobId)}/result`);
141
148
  }
142
149
 
@@ -146,6 +153,7 @@ export class CloudClient {
146
153
  * runners remain compatible with status()/result().
147
154
  */
148
155
  async events(jobId, options = {}) {
156
+ requireUnscopedDescendantControl();
149
157
  if (!/^[\w.-]+$/.test(String(jobId || ""))) {
150
158
  throw new Error(`invalid job id: ${jobId}`);
151
159
  }
@@ -175,6 +183,7 @@ export const TERMINAL_CLOUD_STATUS = new Set(["done", "failed"]);
175
183
  * `sleep`/`now` injected for tests.
176
184
  */
177
185
  export async function pollUntilDone(client, jobId, opts = {}) {
186
+ requireUnscopedDescendantControl();
178
187
  const intervalMs = opts.intervalMs ?? 3000;
179
188
  const timeoutMs = opts.timeoutMs ?? 30 * 60_000;
180
189
  const sleep = opts.sleep || ((ms) => new Promise((r) => setTimeout(r, ms)));
@@ -7,6 +7,7 @@
7
7
  * - Module initialization helper
8
8
  */
9
9
 
10
+ import { providerFetch } from "./formal-budget-provider-scope.js";
10
11
  import { LLMProviderRegistry, BUILT_IN_PROVIDERS } from "./llm-providers.js";
11
12
  import { loadConfig } from "./config-manager.js";
12
13
  import { applyConfigLlmDefaults } from "./llm-config-defaults.js";
@@ -174,7 +175,7 @@ export function createChatFn(options = {}) {
174
175
  currentModel,
175
176
  async ({ signal = opts.signal || resolved.signal } = {}) => {
176
177
  const modelMessages = await prepareMessages();
177
- const res = await fetch(`${baseUrl}/api/chat`, {
178
+ const res = await providerFetch(`${baseUrl}/api/chat`, {
178
179
  method: "POST",
179
180
  signal: requestSignal(signal),
180
181
  headers: { "Content-Type": "application/json" },
@@ -214,7 +215,7 @@ export function createChatFn(options = {}) {
214
215
  ? { system: systemMsgs.map((m) => m.content).join("\n") }
215
216
  : {}),
216
217
  };
217
- const res = await fetch(`${baseUrl}/messages`, {
218
+ const res = await providerFetch(`${baseUrl}/messages`, {
218
219
  method: "POST",
219
220
  signal: requestSignal(signal),
220
221
  headers: {
@@ -245,7 +246,7 @@ export function createChatFn(options = {}) {
245
246
  currentModel,
246
247
  async ({ signal = opts.signal || resolved.signal } = {}) => {
247
248
  const modelMessages = await prepareMessages();
248
- const res = await fetch(`${baseUrl}/chat/completions`, {
249
+ const res = await providerFetch(`${baseUrl}/chat/completions`, {
249
250
  method: "POST",
250
251
  signal: requestSignal(signal),
251
252
  headers: {
@@ -1,4 +1,5 @@
1
1
  import { openDecisionProviderAuthority } from "./provider-authority.js";
2
+ import { providerFetch } from "../formal-budget-provider-scope.js";
2
3
 
3
4
  const PROVIDERS = Object.freeze({
4
5
  typesafe: {
@@ -195,18 +196,22 @@ export function createDecisionProvider({
195
196
  if (Buffer.byteLength(body, "utf8") > MAX_DECISION_REQUEST_BYTES) {
196
197
  throw bodyTooLarge("request", MAX_DECISION_REQUEST_BYTES);
197
198
  }
198
- const response = await fetchImpl(endpoint, {
199
- method: "POST",
200
- headers: {
201
- ...(secret === undefined
202
- ? {}
203
- : { authorization: `Bearer ${secret}` }),
204
- "content-type": "application/json",
199
+ const response = await providerFetch(
200
+ endpoint,
201
+ {
202
+ method: "POST",
203
+ headers: {
204
+ ...(secret === undefined
205
+ ? {}
206
+ : { authorization: `Bearer ${secret}` }),
207
+ "content-type": "application/json",
208
+ },
209
+ body,
210
+ signal,
211
+ redirect: "error",
205
212
  },
206
- body,
207
- signal,
208
- redirect: "error",
209
- });
213
+ fetchImpl,
214
+ );
210
215
  if (!response?.ok) {
211
216
  throw providerError(response?.status ?? 0, options.provider);
212
217
  }
@@ -1,6 +1,10 @@
1
1
  import { createRequire } from "node:module";
2
2
  import { types } from "node:util";
3
3
  import { prepareGovernedModelTurn } from "./governed-model-turn.js";
4
+ import {
5
+ providerFetch,
6
+ requireUnscopedModelTransport,
7
+ } from "../formal-budget-provider-scope.js";
4
8
 
5
9
  const { createAuthenticatedEvolutionModelClient } = createRequire(
6
10
  import.meta.url,
@@ -97,21 +101,25 @@ function captureHubTransport(llm, sdk) {
97
101
  const signal = options.signal
98
102
  ? AbortSignal.any([controller.signal, options.signal])
99
103
  : controller.signal;
100
- const response = await fetchImpl(`${baseUrl}/api/chat`, {
101
- method: "POST",
102
- headers: { "Content-Type": "application/json" },
103
- redirect: "error",
104
- signal,
105
- body: JSON.stringify({
106
- model,
107
- messages,
108
- stream: false,
109
- options: {
110
- temperature: options.temperature ?? 0.2,
111
- ...(options.numCtx ? { num_ctx: options.numCtx } : {}),
112
- },
113
- }),
114
- });
104
+ const response = await providerFetch(
105
+ `${baseUrl}/api/chat`,
106
+ {
107
+ method: "POST",
108
+ headers: { "Content-Type": "application/json" },
109
+ redirect: "error",
110
+ signal,
111
+ body: JSON.stringify({
112
+ model,
113
+ messages,
114
+ stream: false,
115
+ options: {
116
+ temperature: options.temperature ?? 0.2,
117
+ ...(options.numCtx ? { num_ctx: options.numCtx } : {}),
118
+ },
119
+ }),
120
+ },
121
+ fetchImpl,
122
+ );
115
123
  if (!response.ok)
116
124
  throw new Error(
117
125
  `Hub Ollama request failed: HTTP ${response.status}`,
@@ -202,6 +210,7 @@ function captureHubTransport(llm, sdk) {
202
210
  );
203
211
  },
204
212
  async chat(messages, options) {
213
+ requireUnscopedModelTransport();
205
214
  const result = await chat(messages, options);
206
215
  const text =
207
216
  result?.content ??
@@ -233,7 +242,13 @@ function captureHubTransport(llm, sdk) {
233
242
  },
234
243
  };
235
244
  }
236
- return { assertIdentity() {}, chat: llm.chat.bind(llm) };
245
+ return {
246
+ assertIdentity() {},
247
+ chat(messages, options) {
248
+ requireUnscopedModelTransport();
249
+ return llm.chat(messages, options);
250
+ },
251
+ };
237
252
  }
238
253
 
239
254
  // A scoped wrapper preserves the Hub's independent local/cloud consent check.
@@ -1,4 +1,5 @@
1
1
  import { prepareGovernedModelTurn } from "./governed-model-turn.js";
2
+ import { requireUnscopedModelTransport } from "../formal-budget-provider-scope.js";
2
3
  import {
3
4
  captureGovernedHubSdkPorts,
4
5
  createGovernedHubLlm,
@@ -48,6 +49,9 @@ function captureEmbeddingTransport(stage, sdk) {
48
49
  );
49
50
  },
50
51
  async embed(profile) {
52
+ // Neither arbitrary embedding callbacks nor the native embeddings
53
+ // protocol have a verified Chat billing contract in this scope.
54
+ requireUnscopedModelTransport();
51
55
  if (!defaultOllama) return await embed.call(stage, profile);
52
56
  // The raw SDK ollamaEmbed remains closed. This private transport is only
53
57
  // invoked below, after the scoped Run projected the profile.
@@ -8,6 +8,7 @@ import executionBroker, {
8
8
  SANDBOX_BOUNDARIES,
9
9
  } from "../process-execution-broker/index.js";
10
10
  import { BUILT_IN_PROVIDERS } from "../llm-providers.js";
11
+ import { requireUnscopedModelTransport } from "../formal-budget-provider-scope.js";
11
12
 
12
13
  export const GOVERNED_SKILL_SYNTHESIS_PROCESS_GRADER_SCHEMA =
13
14
  "chainlesschain.governed-skill-synthesis-process-grader/v2";
@@ -399,6 +400,9 @@ export function createGovernedSkillSynthesisProcessGrader(options = {}) {
399
400
  persistentProcessAuditRequired: true,
400
401
  });
401
402
  const port = async (messages) => {
403
+ // This worker owns a separate credential reference and cannot inherit an
404
+ // async-local authority. Refuse before provisioning or launching it.
405
+ requireUnscopedModelTransport();
402
406
  const current = executionSnapshot();
403
407
  if (!executionSnapshotMatches(current, snapshot)) {
404
408
  throw new Error(