chainlesschain 0.166.100 → 0.166.101

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 (166) hide show
  1. package/package.json +2 -2
  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-Cd4iUOPt.js → AIOps-BjBS_29I.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton--ucr-zko.js → ActionButton-CUnnQUaj.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-DbejYMWk.js → Analytics-BqYZxgnY.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-CLgKxeGw.js → AppLayout-m8B886ka.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-CTT5BIL5.js → Artifacts-JEOxU3Ug.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-DP-WBWe9.js → Audit-DAXS5c9J.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-B6VqheJk.js → BackgroundAgents-e3a9XHw3.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-VWJK5zim.js → Backup-D3Qmp68h.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-YGFO9RHd.js → BaseInput-C7CXyiUl.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-CVfydnCd.js → Chat-2AHlAGi8.js} +6 -6
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-BICpB-qU.js → ChatBubbleRenderer-D3KsyCUV.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-Bd5vKRMk.js → Checkbox-YfBuQlBH.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-DHNgPHvg.js → Codegen-DCCQDfTL.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-CA2BYQ8T.js → Col-03i2WfrV.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-DnKJ-qpI.js → Community-CJQIpng6.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-C9BZ8t4r.js → Compact-CCtcQ2pq.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-ByyQ2FOl.js → Compliance-Vxl7ZszJ.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-rXTwXE_c.js → Cowork-DN-BwA8I.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-BuW-HODy.js → Cron-Dc2Q46X7.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-OudNtbYW.js → Crosschain-CQCblsl-.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-BQ6BxYNN.js → DID-YYvqUR8C.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-Cz5HG8tz.js → Dashboard-Cafy3DZT.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-BzclHOVv.js → Dropdown-BOyYpIpv.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-CbJETFdy.js → EmailListRenderer-B7NYjc1j.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-Dx_pJG3d.js → EvolutionSettings-C5wfxztf.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-6JCS1MNg.js → FamilyGuardDashboard-aA7KnDGK.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-BrPkMYaf.js → Federation-DlgXUu1L.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-Bhc9pobs.js → FormItemContext-B5YsrLDg.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-BxOh07uQ.js → GenericCardRenderer-DaWojPFw.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-D_idoujr.js → Git-dkhh6Fx2.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-ZGfIRE-x.js → Governance-Cz6vmkjc.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-DpAmcwbw.js → Inference-DWt0hbh8.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-D1S1UTgP.js → KnowledgeGraph-BZJ0Z-nL.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-2sc8V5XV.js → Logs-BaBBmL1A.js} +2 -2
  38. package/src/assets/web-panel/assets/MarkdownRenderer-C1yByobo.js +1 -0
  39. package/src/assets/web-panel/assets/{Marketplace-0xlFUKbe.js → Marketplace-ct8sgQ0s.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-D25eJLGm.js → McpTools-CXKCRGYQ.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-BLRGd9hM.js → Memory-O7ZwlS6a.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-zpFINGzn.js → MobileBridge-By12C-eC.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-Cbyd-8kx.js → MobileProjects-Ba-EVdex.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-DgXgUlHc.js → Mtc-g-932zV2.js} +2 -2
  45. package/src/assets/web-panel/assets/{MtcAudit-DzcL-dKH.js → MtcAudit-BW8hB0ly.js} +4 -4
  46. package/src/assets/web-panel/assets/{Multisig-C3OrZ6VN.js → Multisig-zspLaMbT.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-Bqp_vWA7.js → NLProgramming-dJeUPDoq.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-Dyn45-Ht.js → Notes-C4msiRQL.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-CLjafGZr.js → NotificationSettings-MOCHM-qg.js} +1 -1
  50. package/src/assets/web-panel/assets/{OrderTableRenderer-Bx8wMauC.js → OrderTableRenderer-CX0T66NM.js} +1 -1
  51. package/src/assets/web-panel/assets/{Organization-5gr9hyLm.js → Organization-DOZurBfk.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-BRdU02hT.js → Overflow-qOT9BhUp.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-DIi7fzh6.js → P2P-BMoy7Eo4.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-BCbS1KpA.js → PdhVaultBrowser-ByyV1q-D.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-BjeP9VtA.js → Permissions-6Qyro4ye.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-y8PXOQUc.js → PersonalDataHub-DR3DRNSX.js} +4 -4
  57. package/src/assets/web-panel/assets/{Pipeline-B0fL5uxY.js → Pipeline-Cr6TTdud.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-C8jCDn8Z.js → Privacy-B70otG0l.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-B_L6Dc6V.js → ProjectInit-BHCqxoSk.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-Bb1CYbZh.js → ProjectSettings-B80GZpZk.js} +2 -2
  61. package/src/assets/web-panel/assets/Projects-cq-b9-fQ.js +1 -0
  62. package/src/assets/web-panel/assets/{Providers-mBSTDJ0E.js → Providers-dsVTimHa.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-CHxgalvt.js → QrScannerModal-DRJ8YepZ.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-DI9KIMEV.js → QuickAsk-BSXdEjIB.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-B5_zW1JH.js → Recommend-CQLJGyKC.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-BkH4bmM5.js → RemoteSession-BF9WUFVZ.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-DJrAqwAq.js → Reputation-Cy9o5tvW.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-xZ3MAM34.js → Row-BP346_3b.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-CCsrLLiu.js → RssFeed-BKulxXf3.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-CTCRKvaP.js → Search-EemQj2Dv.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-D7joyfp2.js → Security-DcWPAwwk.js} +4 -4
  72. package/src/assets/web-panel/assets/{Services-oqHPmTG4.js → Services-Bltqciay.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-BR_32bTG.js → Skeleton-BwRyOGY8.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-BoRz9mln.js → Skills-D98qlvpJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-UAGUHZ9b.js → Sla-BUTtBMY0.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-DeP_rMgv.js → SpeechSettings-C7kcY_98.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-CSzzMmeA.js → SyncSettings-Bsk6lKvT.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-CcqOLsLB.js → Tasks-DvSrtz0P.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-cDbkGSDG.js → Templates-BUM6LwPs.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-DmOy58cq.js → Tenant-D9TkOm7z.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-CsRZH5vr.js → Terminal-CP8ZVErN.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-BgJrk6HG.js → TimelineRenderer-V3SoKZ1T.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-CCQglKDE.js → Tokens-CCRlUTOA.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-t-Gt3oBY.js → Trigger-CznUcPme.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-DQgu2kI0.js → Trust-D1GIk_NF.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-Cod2WUGj.js → UkeySign-DHtvtyC-.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-SGN5zaVK.js → VideoEditing-CVxdaJIq.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-CnLEL-LD.js → Wallet-D221OjyE.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-C2keUpD6.js → WebAuthn-Cw0-ESsq.js} +2 -2
  90. package/src/assets/web-panel/assets/{WorkflowEditor-B1GvrwWJ.js → WorkflowEditor-ZYScrBx3.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-1E9_P_qY.js → chat-BU0e1obR.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-DuU6Os4q.js → colors-gzYweuha.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-C5NfOAcM.js → compact-item-ChAXal_k.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-D4Fxz9qQ.js → createContext-of3FolD7.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-Pa13TVrO.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-C6C49iFk.js → hasIn-4PsK_Kx8.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DP2DCKD-.js → index-1dzYRBbg.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-DPzunJER.js → index-B5L7zddz.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BBVqlelF.js → index-BOeX7BzS.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-Bk-paNL3.js → index-BdxRVNPY.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CJS6GTpv.js → index-BfI4dXbi.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-BlHkc48f.js → index-Bftq5rJR.js} +1 -1
  103. package/src/assets/web-panel/assets/index-BhQg-v6V.js +1 -0
  104. package/src/assets/web-panel/assets/{index-HQXFl8fh.js → index-By-pper5.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-cnDfwWU5.js → index-CCLsbul3.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DSypQU1h.js → index-CGFL59q4.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-B-bb-R99.js → index-CHv_63Cp.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-C7mh6xlu.js → index-CO2owKe0.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-gh11zJ9h.js → index-CeEE_SGZ.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BsH8mFp4.js → index-Cn1clrxx.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-C2nO02uW.js → index-Cx4Z6nUl.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BYg1dtne.js → index-CxzBcXOa.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-AO6iDCSL.js → index-CyDQNprx.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Dh-vezHe.js → index-D-Zss5KL.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-BULggEX6.js → index-D1PGrfHE.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-bW6vfpLH.js → index-DDYj14Q4.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-B5lzRoHp.js → index-DEB5fQqG.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-CXb8gEWh.js → index-DEXBckNR.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-BZKRZYTX.js → index-DEzjUgkl.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CpiOzt7U.js → index-DJVrzXtk.js} +1 -1
  121. package/src/assets/web-panel/assets/index-DUD5o-vW.js +1 -0
  122. package/src/assets/web-panel/assets/{index-jFg3CPlQ.js → index-DZ0oKtBg.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-DZgT7pH-.js → index-D_5LTPMH.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-CXn-e3ki.js → index-D_9k680X.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DFK6PTGJ.js → index-D_ialOHx.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BmvU4Tp_.js → index-DjRAIRX7.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Bu6qMjf4.js → index-Djfgsjfy.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-CDVwN9Sv.js → index-DsoV9rzn.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DpaGe-dr.js → index-Dy0ojH6G.js} +3 -3
  130. package/src/assets/web-panel/assets/{index-CQJoh5rw.js → index-E8oDMSAo.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-BU5mPkNX.js → index-Ef5YkVAn.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-D1TXgNPA.js → index-Wr91cnWr.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BVE2wCeb.js → index-cFkMIx1x.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-B_ON9La1.js → index-wo0De0iG.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-lNmDaf3J.js → index-yMf7zmWv.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-3DSfnIpD.js → initDefaultProps-D0Bx6pgr.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-DxGLmgA0.js → motion-BnLuJqJ5.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-DrlLG6m5.js → move-Bxpq9xgR.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-BITbrJSb.js → mtc-parser-BdmrNhOs.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-D7k5vIbk.js → omit-tjJD34BZ.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-BJSvYFWo.js → pickAttrs-CMFzLt7b.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-Bf4to1jA.js → placementArrow-BZf6O3cd.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-BXzeyzTa.js → responsiveObserve-DFDLazsV.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-DLzNUNdj.js → slide-CMbTvp4Y.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-wBBnrRm_.js → statusUtils-FOan8MI7.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-BnmJzXNr.js → styleChecker-DTABspd4.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-DrN8MrJb.js → useFlexGapSupport-CNHXWBpY.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-dnkYGkjY.js → useFs-5K-c_RoL.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-k_xkv7-k.js → usePersonalDataHub-Di0hL4G-.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-B-v8PXpK.js → vnode-DTyDv4ja.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-Coue8wAK.js → zoom-ontRt8ft.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/commands/eval.js +11 -8
  154. package/src/data/changelog.json +13 -0
  155. package/src/harness/provider-backed-compaction.js +13 -5
  156. package/src/lib/context-memory-kernel/live-compaction.js +142 -61
  157. package/src/lib/formal-budget-authority.js +533 -0
  158. package/src/lib/formal-budget-contract.js +609 -0
  159. package/src/lib/formal-budget-transport.js +345 -0
  160. package/src/runtime/agent-core.js +175 -12
  161. package/src/runtime/headless-stream.js +136 -4
  162. package/src/assets/web-panel/assets/MarkdownRenderer-575jjYE6.js +0 -1
  163. package/src/assets/web-panel/assets/Projects-CUSV10Cn.js +0 -1
  164. package/src/assets/web-panel/assets/devWarning-zDWbYMr7.js +0 -1
  165. package/src/assets/web-panel/assets/index-BPBsZZnT.js +0 -1
  166. package/src/assets/web-panel/assets/index-CtGQDg7m.js +0 -1
@@ -0,0 +1,345 @@
1
+ import {
2
+ budgetError,
3
+ canonical,
4
+ requireBudget,
5
+ } from "./formal-budget-contract.js";
6
+
7
+ export const FORMAL_BUDGET_RUNTIME_READINESS = Object.freeze({
8
+ paidReady: false,
9
+ reason:
10
+ "Agent, Chat, compaction, advisor, probes, retries and child-process egress are not yet all routed through this authority",
11
+ });
12
+ export function requireFormalBudgetRuntime() {
13
+ throw budgetError(
14
+ "CC_BUDGET_RUNTIME_NOT_COVERED",
15
+ FORMAL_BUDGET_RUNTIME_READINESS.reason,
16
+ );
17
+ }
18
+
19
+ // JSON.parse alone accepts duplicate keys (including escaped aliases) and
20
+ // overflows numeric literals to Infinity. Neither is safe accounting evidence.
21
+ export function parseBudgetJson(text) {
22
+ requireBudget(typeof text === "string", "JSON text required");
23
+ let at = 0;
24
+ const whitespace = () => {
25
+ while (at < text.length && /[\x20\t\r\n]/u.test(text[at])) at++;
26
+ };
27
+ function string() {
28
+ requireBudget(text[at] === '"', "JSON string expected");
29
+ const start = at++;
30
+ while (at < text.length) {
31
+ const char = text[at++];
32
+ if (char === '"') return JSON.parse(text.slice(start, at));
33
+ if (char === "\\") at++;
34
+ }
35
+ requireBudget(false, "Unterminated JSON string");
36
+ }
37
+ function value(depth) {
38
+ requireBudget(depth <= 64, "JSON nesting exceeds accounting parser bound");
39
+ whitespace();
40
+ if (text[at] === '"') {
41
+ string();
42
+ return;
43
+ }
44
+ if (text[at] === "{") {
45
+ at++;
46
+ whitespace();
47
+ const keys = new Set();
48
+ if (text[at] === "}") {
49
+ at++;
50
+ return;
51
+ }
52
+ for (;;) {
53
+ whitespace();
54
+ const key = string();
55
+ requireBudget(
56
+ !keys.has(key),
57
+ "Duplicate JSON member in provider evidence",
58
+ );
59
+ keys.add(key);
60
+ whitespace();
61
+ requireBudget(text[at++] === ":", "JSON member separator expected");
62
+ value(depth + 1);
63
+ whitespace();
64
+ const separator = text[at++];
65
+ if (separator === "}") return;
66
+ requireBudget(separator === ",", "JSON object separator expected");
67
+ }
68
+ }
69
+ if (text[at] === "[") {
70
+ at++;
71
+ whitespace();
72
+ if (text[at] === "]") {
73
+ at++;
74
+ return;
75
+ }
76
+ for (;;) {
77
+ value(depth + 1);
78
+ whitespace();
79
+ const separator = text[at++];
80
+ if (separator === "]") return;
81
+ requireBudget(separator === ",", "JSON array separator expected");
82
+ }
83
+ }
84
+ for (const literal of ["true", "false", "null"])
85
+ if (text.startsWith(literal, at)) {
86
+ at += literal.length;
87
+ return;
88
+ }
89
+ const number = text
90
+ .slice(at)
91
+ .match(/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/u)?.[0];
92
+ requireBudget(
93
+ number && Number.isFinite(Number(number)),
94
+ "Invalid or non-finite JSON number",
95
+ );
96
+ at += number.length;
97
+ }
98
+ value(0);
99
+ whitespace();
100
+ requireBudget(at === text.length, "Trailing JSON input");
101
+ return JSON.parse(text);
102
+ }
103
+
104
+ /** Allowlist only; the caller must still supply the existing OS sandbox. */
105
+ export function formalBudgetTaskEnvironment(environment = process.env) {
106
+ return Object.fromEntries(
107
+ [
108
+ "PATH",
109
+ "Path",
110
+ "SystemRoot",
111
+ "SYSTEMROOT",
112
+ "WINDIR",
113
+ "ComSpec",
114
+ "PATHEXT",
115
+ "TEMP",
116
+ "TMP",
117
+ "TMPDIR",
118
+ "LANG",
119
+ "LC_ALL",
120
+ "LC_CTYPE",
121
+ ]
122
+ .filter((key) => typeof environment[key] === "string")
123
+ .map((key) => [key, environment[key]]),
124
+ );
125
+ }
126
+
127
+ async function boundedText(response, maximumBytes) {
128
+ requireBudget(response.body?.getReader, "Response body unavailable");
129
+ const reader = response.body.getReader(),
130
+ chunks = [];
131
+ let size = 0;
132
+ try {
133
+ for (;;) {
134
+ const { done, value } = await reader.read();
135
+ if (done) break;
136
+ size += value.byteLength;
137
+ requireBudget(
138
+ size <= maximumBytes,
139
+ "Provider response exceeded bounded parser",
140
+ );
141
+ chunks.push(Buffer.from(value));
142
+ }
143
+ } catch (error) {
144
+ try {
145
+ await reader.cancel();
146
+ } catch {
147
+ /* keep original unknown outcome */
148
+ }
149
+ throw error;
150
+ } finally {
151
+ reader.releaseLock();
152
+ }
153
+ return new TextDecoder("utf-8", { fatal: true }).decode(
154
+ Buffer.concat(chunks),
155
+ );
156
+ }
157
+ function streamReceipt(text) {
158
+ let terminal = false,
159
+ receipt = null,
160
+ usage = null,
161
+ finishReason = null;
162
+ for (const frame of text.replaceAll("\r\n", "\n").split("\n\n")) {
163
+ if (!frame.trim()) continue;
164
+ const data = frame
165
+ .split("\n")
166
+ .filter((line) => line.startsWith("data:"))
167
+ .map((line) => line.slice(5).trimStart())
168
+ .join("\n");
169
+ if (!data) continue;
170
+ requireBudget(!terminal, "Unexpected stream data after terminal marker");
171
+ if (data === "[DONE]") {
172
+ requireBudget(
173
+ finishReason !== null,
174
+ "Stream ended without a completed choice",
175
+ );
176
+ terminal = true;
177
+ continue;
178
+ }
179
+ const row = parseBudgetJson(data);
180
+ requireBudget(row && !Object.hasOwn(row, "error"), "Provider stream error");
181
+ const identity = {
182
+ id: row.id,
183
+ model: row.model,
184
+ service_tier: row.service_tier,
185
+ };
186
+ if (!receipt) receipt = identity;
187
+ else {
188
+ // Some providers only send service_tier on the final usage frame.
189
+ requireBudget(
190
+ row.id === receipt.id && row.model === receipt.model,
191
+ "Stream identity changed",
192
+ );
193
+ if (row.service_tier !== undefined) {
194
+ requireBudget(
195
+ receipt.service_tier === undefined ||
196
+ row.service_tier === receipt.service_tier,
197
+ "Stream tier changed",
198
+ );
199
+ receipt.service_tier = row.service_tier;
200
+ }
201
+ }
202
+ requireBudget(
203
+ Array.isArray(row.choices) &&
204
+ row.choices.length <= 1 &&
205
+ row.choices.every((choice) => choice.index === 0),
206
+ "Multiple/unknown streamed completions",
207
+ );
208
+ for (const choice of row.choices) {
209
+ requireBudget(
210
+ finishReason === null,
211
+ "Choice data received after completed stream choice",
212
+ );
213
+ if (choice.finish_reason != null) {
214
+ requireBudget(
215
+ ["stop", "length", "tool_calls"].includes(choice.finish_reason),
216
+ "Unsupported stream finish reason",
217
+ );
218
+ finishReason = choice.finish_reason;
219
+ }
220
+ }
221
+ if (row.usage != null) {
222
+ requireBudget(
223
+ finishReason !== null,
224
+ "Usage received before complete stream choice",
225
+ );
226
+ requireBudget(
227
+ usage === null || canonical(usage) === canonical(row.usage),
228
+ "Conflicting streamed usage",
229
+ );
230
+ usage = row.usage;
231
+ }
232
+ }
233
+ requireBudget(
234
+ terminal && finishReason !== null && receipt && usage,
235
+ "Incomplete stream or missing usage",
236
+ );
237
+ return { ...receipt, usage };
238
+ }
239
+
240
+ /**
241
+ * Trusted-host JSON/SSE transport: credential stays in this closure, and every
242
+ * physical request consumes a durable dispatch exactly once. No auto retries.
243
+ * This is not the unrestricted Agent/Chat transport and is not auto-enabled.
244
+ */
245
+ export function createFormalBudgetTransport({
246
+ authority,
247
+ credentialProvider,
248
+ fetchImpl = globalThis.fetch,
249
+ maximumResponseBytes = 16 * 1024 * 1024,
250
+ timeoutMs = 60_000,
251
+ }) {
252
+ requireBudget(
253
+ authority &&
254
+ typeof credentialProvider === "function" &&
255
+ typeof fetchImpl === "function",
256
+ "Authority and trusted credential provider required",
257
+ );
258
+ requireBudget(
259
+ Number.isSafeInteger(maximumResponseBytes) &&
260
+ maximumResponseBytes > 0 &&
261
+ maximumResponseBytes <= 16 * 1024 * 1024,
262
+ "Invalid response byte bound",
263
+ );
264
+ requireBudget(
265
+ Number.isSafeInteger(timeoutMs) && timeoutMs > 0 && timeoutMs <= 300_000,
266
+ "Invalid timeout",
267
+ );
268
+ return Object.freeze({
269
+ async dispatch({ runId, callId, body, signal }) {
270
+ // Snapshot before await so caller mutation cannot alter the reserved body.
271
+ const request = JSON.parse(canonical(body));
272
+ authority.reserve({ runId, callId, body: request });
273
+ let settled = false;
274
+ try {
275
+ const reserved = authority.reservedContract(callId);
276
+ const credential = await credentialProvider({
277
+ contractId: reserved.id,
278
+ provider: reserved.provider,
279
+ endpoint: reserved.endpoint,
280
+ });
281
+ requireBudget(
282
+ typeof credential === "string" &&
283
+ credential.length > 0 &&
284
+ !/[\r\n]/u.test(credential),
285
+ "Credential unavailable",
286
+ );
287
+ const deadline = AbortSignal.timeout(timeoutMs);
288
+ const options = {
289
+ method: "POST",
290
+ redirect: "error",
291
+ headers: {
292
+ "Content-Type": "application/json",
293
+ Authorization: `Bearer ${credential}`,
294
+ },
295
+ body: JSON.stringify(request),
296
+ signal: signal ? AbortSignal.any([signal, deadline]) : deadline,
297
+ };
298
+ // Final expiry/request check is AFTER every awaited preparation. There
299
+ // must be no await between this durable admission and physical fetch.
300
+ const contract = authority.markDispatched(callId, request);
301
+ const response = await fetchImpl(contract.endpoint, options);
302
+ requireBudget(response.ok, "Provider HTTP response not successful");
303
+ const text = await boundedText(response, maximumResponseBytes);
304
+ let receipt;
305
+ if (request.stream === true) {
306
+ requireBudget(
307
+ response.headers.get("content-type")?.includes("text/event-stream"),
308
+ "Unexpected stream content type",
309
+ );
310
+ receipt = streamReceipt(text);
311
+ } else {
312
+ receipt = parseBudgetJson(text);
313
+ requireBudget(
314
+ receipt && !Object.hasOwn(receipt, "error"),
315
+ "Provider error envelope cannot settle",
316
+ );
317
+ requireBudget(
318
+ Array.isArray(receipt.choices) &&
319
+ receipt.choices.length === 1 &&
320
+ receipt.choices[0].index === 0 &&
321
+ ["stop", "length", "tool_calls"].includes(
322
+ receipt.choices[0].finish_reason,
323
+ ),
324
+ "Incomplete or multiple completion response",
325
+ );
326
+ }
327
+ const cost = authority.settle(callId, receipt);
328
+ settled = true;
329
+ return { body: text, streaming: request.stream === true, cost };
330
+ } catch {
331
+ if (!settled) {
332
+ // Do not persist provider errors which may contain credentials/content.
333
+ authority.markUnknown(
334
+ callId,
335
+ "transport or settlement outcome unknown",
336
+ );
337
+ }
338
+ throw budgetError(
339
+ "CC_BUDGET_TRANSPORT_UNKNOWN",
340
+ "Provider outcome unknown; reservation retained and further dispatch blocked",
341
+ );
342
+ }
343
+ },
344
+ });
345
+ }
@@ -198,6 +198,7 @@ import {
198
198
  settleManagedToolCheckpoint,
199
199
  } from "../lib/managed-tool-checkpoint.js";
200
200
  import { sessionBudgetAdmissionError } from "../lib/session-budget-production-root.js";
201
+ import { projectRuntimeTokenUsage } from "../lib/runtime-usage-ledger.js";
201
202
  import {
202
203
  createMcpCallLedger,
203
204
  McpEffect,
@@ -11860,6 +11861,11 @@ export async function chatWithTools(rawMessages, options) {
11860
11861
 
11861
11862
  throwIfAborted(signal);
11862
11863
 
11864
+ // Host accounting starts only after request admission. A rejected model
11865
+ // projection never reaches the provider; failures after this boundary must
11866
+ // still retain conservative usage accounting regardless of error metadata.
11867
+ await options.onProviderCallStart?.();
11868
+
11863
11869
  if (provider === "ollama") {
11864
11870
  const apiUrl = `${baseUrl}/api/chat`;
11865
11871
  // Multimodal (`cc agent --image`): ollama wants `{content, images:[base64]}`
@@ -13471,6 +13477,19 @@ function _workflowNestedToolOutcomeUnknown(binding, toolName, result) {
13471
13477
  return error;
13472
13478
  }
13473
13479
 
13480
+ function _takeCompactionProviderReceipt(call, workflowEffectId) {
13481
+ if (!call?.providerReceipt || call.providerReceiptEmitted) return null;
13482
+ call.providerReceiptEmitted = true;
13483
+ return {
13484
+ type: "provider-request-receipt",
13485
+ callId: call.callId,
13486
+ workflowEffectId,
13487
+ callSequence: call.callSequence,
13488
+ source: "semantic-compaction",
13489
+ ...call.providerReceipt,
13490
+ };
13491
+ }
13492
+
13474
13493
  function _workflowCompactionOutcomeUnknown(
13475
13494
  cause,
13476
13495
  code = "CC_WORKFLOW_COMPACTION_PROVIDER_OUTCOME_UNKNOWN",
@@ -13870,6 +13889,21 @@ function _instrumentAutoCompactorUsage(compactor, options) {
13870
13889
  this,
13871
13890
  requestBinding ? [...args, requestBinding] : args,
13872
13891
  );
13892
+ // Keep validated provider-returned usage private to this actual call.
13893
+ // It is not settled yet: the host consumes token-usage exactly once.
13894
+ try {
13895
+ call.returnedUsage = projectRuntimeTokenUsage({
13896
+ callId: call.callId,
13897
+ provider: result?.provider || call.provider,
13898
+ model: result?.model || call.model,
13899
+ source: call.source,
13900
+ usage: result?.usage,
13901
+ });
13902
+ if (result?.callId && result.callId !== call.callId)
13903
+ call.returnedUsage = null;
13904
+ } catch {
13905
+ call.returnedUsage = null;
13906
+ }
13873
13907
  call.providerReceipt = providerRequestId
13874
13908
  ? _snapshotProviderRequestReceipt(
13875
13909
  result?.providerReceipt,
@@ -13879,6 +13913,7 @@ function _instrumentAutoCompactorUsage(compactor, options) {
13879
13913
  : null;
13880
13914
  return result;
13881
13915
  } catch (error) {
13916
+ call.returnedUsage = null;
13882
13917
  if (workflowEffectId) {
13883
13918
  throw _workflowCompactionOutcomeUnknown(error);
13884
13919
  }
@@ -14026,8 +14061,8 @@ async function _getAutoCompactor(options) {
14026
14061
  compressOptions,
14027
14062
  sessionId: options.sessionId,
14028
14063
  operationId: `auto-${randomUUID()}`,
14029
- provider: options.provider,
14030
- model: options.model,
14064
+ provider: options.provider || "ollama",
14065
+ model: options.model || "unknown",
14031
14066
  env: options.contextMemoryEnv || process.env,
14032
14067
  persist: options.persistCompaction !== false,
14033
14068
  trigger: "auto",
@@ -15062,6 +15097,37 @@ export async function* agentLoop(messages, options) {
15062
15097
  !["committed", "degraded"].includes(stats.canonicalReceipt.status)
15063
15098
  ) {
15064
15099
  automaticCompactionSettlementBlocked = true;
15100
+ const unsettledCall = compactionUsageState.calls.at(-1);
15101
+ if (unsettledCall) {
15102
+ const providerReceipt = _takeCompactionProviderReceipt(
15103
+ unsettledCall,
15104
+ workflowEffectId,
15105
+ );
15106
+ if (providerReceipt) yield providerReceipt;
15107
+ if (
15108
+ unsettledCall.returnedUsage &&
15109
+ stats.summaryUsageUnknown !== true
15110
+ ) {
15111
+ yield {
15112
+ type: "token-usage",
15113
+ ...unsettledCall.returnedUsage,
15114
+ runId,
15115
+ };
15116
+ } else {
15117
+ yield {
15118
+ type: "compaction-usage-unknown",
15119
+ callId: unsettledCall.callId,
15120
+ runId,
15121
+ provider: unsettledCall.provider,
15122
+ model: unsettledCall.model,
15123
+ source: "semantic-compaction",
15124
+ code: "provider_usage_unsettled",
15125
+ reason:
15126
+ stats.summaryUsageUnknownReason ||
15127
+ "provider_transport_outcome_unknown",
15128
+ };
15129
+ }
15130
+ }
15065
15131
  yield {
15066
15132
  type: "compaction-degraded",
15067
15133
  runId,
@@ -15080,6 +15146,20 @@ export async function* agentLoop(messages, options) {
15080
15146
  backgroundSubAgents,
15081
15147
  backgroundUsageFailureState,
15082
15148
  );
15149
+ if (workflowEffectId) {
15150
+ throw _markWorkflowCompactionFailureReported(
15151
+ _workflowCompactionOutcomeUnknown(
15152
+ null,
15153
+ "CC_WORKFLOW_COMPACTION_SETTLEMENT_UNKNOWN",
15154
+ "Workflow-bound semantic compaction requires reconciliation",
15155
+ ),
15156
+ );
15157
+ }
15158
+ yield {
15159
+ type: "run-ended",
15160
+ runId,
15161
+ reason: "compaction-settlement-failed",
15162
+ };
15083
15163
  return;
15084
15164
  }
15085
15165
  const observerFailure = compactionUsageState.calls.find(
@@ -15092,16 +15172,11 @@ export async function* agentLoop(messages, options) {
15092
15172
  }
15093
15173
  compactionUsageCall = compactionUsageState.calls.at(-1) || null;
15094
15174
  const compactionUsage = _compactionTokenUsage(stats);
15095
- if (compactionUsageCall?.providerReceipt) {
15096
- yield {
15097
- type: "provider-request-receipt",
15098
- callId: compactionUsageCall.callId,
15099
- workflowEffectId,
15100
- callSequence: compactionUsageCall.callSequence,
15101
- source: "semantic-compaction",
15102
- ...compactionUsageCall.providerReceipt,
15103
- };
15104
- }
15175
+ const providerReceipt = _takeCompactionProviderReceipt(
15176
+ compactionUsageCall,
15177
+ workflowEffectId,
15178
+ );
15179
+ if (providerReceipt) yield providerReceipt;
15105
15180
  if (stats.degraded === true) {
15106
15181
  const usageOutcomeUnknown = stats.summaryUsageUnknown === true;
15107
15182
  const projectedStats = usageOutcomeUnknown
@@ -15177,6 +15252,11 @@ export async function* agentLoop(messages, options) {
15177
15252
  ),
15178
15253
  );
15179
15254
  }
15255
+ yield {
15256
+ type: "run-ended",
15257
+ runId,
15258
+ reason: "compaction-usage-unknown",
15259
+ };
15180
15260
  return;
15181
15261
  }
15182
15262
  if (
@@ -15239,6 +15319,11 @@ export async function* agentLoop(messages, options) {
15239
15319
  ),
15240
15320
  );
15241
15321
  }
15322
+ yield {
15323
+ type: "run-ended",
15324
+ runId,
15325
+ reason: "compaction-settlement-failed",
15326
+ };
15242
15327
  return;
15243
15328
  }
15244
15329
  if (!hermeticExecution) {
@@ -15303,6 +15388,79 @@ export async function* agentLoop(messages, options) {
15303
15388
  }
15304
15389
  compactionUsageCall =
15305
15390
  compactionUsageCall || compactionUsageState?.calls?.at(-1) || null;
15391
+ const { getRejectedCompactionUsage } =
15392
+ await import("../lib/context-memory-kernel/live-compaction.js");
15393
+ const rejectedUsage = getRejectedCompactionUsage(_e);
15394
+ const returnedUsage = compactionUsageCall?.returnedUsage;
15395
+ const providerReceipt = _takeCompactionProviderReceipt(
15396
+ compactionUsageCall,
15397
+ workflowEffectId,
15398
+ );
15399
+ if (providerReceipt) yield providerReceipt;
15400
+ const knownPlanRejection =
15401
+ rejectedUsage &&
15402
+ returnedUsage &&
15403
+ (!rejectedUsage.callId ||
15404
+ rejectedUsage.callId === returnedUsage.callId) &&
15405
+ (!rejectedUsage.receipt.callId ||
15406
+ rejectedUsage.receipt.callId === returnedUsage.callId) &&
15407
+ rejectedUsage.provider === returnedUsage.provider &&
15408
+ rejectedUsage.model === returnedUsage.model &&
15409
+ [
15410
+ "input_tokens",
15411
+ "output_tokens",
15412
+ "cache_read_input_tokens",
15413
+ "cache_creation_input_tokens",
15414
+ ].every(
15415
+ (field) =>
15416
+ rejectedUsage.usage[field] === returnedUsage.usage[field],
15417
+ );
15418
+ if (knownPlanRejection || (!rejectedUsage && returnedUsage)) {
15419
+ automaticCompactionSettlementBlocked = true;
15420
+ // Yield through the existing host ledger/budget settlement path;
15421
+ // never claim a callback or an error flag already paid this debt.
15422
+ yield { type: "token-usage", ...returnedUsage, runId };
15423
+ yield {
15424
+ type: "compaction-degraded",
15425
+ runId,
15426
+ code: _e.code,
15427
+ reason: knownPlanRejection
15428
+ ? "canonical_compaction_plan_rejected"
15429
+ : "canonical_compaction_settlement_failed",
15430
+ summaryMode: "none",
15431
+ };
15432
+ await _awaitBackgroundUsageSettlement(
15433
+ backgroundSubAgents,
15434
+ backgroundUsageFailureState,
15435
+ );
15436
+ if (workflowEffectId) {
15437
+ if (knownPlanRejection) {
15438
+ const error = new Error(
15439
+ "Workflow-bound compaction plan was rejected; the task is incomplete",
15440
+ { cause: _e },
15441
+ );
15442
+ error.code = "CC_WORKFLOW_COMPACTION_PLAN_REJECTED";
15443
+ error.contextOutcome = "aborted";
15444
+ error.usageOutcome = "known";
15445
+ throw error;
15446
+ }
15447
+ const error = _workflowCompactionOutcomeUnknown(
15448
+ _e,
15449
+ "CC_WORKFLOW_COMPACTION_SETTLEMENT_UNKNOWN",
15450
+ "Workflow-bound semantic compaction settlement is unknown",
15451
+ );
15452
+ error.usageOutcome = "known";
15453
+ throw _markWorkflowCompactionFailureReported(error);
15454
+ }
15455
+ yield {
15456
+ type: "run-ended",
15457
+ runId,
15458
+ reason: knownPlanRejection
15459
+ ? "compaction-plan-rejected"
15460
+ : "compaction-settlement-failed",
15461
+ };
15462
+ return;
15463
+ }
15306
15464
  if (compactionUsageCall) {
15307
15465
  automaticCompactionSettlementBlocked = true;
15308
15466
  yield {
@@ -15326,6 +15484,11 @@ export async function* agentLoop(messages, options) {
15326
15484
  : _workflowCompactionOutcomeUnknown(_e),
15327
15485
  );
15328
15486
  }
15487
+ yield {
15488
+ type: "run-ended",
15489
+ runId,
15490
+ reason: "compaction-usage-unknown",
15491
+ };
15329
15492
  return;
15330
15493
  }
15331
15494
  yield {