chainlesschain 0.163.6 → 0.163.7

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 (218) hide show
  1. package/package.json +1 -1
  2. package/src/assets/web-panel/assets/{AIOps-DDIUofA8.js → AIOps-axqQfwv8.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-Bm-5xYRn.js → ActionButton-DV-Ro0By.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-D5UH4ljI.js → Analytics-Bt72WEVu.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-D_ifjOOP.js → AppLayout-BtepG55E.js} +5 -5
  6. package/src/assets/web-panel/assets/{Artifacts-BY1mXdC7.js → Artifacts-B7KaJ7S_.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-Bujr4Ml3.js → Audit-FNFaUg7A.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-sioKSTcC.js → BackgroundAgents-DFb6J2wQ.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DDOAK8RK.js → Backup-CC7YBhyj.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CtCsVVke.js → BaseInput-RkgTNVtj.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DpNj0vnd.js → Chat-hHEmGZy-.js} +4 -4
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZta3Ftr.js → ChatBubbleRenderer-CAP9YhHv.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-DoHVNSXq.js → Checkbox-z5wXOQP1.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DlVl7Qmv.js → Codegen-DVaDJnxy.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-GIqoPYty.js → Col-CJmaRDR5.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CIAPEVji.js → Community-DF29_2bI.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BN7JiI_h.js → Compact-DtkQkBzn.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CqUWCM9B.js → Compliance-xoHDxp7I.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-A4iPp7A4.js → Cowork-BUm-R7ht.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-B2zeXXWb.js → Cron-Cgl14ZkB.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BR2xmWr8.js → Crosschain-BNcbmoqh.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-BzFDjrIv.js → DID-Bwja0Zo9.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DKtDo3yA.js → Dashboard-Bk5XjEdJ.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-RNx43_YG.js → Dropdown-Ci36Oitq.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-SwMt4Rcy.js → EmailListRenderer--U04ZN4q.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CsYebZ4X.js → FamilyGuardDashboard-B2gNPR2s.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BmRKvBTy.js → Federation-C4KghYn7.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CVxGTA-0.js → FormItemContext-QL7x_Q_0.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-x2iXpyB7.js → GenericCardRenderer-F3Ryltwm.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DfqbkiOP.js → Git-2HassK5k.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-RuHyyj5O.js → Governance-DoBIp7oe.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-Bn7uZ7rI.js → Inference--W01QhZ-.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DlP7XefZ.js → KnowledgeGraph-DmvwqGpT.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-BYNdOiCd.js → Logs-BBJ4yAel.js} +2 -2
  35. package/src/assets/web-panel/assets/{MarkdownRenderer-aMtgN-R6.js → MarkdownRenderer-BLCZMzhJ.js} +1 -1
  36. package/src/assets/web-panel/assets/{Marketplace-JQYmDqM8.js → Marketplace-D5lNngSI.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Cyx4yZ-9.js → McpTools-CkEVOMKH.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-VDuGZTN2.js → Memory-B1Ow1xVE.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-_yKo97gi.js → MobileBridge-SgYbUfb6.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-CXRXW3q7.js → MobileProjects-BWdOvQAj.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-acTGtfLH.js → Mtc-DcTXSSma.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-ClpjXfkY.js → MtcAudit-Dt3WG4oj.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-_6Tn3o96.js → Multisig-B9B38UZx.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-CK7pbZzP.js → NLProgramming-B0S4GGvG.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-Czy6V_P8.js → Notes-DZ5U58Ng.js} +3 -3
  46. package/src/assets/web-panel/assets/{NotificationSettings-Cqx-UVv3.js → NotificationSettings-PjL5ZW34.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-C69WDxGy.js → OrderTableRenderer-DrAX2ESt.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-DFnA9vLQ.js → Organization-Cv1GYs-c.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-ReZkk2yT.js → Overflow-Bbkp_PL3.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-DzjSI0aI.js → P2P-BD8QUgoZ.js} +2 -2
  51. package/src/assets/web-panel/assets/{PdhVaultBrowser-DKTf5xIP.js → PdhVaultBrowser-BO-2PeaB.js} +3 -3
  52. package/src/assets/web-panel/assets/{Permissions-DhQ5klhR.js → Permissions-D_OPVa02.js} +4 -4
  53. package/src/assets/web-panel/assets/{PersonalDataHub-CUL1iHrW.js → PersonalDataHub-mh-pEmaB.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-DU88iu4N.js → Pipeline-6JC2EDdb.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-Bw-sYfyK.js → Privacy-CUshzUAG.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-Bq3Q5y0z.js → ProjectInit-Cs2Aalri.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-C8spzpho.js → ProjectSettings-1ak49tcj.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-BV4oApsm.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-Bf4eTP9W.js → Providers-CXXxvafH.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-Dme9BDU1.js → QrScannerModal-PTcDsF58.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-CIXfv1rE.js → QuickAsk-CDwucrJw.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CIxvdeZ-.js → Recommend-CJlLVRXR.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C6k7MExI.js → RemoteSession-DlN-ETsO.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CISDz2bl.js → Reputation-DI23LR6m.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-CdnDxXyf.js → Row-Cl7UQMrM.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-C-QpRHsl.js → RssFeed-CexHNfh8.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DBjaGzSn.js → Search-BneBWvRN.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CQKukOeE.js → Security-DX7Phgrp.js} +4 -4
  69. package/src/assets/web-panel/assets/{Services-DZz86jWb.js → Services-BWXO8Mte.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-jb8RMK0d.js → Skeleton-DCyOjKPJ.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CdY76fZG.js → Skills-CXqERsTB.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-C_CSiZX9.js → Sla-bhbrbz8E.js} +1 -1
  73. package/src/assets/web-panel/assets/SpeechSettings-3IPU0HBZ.js +1 -0
  74. package/src/assets/web-panel/assets/{SyncSettings-qvimGO0O.js → SyncSettings-DBNTQLbM.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-Dng5LPJC.js → Tasks-quP0bkN-.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Bwqq5Wll.js → Templates-BouWmgho.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DNWuwP7Z.js → Tenant-qv0D9s7z.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-B-6Othpp.js → Terminal-BxvbE8BB.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DKpKZfzx.js → TimelineRenderer-D-IeLnJ2.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DzfGMd2J.js → Tokens-CFMKKyVG.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BXwUi74J.js → Trigger-L8as3UuJ.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BNzUq4ui.js → Trust-MxmA4VZG.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-BYugxww4.js → UkeySign-C0VvJYRi.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DdauhtSJ.js → VideoEditing-Bf5QZj8N.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-CSC9bCe_.js → Wallet-BIJ9riRz.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Q8AN3bTO.js → WebAuthn-B8p9Mhkw.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-d-LBGCuA.js → WorkflowEditor-BVsuaPen.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BLVDCgsZ.js → chat-BfkjoKpV.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BZlPSEHl.js → colors-DeAlsWK8.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-IWseP6R6.js → compact-item-Cs97bz5j.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DnVRV3Ao.js → createContext-BqbG60LH.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-DPty0mGN.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DLQZA_Wn.js → hasIn-i_RY0b1X.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-B_N4-Gq9.js → index-0-agYlWL.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-DB0MJgF_.js → index-79V_zv1s.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-BOZJBTWZ.js → index-B-3tEpTc.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-DUq0c7gq.js → index-B-JVTrpr.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Dy0R5ZED.js → index-B1CbOH1i.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-Bxp7uDD8.js → index-B5UkyA3c.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DpVrK6fr.js → index-BESLFt4q.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CT9vVN-X.js → index-BOVkf1K3.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-DOoQpuQY.js → index-BYUVuwKt.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-CINJQEj6.js → index-BcUXAB2s.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CarMTIyQ.js → index-BkBi5TmC.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C5dgnilC.js → index-Bm7lLR4c.js} +1 -1
  106. package/src/assets/web-panel/assets/index-Bt7g0Vq_.js +1 -0
  107. package/src/assets/web-panel/assets/{index-CbQNL0ue.js → index-BuLQobzW.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CpBaJ3TD.js → index-CE2VtTlp.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-jWb70ZgZ.js → index-CED2PL_y.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BEu2lMBy.js → index-CG3PRyAL.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-DocEhinm.js → index-CIG8fQ2_.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-D_LQodeJ.js → index-COdGA-8n.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-DZpYeqrh.js → index-CeWoNHau.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-gt8bNefW.js → index-Cf3WCLmy.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-N_GoWZX4.js → index-CgsqdnRV.js} +1 -1
  116. package/src/assets/web-panel/assets/index-ChVT0p9u.js +1 -0
  117. package/src/assets/web-panel/assets/{index-CZDekj7T.js → index-D2B4VPyP.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-YSw_gxlZ.js → index-D9evtvg2.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DTbxp4UH.js → index-DUUrv141.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-Bbj2NS_I.js → index-DiSkx4UB.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-BZs5bBnk.js → index-Dk2qouAz.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DalA0TKC.js → index-Dk7-v4hP.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-1jeAudHd.js → index-DmbfhJUP.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-C1ifZtXo.js → index-DqBgBpgp.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-BhA3QEni.js → index-PT_5sBMA.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-BSjilZ9L.js → index-U4f5izHz.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-C2FqfMvU.js → index-YXgLng0K.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-COev0W2g.js → index-ZxO_-E8a.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-M7wxfAbm.js → index-dIHr4B_u.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-DjWnONdy.js → index-gyFpvL7l.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-Dkwsi1Kn.js → index-s1opAL-M.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-hwVDeoC0.js → index-yObj1O4n.js} +1 -1
  133. package/src/assets/web-panel/assets/{initDefaultProps-Co67Kqmb.js → initDefaultProps-C9h9yKL3.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BMOxQSF_.js → motion-BvmLsPdu.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-C5fWDw-N.js → move-CoL4ekU1.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BJevpL0e.js → mtc-parser-C4pMy6xV.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-BCzNU8s6.js → omit-DPuJfNxx.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-CybWvDPk.js → pickAttrs-D0KEeaK2.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BMWS9HnW.js → placementArrow-BpkyINxt.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-BoL2UnGY.js → responsiveObserve-DQI_wOq8.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DWNfXraU.js → slide-DYfdDiRg.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BquTM3tX.js → statusUtils-B5dtvb0D.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-BEkCleim.js → styleChecker-CF310mSj.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Oecnq7EA.js → useFlexGapSupport-D1Qp4BLp.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-CkDffJ4F.js → useFs-C7_iyvJK.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-qbvKXesB.js → usePersonalDataHub-DZUt_fIm.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-C6v8n6mA.js → vnode-D3dsi0lZ.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-4CTeFILV.js → zoom-WdbOlvdQ.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +2 -2
  151. package/src/commands/agent.js +90 -1
  152. package/src/commands/chat.js +11 -2
  153. package/src/commands/compact.js +106 -23
  154. package/src/commands/loop.js +28 -10
  155. package/src/commands/routine.js +1 -1
  156. package/src/commands/scheduler-daemon.js +359 -2
  157. package/src/commands/session-observability.js +305 -0
  158. package/src/commands/session.js +38 -0
  159. package/src/data/changelog.json +14 -1
  160. package/src/gateways/ws/ws-agent-handler.js +439 -5
  161. package/src/harness/jsonl-session-store.js +463 -125
  162. package/src/harness/prompt-compressor.js +86 -13
  163. package/src/harness/provider-backed-compaction.js +100 -27
  164. package/src/lib/advisor-runtime.js +3 -1
  165. package/src/lib/agent-schedule-store.js +414 -4
  166. package/src/lib/agent-team/team-adjudication.js +40 -1
  167. package/src/lib/automation-engine.js +494 -0
  168. package/src/lib/background-agent-supervisor.js +793 -215
  169. package/src/lib/background-command-argv.js +24 -0
  170. package/src/lib/background-interaction-journal.js +361 -52
  171. package/src/lib/background-interaction-resolver.js +32 -0
  172. package/src/lib/background-launch-profile.js +2 -0
  173. package/src/lib/causal-observability.js +2661 -0
  174. package/src/lib/chat-session-admission.js +76 -0
  175. package/src/lib/cost-budget.js +5 -7
  176. package/src/lib/cowork/ab-comparator-cli.js +11 -0
  177. package/src/lib/cowork/debate-review-cli.js +12 -0
  178. package/src/lib/cowork-adapter.js +159 -38
  179. package/src/lib/cowork-cron.js +357 -1
  180. package/src/lib/cowork-task-runner.js +112 -17
  181. package/src/lib/delivery-coordinator.js +142 -0
  182. package/src/lib/direct-model-usage.js +121 -0
  183. package/src/lib/file-lines.js +183 -47
  184. package/src/lib/llm-pricing.js +12 -17
  185. package/src/lib/loop.js +26 -2
  186. package/src/lib/routine-store.js +380 -21
  187. package/src/lib/runtime-usage-ledger.js +182 -0
  188. package/src/lib/scheduler-kernel/agenda-adapter.js +308 -3
  189. package/src/lib/scheduler-kernel/automation-adapter.js +410 -8
  190. package/src/lib/scheduler-kernel/automation-event-adapter.js +36 -0
  191. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +285 -3
  192. package/src/lib/scheduler-kernel/loop-adapter.js +541 -6
  193. package/src/lib/scheduler-kernel/migration-admin.js +346 -0
  194. package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
  195. package/src/lib/scheduler-kernel/routine-adapter.js +394 -20
  196. package/src/lib/scheduler-kernel/runtime.js +63 -1
  197. package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
  198. package/src/lib/scheduler-kernel/store.js +2586 -85
  199. package/src/lib/session-host-lease.js +171 -2
  200. package/src/lib/session-host-snapshot.js +14 -3
  201. package/src/lib/session-persistence-failure.js +1 -0
  202. package/src/lib/session-tail.js +179 -34
  203. package/src/lib/session-transcript-structure.js +96 -0
  204. package/src/lib/sub-agent-context.js +328 -22
  205. package/src/lib/ws-agent-handler.js +4 -1
  206. package/src/repl/agent-repl.js +732 -91
  207. package/src/repl/chat-repl.js +5 -1
  208. package/src/runtime/agent-core.js +1272 -207
  209. package/src/runtime/fallback-model.js +5 -0
  210. package/src/runtime/headless-runner.js +324 -82
  211. package/src/runtime/headless-stream.js +232 -26
  212. package/src/runtime/policies/agent-policy.js +4 -0
  213. package/src/workers/background-agent-worker.js +403 -96
  214. package/src/assets/web-panel/assets/Projects-Dd-xuPIc.js +0 -1
  215. package/src/assets/web-panel/assets/SpeechSettings-C7tT9iad.js +0 -1
  216. package/src/assets/web-panel/assets/devWarning-Jzu62CLC.js +0 -1
  217. package/src/assets/web-panel/assets/index-Zb2MeDSy.js +0 -1
  218. package/src/assets/web-panel/assets/index-fikqml4k.js +0 -1
@@ -11,6 +11,7 @@
11
11
  * adapter.
12
12
  */
13
13
 
14
+ import { randomUUID } from "node:crypto";
14
15
  import { agentLoop, formatToolArgs } from "../../runtime/agent-core.js";
15
16
  import { classifyToolSideEffect } from "../../lib/side-effect-ledger.js";
16
17
  import { DiffReviewFollowUpTracker } from "../../lib/diff-review-follow-up.js";
@@ -37,12 +38,25 @@ import { createMcpHostRecoveryRuntime } from "../../lib/mcp-host-recovery-runtim
37
38
  import { compactConversationWithProvider } from "../../harness/provider-backed-compaction.js";
38
39
  import { projectCanonicalResumeMessages } from "../../lib/session-message-provenance.js";
39
40
  import { feature } from "../../lib/feature-flags.js";
41
+ import { classifyStreamRetryReason } from "../../lib/stream-retry.js";
42
+ import {
43
+ markRuntimeLedgerPersistenceError,
44
+ projectRuntimeTokenUsage,
45
+ projectRuntimeUsageBoundary,
46
+ runtimeToolCallId,
47
+ runtimeUsageEventType,
48
+ } from "../../lib/runtime-usage-ledger.js";
40
49
  import {
41
50
  appendCompactEventIfMessagesMatch,
51
+ appendEvent,
52
+ appendLlmRetryCompact,
53
+ appendTokenUsage,
54
+ appendToolCallCompact,
42
55
  claimWsTurnIfHead,
43
56
  computeWsTurnInputDigest,
44
57
  createWsTurnClaimId,
45
58
  normalizeWsTurnRequestId,
59
+ readVerifiedProjection,
46
60
  readVerifiedWsTurnState,
47
61
  readVerifiedMessages,
48
62
  settleWsTurnClaim,
@@ -50,6 +64,59 @@ import {
50
64
 
51
65
  const CANONICAL_WS_TURN_QUEUES = new Map();
52
66
  const CANONICAL_WS_CLAIM_CAS_ATTEMPTS = 4;
67
+ const CALL_LEDGER_PROTOCOL = "call-ledger";
68
+ const CALL_LEDGER_VERSION = 1;
69
+ const USAGE_LEDGER_PERSISTENCE_CODE = "CC_USAGE_LEDGER_PERSISTENCE_FAILED";
70
+ const USAGE_LEDGER_PERSISTENCE_MESSAGE =
71
+ "Canonical usage ledger persistence failed; model and tool execution is blocked";
72
+
73
+ function usageProtocolError(code, message) {
74
+ const error = new Error(message);
75
+ error.code = code;
76
+ return error;
77
+ }
78
+
79
+ function classifyCanonicalUsageProtocol(data = {}) {
80
+ const record =
81
+ data && typeof data === "object" && !Array.isArray(data) ? data : {};
82
+ const hasScope = Object.hasOwn(record, "observabilityScope");
83
+ const hasProtocol = Object.hasOwn(record, "usageTelemetryProtocol");
84
+ const hasVersion = Object.hasOwn(record, "usageTelemetryVersion");
85
+ if (!hasScope && !hasProtocol && !hasVersion) return "legacy";
86
+ if (!hasProtocol || !hasVersion) {
87
+ throw usageProtocolError(
88
+ "CC_USAGE_LEDGER_PROTOCOL_REQUIRED",
89
+ "Canonical scoped sessions require call-ledger usage telemetry before model or tool execution",
90
+ );
91
+ }
92
+ if (
93
+ record.usageTelemetryProtocol !== CALL_LEDGER_PROTOCOL ||
94
+ record.usageTelemetryVersion !== CALL_LEDGER_VERSION
95
+ ) {
96
+ throw usageProtocolError(
97
+ "CC_USAGE_LEDGER_PROTOCOL_UNSUPPORTED",
98
+ "Canonical session usage telemetry protocol is unsupported",
99
+ );
100
+ }
101
+ return "call-ledger";
102
+ }
103
+
104
+ export function readCanonicalUsageProtocol(sessionId, projectionReader) {
105
+ if (typeof projectionReader !== "function") return "legacy";
106
+ return projectionReader(sessionId, () => {
107
+ let sessionStart = null;
108
+ return {
109
+ accept(event) {
110
+ if (event?.type === "session_start" && sessionStart === null) {
111
+ sessionStart = event.data || {};
112
+ }
113
+ },
114
+ finish() {
115
+ return classifyCanonicalUsageProtocol(sessionStart || {});
116
+ },
117
+ };
118
+ });
119
+ }
53
120
 
54
121
  function runCanonicalWsTurnExclusive(sessionId, task) {
55
122
  const previous = CANONICAL_WS_TURN_QUEUES.get(sessionId) || Promise.resolve();
@@ -137,17 +204,33 @@ export class WSAgentHandler {
137
204
  const { chatWithTools } = await import("../../runtime/agent-core.js");
138
205
  return chatWithTools(...args);
139
206
  });
207
+ const injectedCanonicalStore = canonicalSessionStore || null;
140
208
  this._canonicalSessionStore = {
141
209
  appendCompactEventIfMessagesMatch,
210
+ appendEvent,
211
+ appendLlmRetryCompact,
212
+ appendTokenUsage,
213
+ appendToolCallCompact,
142
214
  claimWsTurnIfHead,
143
215
  computeWsTurnInputDigest,
144
216
  createWsTurnClaimId,
145
217
  normalizeWsTurnRequestId,
218
+ readVerifiedProjection,
146
219
  readVerifiedWsTurnState,
147
220
  readVerifiedMessages,
148
221
  settleWsTurnClaim,
149
222
  ...(canonicalSessionStore || {}),
150
223
  };
224
+ // Test/embedding stores historically injected only WS-turn CAS methods.
225
+ // Preserve that compatibility as legacy unless they explicitly provide a
226
+ // verified projection reader. The production store always supplies one.
227
+ this._canonicalUsageProjectionReader =
228
+ injectedCanonicalStore &&
229
+ typeof injectedCanonicalStore.readVerifiedProjection !== "function"
230
+ ? null
231
+ : this._canonicalSessionStore.readVerifiedProjection;
232
+ this._canonicalUsageProtocol = null;
233
+ this._usageLedgerFailure = null;
151
234
  const explicitHostPrefix = Array.isArray(
152
235
  session?._canonicalHostSystemPrefix,
153
236
  )
@@ -188,6 +271,159 @@ export class WSAgentHandler {
188
271
  return this.session.messages;
189
272
  }
190
273
 
274
+ _resolveCanonicalUsageProtocol() {
275
+ if (this.session.canonicalJsonlSession !== true) return "legacy";
276
+ if (this._canonicalUsageProtocol) return this._canonicalUsageProtocol;
277
+
278
+ // An embedding may attach the immutable session-start declaration directly
279
+ // while supplying a partial canonical store. Never ignore such a marker.
280
+ const attachedDeclaration = {};
281
+ for (const field of [
282
+ "observabilityScope",
283
+ "usageTelemetryProtocol",
284
+ "usageTelemetryVersion",
285
+ ]) {
286
+ if (Object.hasOwn(this.session, field)) {
287
+ attachedDeclaration[field] = this.session[field];
288
+ }
289
+ }
290
+ const attachedMode = classifyCanonicalUsageProtocol(attachedDeclaration);
291
+ if (attachedMode !== "legacy") {
292
+ this._canonicalUsageProtocol = attachedMode;
293
+ return attachedMode;
294
+ }
295
+
296
+ this._canonicalUsageProtocol = readCanonicalUsageProtocol(
297
+ this.session.id,
298
+ this._canonicalUsageProjectionReader,
299
+ );
300
+ return this._canonicalUsageProtocol;
301
+ }
302
+
303
+ _usageLedgerTerminalError(cause = null) {
304
+ const error = new Error(USAGE_LEDGER_PERSISTENCE_MESSAGE, {
305
+ ...(cause ? { cause } : {}),
306
+ });
307
+ error.code = USAGE_LEDGER_PERSISTENCE_CODE;
308
+ error.runtimeLedgerPersistence = true;
309
+ return error;
310
+ }
311
+
312
+ _latchUsageLedgerFailure(error) {
313
+ const marked = markRuntimeLedgerPersistenceError(error);
314
+ this._usageLedgerFailure ||= Object.freeze({
315
+ code: USAGE_LEDGER_PERSISTENCE_CODE,
316
+ reason: "canonical_usage_ledger_persistence_failed",
317
+ });
318
+ return this._usageLedgerTerminalError(marked);
319
+ }
320
+
321
+ _assertUsageLedgerWritable() {
322
+ if (this._usageLedgerFailure) throw this._usageLedgerTerminalError();
323
+ }
324
+
325
+ _callCanonicalLedgerStore(method, ...args) {
326
+ this._assertUsageLedgerWritable();
327
+ try {
328
+ const result = this._canonicalSessionStore[method](...args);
329
+ if (result && typeof result.then === "function") {
330
+ void Promise.resolve(result).catch(() => {});
331
+ throw new TypeError(
332
+ `Canonical usage ledger ${method} must be synchronous`,
333
+ );
334
+ }
335
+ return result;
336
+ } catch (error) {
337
+ throw this._latchUsageLedgerFailure(error);
338
+ }
339
+ }
340
+
341
+ _persistCanonicalUsageBoundary(event, outcome) {
342
+ let projected;
343
+ try {
344
+ projected = projectRuntimeUsageBoundary(event, outcome);
345
+ } catch (error) {
346
+ throw this._latchUsageLedgerFailure(error);
347
+ }
348
+ this._callCanonicalLedgerStore(
349
+ "appendEvent",
350
+ this.session.id,
351
+ runtimeUsageEventType(outcome),
352
+ projected,
353
+ );
354
+ }
355
+
356
+ _persistCanonicalTokenUsage(event) {
357
+ let projected;
358
+ try {
359
+ projected = projectRuntimeTokenUsage(event);
360
+ } catch (error) {
361
+ throw this._latchUsageLedgerFailure(error);
362
+ }
363
+ this._callCanonicalLedgerStore(
364
+ "appendTokenUsage",
365
+ this.session.id,
366
+ projected,
367
+ );
368
+ }
369
+
370
+ _persistCanonicalUsageSettlement(event) {
371
+ if (event?.type === "token-usage") {
372
+ this._persistCanonicalTokenUsage(event);
373
+ return;
374
+ }
375
+ this._persistCanonicalUsageBoundary(event, "unknown");
376
+ }
377
+
378
+ _beginCanonicalCompactionUsage() {
379
+ const call = Object.freeze({
380
+ callId: `ws-cmp-${randomUUID()}`,
381
+ provider: this.session.provider || null,
382
+ model: this.session.model || null,
383
+ source: "semantic-compaction",
384
+ });
385
+ this._persistCanonicalUsageBoundary(call, "started");
386
+ return call;
387
+ }
388
+
389
+ _settleCanonicalCompactionUsage(call, result) {
390
+ if (!call) return;
391
+ const unknown = result?.usageUnknownEvent || null;
392
+ if (unknown) {
393
+ const reason = unknown.reason || "provider_transport_outcome_unknown";
394
+ this._persistCanonicalUsageBoundary(
395
+ {
396
+ ...call,
397
+ code:
398
+ reason === "provider_usage_not_reported"
399
+ ? "provider_usage_missing"
400
+ : unknown.code || "provider_call_failed",
401
+ },
402
+ "unknown",
403
+ );
404
+ return;
405
+ }
406
+ if (result?.usageEvent?.usage) {
407
+ this._persistCanonicalTokenUsage({
408
+ ...call,
409
+ usage: result.usageEvent.usage,
410
+ });
411
+ return;
412
+ }
413
+ this._persistCanonicalUsageBoundary(
414
+ { ...call, code: "provider_usage_missing" },
415
+ "unknown",
416
+ );
417
+ }
418
+
419
+ _settleCanonicalCompactionFailure(call) {
420
+ if (!call) return;
421
+ this._persistCanonicalUsageBoundary(
422
+ { ...call, code: "provider_call_failed" },
423
+ "unknown",
424
+ );
425
+ }
426
+
191
427
  _latchCompactionSettlement({
192
428
  code,
193
429
  reason,
@@ -286,6 +522,10 @@ export class WSAgentHandler {
286
522
 
287
523
  const before = session.messages.length;
288
524
  const expectedMessages = [...session.messages];
525
+ const strictUsageTelemetry =
526
+ this._resolveCanonicalUsageProtocol() === "call-ledger";
527
+ let compactionUsageCall = null;
528
+ let compactionUsageSettled = false;
289
529
  let result;
290
530
  try {
291
531
  this._sessionHostLease?.assert?.();
@@ -303,13 +543,35 @@ export class WSAgentHandler {
303
543
  cwd: session.projectRoot,
304
544
  sessionId: session.id,
305
545
  },
546
+ ...(strictUsageTelemetry
547
+ ? {
548
+ onProviderCallStart: () => {
549
+ const call = this._beginCanonicalCompactionUsage();
550
+ compactionUsageCall = call;
551
+ return call.callId;
552
+ },
553
+ }
554
+ : {}),
306
555
  maxMessages: session.compactionMaxMessages,
307
556
  maxTokens: session.compactionMaxTokens,
308
557
  maxOutputTokens: session.compactionMaxOutputTokens,
309
558
  summaryInputMaxChars: session.compactionInputMaxChars,
310
559
  });
560
+ if (compactionUsageCall) {
561
+ this._settleCanonicalCompactionUsage(compactionUsageCall, result);
562
+ compactionUsageSettled = true;
563
+ }
311
564
  this._sessionHostLease?.assert?.();
312
565
  } catch (error) {
566
+ if (
567
+ compactionUsageCall &&
568
+ !compactionUsageSettled &&
569
+ error?.runtimeLedgerPersistence !== true
570
+ ) {
571
+ this._settleCanonicalCompactionFailure(compactionUsageCall);
572
+ compactionUsageSettled = true;
573
+ }
574
+ if (error?.runtimeLedgerPersistence === true) throw error;
313
575
  if (isAbortError(error) || this._sessionHostLease?.signal?.aborted) {
314
576
  throw error;
315
577
  }
@@ -755,6 +1017,7 @@ export class WSAgentHandler {
755
1017
  let diffReviewFollowUps = null;
756
1018
  let runRecorded = false;
757
1019
  let canonicalTurn = null;
1020
+ let strictUsageTelemetry = false;
758
1021
 
759
1022
  try {
760
1023
  const { session } = this;
@@ -776,6 +1039,9 @@ export class WSAgentHandler {
776
1039
  inputDigest,
777
1040
  );
778
1041
  if (!canonicalTurn) {
1042
+ strictUsageTelemetry =
1043
+ this._resolveCanonicalUsageProtocol() === "call-ledger";
1044
+ if (strictUsageTelemetry) this._assertUsageLedgerWritable();
779
1045
  const compacted =
780
1046
  await this._compactCanonicalHistoryBeforeClaim(requestId);
781
1047
  if (!compacted) return;
@@ -886,6 +1152,27 @@ export class WSAgentHandler {
886
1152
  ...(session.canonicalJsonlSession === true
887
1153
  ? { autoCompact: false }
888
1154
  : {}),
1155
+ ...(strictUsageTelemetry
1156
+ ? {
1157
+ strictUsageTelemetry: true,
1158
+ onUsageBoundary: (event) =>
1159
+ this._persistCanonicalUsageBoundary(event, "started"),
1160
+ onUsageSettlement: (event) =>
1161
+ this._persistCanonicalUsageSettlement(event),
1162
+ onStreamRetry: (attempt, error, telemetry = {}) =>
1163
+ this._callCanonicalLedgerStore(
1164
+ "appendLlmRetryCompact",
1165
+ session.id,
1166
+ {
1167
+ attempt,
1168
+ durationMs: telemetry.durationMs,
1169
+ provider: telemetry.provider || session.provider,
1170
+ model: telemetry.model || activeModel,
1171
+ reason: classifyStreamRetryReason(error),
1172
+ },
1173
+ ),
1174
+ }
1175
+ : {}),
889
1176
  };
890
1177
 
891
1178
  // P0-2: crash-safe side-effect ledger for the IDE/bridge path — mirrors
@@ -897,6 +1184,68 @@ export class WSAgentHandler {
897
1184
  diffReviewFollowUps = new DiffReviewFollowUpTracker(sideEffectLedger);
898
1185
  let currentSideEffectOpId = null;
899
1186
  let currentTodoWrite = null;
1187
+ const activeToolCalls = new Map();
1188
+ const activeToolCallOrder = [];
1189
+ const boundedToolUseId = (value) =>
1190
+ typeof value === "string" &&
1191
+ value.trim() &&
1192
+ value.length <= 128 &&
1193
+ !/\p{Cc}/u.test(value)
1194
+ ? value.trim()
1195
+ : null;
1196
+ const boundedToolName = (value) => {
1197
+ if (typeof value !== "string") return "?";
1198
+ const clean = value.replace(/\p{Cc}/gu, "").trim();
1199
+ return clean ? clean.slice(0, 160) : "?";
1200
+ };
1201
+ const beginToolUsage = (event) => {
1202
+ const providerId = boundedToolUseId(event.tool_use_id);
1203
+ const record = {
1204
+ id: runtimeToolCallId(providerId || undefined),
1205
+ providerId,
1206
+ tool: boundedToolName(event.tool),
1207
+ startedAt: Date.now(),
1208
+ };
1209
+ this._callCanonicalLedgerStore(
1210
+ "appendEvent",
1211
+ session.id,
1212
+ "tool_call_started",
1213
+ { id: record.id, tool: record.tool },
1214
+ );
1215
+ activeToolCallOrder.push(record);
1216
+ if (providerId) activeToolCalls.set(providerId, record);
1217
+ };
1218
+ const settleToolUsage = (event) => {
1219
+ const providerId = boundedToolUseId(event.tool_use_id);
1220
+ const record =
1221
+ (providerId ? activeToolCalls.get(providerId) : null) ||
1222
+ activeToolCallOrder.find(
1223
+ (entry) => entry.tool === boundedToolName(event.tool),
1224
+ ) ||
1225
+ null;
1226
+ if (!record) return;
1227
+ const durationMs =
1228
+ event.result?.toolTelemetryRecord?.durationMs ??
1229
+ Math.max(0, Date.now() - record.startedAt);
1230
+ this._callCanonicalLedgerStore("appendToolCallCompact", session.id, {
1231
+ id: record.id,
1232
+ tool: record.tool,
1233
+ isError: Boolean(event.error || event.result?.error),
1234
+ skill:
1235
+ event?.attribution?.skill ||
1236
+ (record.tool === "run_skill"
1237
+ ? event.result?.skill || event.result?.skill_name || undefined
1238
+ : undefined),
1239
+ durationMs,
1240
+ });
1241
+ if (record.providerId) activeToolCalls.delete(record.providerId);
1242
+ const index = activeToolCallOrder.indexOf(record);
1243
+ if (index >= 0) activeToolCallOrder.splice(index, 1);
1244
+ };
1245
+ if (strictUsageTelemetry) {
1246
+ loopOptions.onToolCallBoundary = beginToolUsage;
1247
+ loopOptions.onToolCallSettlement = settleToolUsage;
1248
+ }
900
1249
 
901
1250
  const executeAgentTurn = async () => {
902
1251
  for await (const event of this._agentLoop(
@@ -913,6 +1262,7 @@ export class WSAgentHandler {
913
1262
  break;
914
1263
 
915
1264
  case "tool-executing":
1265
+ if (strictUsageTelemetry) beginToolUsage(event);
916
1266
  this.interaction.emit("tool-executing", {
917
1267
  requestId,
918
1268
  tool: event.tool,
@@ -953,6 +1303,7 @@ export class WSAgentHandler {
953
1303
  break;
954
1304
 
955
1305
  case "tool-result":
1306
+ if (strictUsageTelemetry) settleToolUsage(event);
956
1307
  this.interaction.emit("tool-result", {
957
1308
  requestId,
958
1309
  tool: event.tool,
@@ -1007,9 +1358,24 @@ export class WSAgentHandler {
1007
1358
  break;
1008
1359
 
1009
1360
  case "compaction-usage-unknown":
1361
+ if (strictUsageTelemetry && event.ledgerPersisted !== true) {
1362
+ this._persistCanonicalUsageBoundary(event, "unknown");
1363
+ }
1010
1364
  this._emitCompactionUsageUnknown(requestId, event);
1011
1365
  break;
1012
1366
 
1367
+ case "model-usage-started":
1368
+ if (strictUsageTelemetry && event.ledgerPersisted !== true) {
1369
+ this._persistCanonicalUsageBoundary(event, "started");
1370
+ }
1371
+ break;
1372
+
1373
+ case "model-usage-unknown":
1374
+ if (strictUsageTelemetry && event.ledgerPersisted !== true) {
1375
+ this._persistCanonicalUsageBoundary(event, "unknown");
1376
+ }
1377
+ break;
1378
+
1013
1379
  case "compaction":
1014
1380
  this.interaction.emit("compaction", {
1015
1381
  requestId,
@@ -1018,6 +1384,9 @@ export class WSAgentHandler {
1018
1384
  break;
1019
1385
 
1020
1386
  case "token-usage":
1387
+ if (strictUsageTelemetry && event.ledgerPersisted !== true) {
1388
+ this._persistCanonicalTokenUsage(event);
1389
+ }
1021
1390
  this.interaction.emit("token-usage", {
1022
1391
  requestId,
1023
1392
  provider: event.provider,
@@ -1122,6 +1491,12 @@ export class WSAgentHandler {
1122
1491
  );
1123
1492
  surfacedError.code = "CC_WS_TURN_SETTLEMENT_UNKNOWN";
1124
1493
  }
1494
+ if (
1495
+ surfacedError?.runtimeLedgerPersistence === true &&
1496
+ surfacedError?.code !== "CC_WS_TURN_SETTLEMENT_UNKNOWN"
1497
+ ) {
1498
+ surfacedError = this._usageLedgerTerminalError(surfacedError);
1499
+ }
1125
1500
  if (canonicalTurn?.baseMessages && canonicalTurn.status !== "completed") {
1126
1501
  this.session.messages = [...canonicalTurn.baseMessages];
1127
1502
  }
@@ -1312,10 +1687,41 @@ export class WSAgentHandler {
1312
1687
  break;
1313
1688
  }
1314
1689
 
1690
+ let strictUsageTelemetry = false;
1691
+ if (session.canonicalJsonlSession === true) {
1692
+ try {
1693
+ strictUsageTelemetry =
1694
+ this._resolveCanonicalUsageProtocol() === "call-ledger";
1695
+ if (strictUsageTelemetry) this._assertUsageLedgerWritable();
1696
+ } catch (error) {
1697
+ const admission = {
1698
+ code: error?.code || "CC_USAGE_LEDGER_ADMISSION_FAILED",
1699
+ reason: "canonical_usage_telemetry_admission_failed",
1700
+ };
1701
+ this.interaction.emit("compaction-degraded", {
1702
+ requestId,
1703
+ reason: admission.reason,
1704
+ summaryMode: "none",
1705
+ code: admission.code,
1706
+ });
1707
+ this.interaction.emit("command-response", {
1708
+ requestId,
1709
+ command: cmd,
1710
+ result: {
1711
+ messageCount: session.messages.length,
1712
+ error: admission,
1713
+ },
1714
+ });
1715
+ break;
1716
+ }
1717
+ }
1718
+
1315
1719
  const before = session.messages.length;
1316
1720
  const expectedMessages = [...session.messages];
1317
1721
  let result = null;
1318
1722
  let commandError = null;
1723
+ let compactionUsageCall = null;
1724
+ let compactionUsageSettled = false;
1319
1725
  try {
1320
1726
  this._sessionHostLease?.assert?.();
1321
1727
  result = await compactConversationWithProvider(session.messages, {
@@ -1332,19 +1738,47 @@ export class WSAgentHandler {
1332
1738
  cwd: session.projectRoot,
1333
1739
  sessionId: session.id,
1334
1740
  },
1741
+ ...(strictUsageTelemetry
1742
+ ? {
1743
+ onProviderCallStart: () => {
1744
+ const call = this._beginCanonicalCompactionUsage();
1745
+ compactionUsageCall = call;
1746
+ return call.callId;
1747
+ },
1748
+ }
1749
+ : {}),
1335
1750
  maxOutputTokens: session.compactionMaxOutputTokens,
1336
1751
  summaryInputMaxChars: session.compactionInputMaxChars,
1337
1752
  });
1753
+ if (compactionUsageCall) {
1754
+ this._settleCanonicalCompactionUsage(compactionUsageCall, result);
1755
+ compactionUsageSettled = true;
1756
+ }
1338
1757
  this._sessionHostLease?.assert?.();
1339
1758
  } catch (error) {
1759
+ if (
1760
+ compactionUsageCall &&
1761
+ !compactionUsageSettled &&
1762
+ error?.runtimeLedgerPersistence !== true
1763
+ ) {
1764
+ this._settleCanonicalCompactionFailure(compactionUsageCall);
1765
+ compactionUsageSettled = true;
1766
+ }
1340
1767
  if (isAbortError(error) || this._sessionHostLease?.signal?.aborted) {
1341
1768
  throw error;
1342
1769
  }
1343
- commandError = this._latchCompactionSettlement({
1344
- code: error?.code || "CC_COMPACTION_FAILED",
1345
- reason: `compaction_failed:${String(error?.message || error).slice(0, 240)}`,
1346
- commitState: "provider-outcome-unknown",
1347
- });
1770
+ commandError =
1771
+ error?.runtimeLedgerPersistence === true
1772
+ ? {
1773
+ code: USAGE_LEDGER_PERSISTENCE_CODE,
1774
+ reason: "canonical_usage_ledger_persistence_failed",
1775
+ commitState: "usage-ledger-failed",
1776
+ }
1777
+ : this._latchCompactionSettlement({
1778
+ code: error?.code || "CC_COMPACTION_FAILED",
1779
+ reason: `compaction_failed:${String(error?.message || error).slice(0, 240)}`,
1780
+ commitState: "provider-outcome-unknown",
1781
+ });
1348
1782
  this.interaction.emit("compaction-degraded", {
1349
1783
  requestId,
1350
1784
  reason: commandError.reason,