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
@@ -7,6 +7,8 @@
7
7
  * Lightweight: uses native fetch, no heavy dependencies.
8
8
  */
9
9
 
10
+ import { requireUnscopedPaidService } from "./formal-budget-provider-scope.js";
11
+
10
12
  // Exported for test injection
11
13
  export const _deps = {
12
14
  fetch: globalThis.fetch,
@@ -21,7 +23,9 @@ export class EvoMapClient {
21
23
  * @param {string} [options.apiKey] - Optional API key for authenticated endpoints
22
24
  * @param {number} [options.timeout] - Request timeout in ms
23
25
  */
24
- constructor({ hubUrl, apiKey, timeout } = {}) {
26
+ constructor(options = {}) {
27
+ requireUnscopedPaidService();
28
+ const { hubUrl, apiKey, timeout } = options;
25
29
  this.hubUrl = hubUrl || process.env.EVOMAP_HUB_URL || DEFAULT_HUB;
26
30
  this.apiKey = apiKey || process.env.EVOMAP_API_KEY || "";
27
31
  this.timeout = timeout || 10000;
@@ -35,7 +39,9 @@ export class EvoMapClient {
35
39
  * @param {number} [options.limit] - Max results
36
40
  * @returns {Promise<Array<{ id, name, description, author, version, downloads, rating }>>}
37
41
  */
38
- async search(query, { category, limit = 20 } = {}) {
42
+ async search(query, options = {}) {
43
+ requireUnscopedPaidService();
44
+ const { category, limit = 20 } = options;
39
45
  const params = new URLSearchParams({ q: query, limit: String(limit) });
40
46
  if (category) params.set("category", category);
41
47
 
@@ -47,6 +53,7 @@ export class EvoMapClient {
47
53
  * Get gene details by ID.
48
54
  */
49
55
  async getGene(geneId) {
56
+ requireUnscopedPaidService();
50
57
  return this._request(`/genes/${encodeURIComponent(geneId)}`);
51
58
  }
52
59
 
@@ -55,6 +62,7 @@ export class EvoMapClient {
55
62
  * @returns {{ gene: object, content: string }}
56
63
  */
57
64
  async download(geneId) {
65
+ requireUnscopedPaidService();
58
66
  const data = await this._request(
59
67
  `/genes/${encodeURIComponent(geneId)}/download`,
60
68
  );
@@ -66,6 +74,7 @@ export class EvoMapClient {
66
74
  * @param {object} gene - Gene metadata + content
67
75
  */
68
76
  async publish(gene) {
77
+ requireUnscopedPaidService();
69
78
  if (!this.apiKey) throw new Error("API key required for publishing");
70
79
  return this._request("/genes", {
71
80
  method: "POST",
@@ -77,6 +86,7 @@ export class EvoMapClient {
77
86
  * List hub information.
78
87
  */
79
88
  async getHubInfo() {
89
+ requireUnscopedPaidService();
80
90
  return this._request("/info");
81
91
  }
82
92
 
@@ -84,6 +94,7 @@ export class EvoMapClient {
84
94
  * List available hubs (returns current hub info).
85
95
  */
86
96
  async listHubs() {
97
+ requireUnscopedPaidService();
87
98
  try {
88
99
  const info = await this.getHubInfo();
89
100
  return [{ url: this.hubUrl, ...info }];
@@ -95,6 +106,7 @@ export class EvoMapClient {
95
106
  // ─── Internal ───
96
107
 
97
108
  async _request(path, options = {}) {
109
+ requireUnscopedPaidService();
98
110
  const url = `${this.hubUrl}${path}`;
99
111
  const headers = {
100
112
  "Content-Type": "application/json",
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { createRequire } from "node:module";
4
+ import { FormalBudgetLineageRegistry } from "./formal-budget-lineage-registry.js";
4
5
  import {
5
6
  budgetError,
6
7
  requireBudget,
@@ -50,11 +51,29 @@ function checkFile(filename) {
50
51
  );
51
52
  }
52
53
 
54
+ function stateDigest(db) {
55
+ return evidenceDigest({
56
+ schema: db
57
+ .prepare(
58
+ "SELECT type,name,sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%' ORDER BY type,name",
59
+ )
60
+ .all(),
61
+ authority: db.prepare("SELECT * FROM authority ORDER BY id").all(),
62
+ tasks: db.prepare("SELECT * FROM task ORDER BY id").all(),
63
+ runs: db.prepare("SELECT * FROM run ORDER BY id").all(),
64
+ calls: db.prepare("SELECT * FROM call ORDER BY id").all(),
65
+ events: db.prepare("SELECT * FROM event ORDER BY sequence").all(),
66
+ guard: db.prepare("SELECT * FROM lineage_guard ORDER BY id").all(),
67
+ });
68
+ }
69
+
53
70
  /** Trusted-host service. Task processes must never receive this object or DB access. */
54
71
  export class FormalBudgetAuthority {
55
72
  #db;
56
73
  #config;
57
74
  #now;
75
+ #registry;
76
+ #binding;
58
77
  constructor({
59
78
  filename,
60
79
  lineageId,
@@ -62,6 +81,10 @@ export class FormalBudgetAuthority {
62
81
  activationDigest,
63
82
  verifyEvidence,
64
83
  now = Date.now,
84
+ lineageRegistry,
85
+ lineageRegistryId,
86
+ lineageRegistryFilename,
87
+ lineageRegistryFileIdentity,
65
88
  }) {
66
89
  checkFile(filename);
67
90
  this.#db = database(filename);
@@ -89,90 +112,190 @@ export class FormalBudgetAuthority {
89
112
  this.#db.pragma("quick_check", { simple: true }) === "ok",
90
113
  "Corrupt budget database",
91
114
  );
115
+ const hasGuard = this.#db
116
+ .prepare(
117
+ "SELECT 1 FROM sqlite_master WHERE type='table' AND name='lineage_guard'",
118
+ )
119
+ .get();
120
+ const guard = hasGuard
121
+ ? this.#db.prepare("SELECT * FROM lineage_guard WHERE id=1").get()
122
+ : null;
123
+ requireBudget(
124
+ (!lineageRegistryId || guard?.registry_id === lineageRegistryId) &&
125
+ (!lineageRegistryFilename ||
126
+ guard?.registry_filename === lineageRegistryFilename) &&
127
+ (!lineageRegistryFileIdentity ||
128
+ guard?.registry_file_identity === lineageRegistryFileIdentity),
129
+ "Pinned lineage guard is missing or changed",
130
+ "CC_BUDGET_LINEAGE_IDENTITY",
131
+ );
132
+ if (hasGuard || lineageRegistry) {
133
+ requireBudget(
134
+ guard && lineageRegistry instanceof FormalBudgetLineageRegistry,
135
+ "Guarded authority requires its independent host-owned registry",
136
+ "CC_BUDGET_LINEAGE_REQUIRED",
137
+ );
138
+ requireBudget(
139
+ guard.registry_id === lineageRegistry.registryId &&
140
+ guard.registry_filename ===
141
+ lineageRegistry.bindingIdentity.filename &&
142
+ guard.registry_file_identity ===
143
+ lineageRegistry.bindingIdentity.fileIdentity &&
144
+ (guard.checkpoint_host_id ?? null) ===
145
+ lineageRegistry.checkpointHostId,
146
+ "Independent registry physical identity differs from the authority binding; no automatic migration",
147
+ "CC_BUDGET_LINEAGE_IDENTITY",
148
+ );
149
+ this.#registry = lineageRegistry;
150
+ this.#binding = {
151
+ filename,
152
+ lineageId,
153
+ planDigest,
154
+ activationDigest,
155
+ bindingId: guard.binding_id,
156
+ };
157
+ this.#transaction(() => {});
158
+ }
92
159
  } catch (error) {
93
160
  this.#db.close();
94
161
  throw error;
95
162
  }
96
163
  }
97
164
 
98
- static initialize({ filename, config, verifyEvidence, now = Date.now }) {
165
+ static initialize({
166
+ filename,
167
+ config,
168
+ verifyEvidence,
169
+ now = Date.now,
170
+ lineageRegistry,
171
+ }) {
99
172
  const checked = validateActivation(config, verifyEvidence, now());
100
173
  requireBudget(
101
174
  path.isAbsolute(filename),
102
175
  "Authority database path must be absolute",
103
176
  );
104
- // Explicit creation only. Opening a missing database never starts a fresh lineage.
105
- const fd = fs.openSync(filename, "wx", 0o600);
106
- fs.closeSync(fd);
107
- const db = database(filename);
108
- try {
109
- db.exec(`BEGIN IMMEDIATE;
177
+ requireBudget(
178
+ !lineageRegistry ||
179
+ lineageRegistry instanceof FormalBudgetLineageRegistry,
180
+ "Trusted lineage registry required",
181
+ "CC_BUDGET_LINEAGE_REQUIRED",
182
+ );
183
+ const initialize = (guard) => {
184
+ // Explicit creation only. Opening a missing database never starts a fresh lineage.
185
+ const fd = fs.openSync(filename, "wx", 0o600);
186
+ fs.closeSync(fd);
187
+ const db = database(filename);
188
+ try {
189
+ db.exec(`BEGIN IMMEDIATE;
110
190
  CREATE TABLE authority(id INTEGER PRIMARY KEY CHECK(id=1),config TEXT NOT NULL,digest TEXT NOT NULL,halted TEXT);
111
191
  CREATE TABLE task(id TEXT PRIMARY KEY,cap INTEGER NOT NULL,historical_spent INTEGER NOT NULL,historical_reserved INTEGER NOT NULL,slots INTEGER NOT NULL);
112
192
  CREATE TABLE run(id TEXT PRIMARY KEY,task TEXT NOT NULL REFERENCES task(id),phase TEXT NOT NULL,status TEXT NOT NULL);
113
193
  CREATE TABLE call(id TEXT PRIMARY KEY,run TEXT NOT NULL REFERENCES run(id),contract TEXT NOT NULL,request_digest TEXT NOT NULL,state TEXT NOT NULL,reserved_usd INTEGER NOT NULL,reserved_native INTEGER NOT NULL,currency TEXT NOT NULL,cost_usd INTEGER,cost_native INTEGER,receipt_digest TEXT,receipt TEXT);
114
194
  CREATE TABLE event(sequence INTEGER PRIMARY KEY,kind TEXT NOT NULL,body TEXT NOT NULL);`);
115
- const halted = checked.history.tasks.some((t) => t.unknown)
116
- ? "unreconciled historical liability"
117
- : null;
118
- db.prepare("INSERT INTO authority VALUES (1,?,?,?)").run(
119
- canonical(checked),
120
- evidenceDigest(checked),
121
- halted,
122
- );
123
- for (const task of checked.plan.tasks) {
124
- const history = checked.history.tasks.find((t) => t.id === task.id);
125
- db.prepare("INSERT INTO task VALUES (?,?,?,?,?)").run(
126
- task.id,
127
- task.capUsdMicros,
128
- history.spentUsdMicros,
129
- history.reservedUsdMicros,
130
- history.runsUsed,
195
+ if (guard) {
196
+ db.exec(
197
+ "CREATE TABLE lineage_guard(id INTEGER PRIMARY KEY CHECK(id=1),registry_id TEXT NOT NULL,binding_id TEXT NOT NULL,registry_filename TEXT NOT NULL,registry_file_identity TEXT NOT NULL,checkpoint_host_id TEXT)",
198
+ );
199
+ db.prepare("INSERT INTO lineage_guard VALUES (1,?,?,?,?,?)").run(
200
+ guard.registryId,
201
+ guard.bindingId,
202
+ guard.registryFilename,
203
+ guard.registryFileIdentity,
204
+ guard.checkpointHostId,
205
+ );
206
+ }
207
+ const halted = checked.history.tasks.some((t) => t.unknown)
208
+ ? "unreconciled historical liability"
209
+ : null;
210
+ db.prepare("INSERT INTO authority VALUES (1,?,?,?)").run(
211
+ canonical(checked),
212
+ evidenceDigest(checked),
213
+ halted,
214
+ );
215
+ for (const task of checked.plan.tasks) {
216
+ const history = checked.history.tasks.find((t) => t.id === task.id);
217
+ db.prepare("INSERT INTO task VALUES (?,?,?,?,?)").run(
218
+ task.id,
219
+ task.capUsdMicros,
220
+ history.spentUsdMicros,
221
+ history.reservedUsdMicros,
222
+ history.runsUsed,
223
+ );
224
+ }
225
+ db.prepare("INSERT INTO event(kind,body) VALUES (?,?)").run(
226
+ "initialized",
227
+ canonical({ activationDigest: evidenceDigest(checked), at: now() }),
131
228
  );
229
+ db.exec("COMMIT");
230
+ return guard ? stateDigest(db) : null;
231
+ } catch (error) {
232
+ try {
233
+ db.exec("ROLLBACK");
234
+ } catch {
235
+ /* retain incomplete DB; never silently reset */
236
+ }
237
+ throw error;
238
+ } finally {
239
+ db.close();
132
240
  }
133
- db.prepare("INSERT INTO event(kind,body) VALUES (?,?)").run(
134
- "initialized",
135
- canonical({ activationDigest: evidenceDigest(checked), at: now() }),
241
+ };
242
+ if (lineageRegistry) {
243
+ lineageRegistry.register(
244
+ {
245
+ filename,
246
+ lineageId: checked.plan.lineageId,
247
+ planDigest: checked.plan.digest,
248
+ activationDigest: evidenceDigest(checked),
249
+ },
250
+ initialize,
136
251
  );
137
- db.exec("COMMIT");
138
- } catch (error) {
139
- try {
140
- db.exec("ROLLBACK");
141
- } catch {
142
- /* retain incomplete DB; never silently reset */
143
- }
144
- throw error;
145
- } finally {
146
- db.close();
147
- }
252
+ } else initialize(null);
148
253
  return {
149
254
  filename,
150
255
  lineageId: checked.plan.lineageId,
151
256
  planDigest: checked.plan.digest,
152
257
  activationDigest: evidenceDigest(checked),
258
+ ...(lineageRegistry
259
+ ? {
260
+ lineageRegistryId: lineageRegistry.registryId,
261
+ lineageRegistryFilename: lineageRegistry.bindingIdentity.filename,
262
+ lineageRegistryFileIdentity:
263
+ lineageRegistry.bindingIdentity.fileIdentity,
264
+ }
265
+ : {}),
153
266
  };
154
267
  }
155
268
 
156
269
  #transaction(action) {
157
- this.#db.exec("BEGIN IMMEDIATE");
158
- try {
159
- const result = action();
160
- this.#db.exec("COMMIT");
161
- return result;
162
- } catch (error) {
270
+ const transact = (lease) => {
271
+ this.#db.exec("BEGIN IMMEDIATE");
163
272
  try {
164
- this.#db.exec("ROLLBACK");
165
- } catch {
166
- /* original error */
273
+ lease?.assertState(stateDigest(this.#db));
274
+ const result = action();
275
+ lease?.advance(stateDigest(this.#db));
276
+ this.#db.exec("COMMIT");
277
+ return result;
278
+ } catch (error) {
279
+ try {
280
+ this.#db.exec("ROLLBACK");
281
+ } catch {
282
+ /* original error */
283
+ }
284
+ throw error;
167
285
  }
168
- throw error;
169
- }
286
+ };
287
+ return this.#registry
288
+ ? this.#registry.coordinate(this.#binding, transact)
289
+ : transact(null);
170
290
  }
171
291
  #event(kind, body) {
172
292
  this.#db
173
293
  .prepare("INSERT INTO event(kind,body) VALUES (?,?)")
174
294
  .run(kind, canonical({ ...body, at: this.#now() }));
175
295
  }
296
+ #read(action) {
297
+ return this.#registry ? this.#transaction(action) : action();
298
+ }
176
299
  #admissible() {
177
300
  const { halted } = this.#db
178
301
  .prepare("SELECT halted FROM authority WHERE id=1")
@@ -286,7 +409,7 @@ export class FormalBudgetAuthority {
286
409
  this.#event("run-close", { runId });
287
410
  });
288
411
  }
289
- reserve({ runId, callId, body }) {
412
+ reserve({ runId, callId, body, endpoint }) {
290
413
  label(runId, "run ID");
291
414
  label(callId, "physical call ID");
292
415
  const request = JSON.parse(canonical(body));
@@ -303,6 +426,11 @@ export class FormalBudgetAuthority {
303
426
  requireBudget(run, "Active run required");
304
427
  const task = this.#config.plan.tasks.find((t) => t.id === run.task);
305
428
  const { contract, fx } = this.#contract(task.contractId);
429
+ requireBudget(
430
+ endpoint === undefined || endpoint === contract.endpoint,
431
+ "Requested endpoint differs from the reserved account contract",
432
+ "CC_BUDGET_ENDPOINT_MISMATCH",
433
+ );
306
434
  const requestDigest = validateRequest(contract, request);
307
435
  const nativeMicros = quoteNative(contract),
308
436
  usdMicros = convertToUsd(nativeMicros, fx);
@@ -347,14 +475,18 @@ export class FormalBudgetAuthority {
347
475
  });
348
476
  }
349
477
  reservedContract(callId) {
350
- const call = this.#db.prepare("SELECT * FROM call WHERE id=?").get(callId);
351
- requireBudget(
352
- call?.state === "held",
353
- "Physical call is not reserved",
354
- "CC_BUDGET_CALL_REPLAY",
355
- );
356
- const { contract } = this.#contract(call.contract);
357
- return JSON.parse(canonical(contract));
478
+ return this.#read(() => {
479
+ const call = this.#db
480
+ .prepare("SELECT * FROM call WHERE id=?")
481
+ .get(callId);
482
+ requireBudget(
483
+ call?.state === "held",
484
+ "Physical call is not reserved",
485
+ "CC_BUDGET_CALL_REPLAY",
486
+ );
487
+ const { contract } = this.#contract(call.contract);
488
+ return JSON.parse(canonical(contract));
489
+ });
358
490
  }
359
491
  markDispatched(callId, body) {
360
492
  return this.#transaction(() => {
@@ -513,7 +645,7 @@ export class FormalBudgetAuthority {
513
645
  return result;
514
646
  }
515
647
  status() {
516
- return {
648
+ return this.#read(() => ({
517
649
  lineageId: this.#config.plan.lineageId,
518
650
  planDigest: this.#config.plan.digest,
519
651
  capUsdMicros: this.#config.plan.limitUsdMicros,
@@ -525,7 +657,7 @@ export class FormalBudgetAuthority {
525
657
  "SELECT id,state,reserved_usd,reserved_native,currency FROM call WHERE state!='settled'",
526
658
  )
527
659
  .all(),
528
- };
660
+ }));
529
661
  }
530
662
  close() {
531
663
  this.#db.close();
@@ -1,15 +1,16 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { validateVerify01Bundle } from "./eval/verify01-contracts.js";
3
+ import { requireBudget, label } from "./formal-budget-errors.js";
4
+ export {
5
+ budgetError,
6
+ isFormalBudgetError,
7
+ requireBudget,
8
+ label,
9
+ } from "./formal-budget-errors.js";
3
10
 
4
11
  const VOLCENGINE_V3_PLAN_DIGEST =
5
12
  "sha256:04b90d1a93cfd6556f91688a39508c69e4423671a7b6bcb85fac4dc7e82c0e13";
6
13
 
7
- export function budgetError(code, message) {
8
- return Object.assign(new Error(message), { code });
9
- }
10
- export function requireBudget(condition, message, code = "CC_BUDGET_INVALID") {
11
- if (!condition) throw budgetError(code, message);
12
- }
13
14
  export function integer(value, name, minimum = 0) {
14
15
  requireBudget(
15
16
  Number.isSafeInteger(value) && value >= minimum,
@@ -33,13 +34,6 @@ export function canonical(value) {
33
34
  }
34
35
  export const evidenceDigest = (value) =>
35
36
  createHash("sha256").update(canonical(value)).digest("hex");
36
- export function label(value, name) {
37
- requireBudget(
38
- typeof value === "string" && /^[A-Za-z0-9._:-]{1,160}$/u.test(value),
39
- `Invalid ${name}`,
40
- );
41
- return value;
42
- }
43
37
  function digest(value, name) {
44
38
  requireBudget(
45
39
  typeof value === "string" && /^[a-f0-9]{64}$/u.test(value),
@@ -0,0 +1,31 @@
1
+ // Dependency-free so ordinary model transports do not load the formal eval
2
+ // specification merely to recognize an authoritative budget failure.
3
+ export function budgetError(code, message) {
4
+ return Object.assign(new Error(message), { code, noReplay: true });
5
+ }
6
+
7
+ export function isFormalBudgetError(error) {
8
+ const visited = new Set();
9
+ for (let current = error; current; current = current.cause) {
10
+ if (visited.has(current) || visited.size >= 32) break;
11
+ visited.add(current);
12
+ if (
13
+ typeof current.code === "string" &&
14
+ current.code.startsWith("CC_BUDGET_")
15
+ )
16
+ return true;
17
+ }
18
+ return false;
19
+ }
20
+
21
+ export function requireBudget(condition, message, code = "CC_BUDGET_INVALID") {
22
+ if (!condition) throw budgetError(code, message);
23
+ }
24
+
25
+ export function label(value, name) {
26
+ requireBudget(
27
+ typeof value === "string" && /^[A-Za-z0-9._:-]{1,160}$/u.test(value),
28
+ `Invalid ${name}`,
29
+ );
30
+ return value;
31
+ }