chainlesschain 0.163.6 → 0.163.8

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 (234) hide show
  1. package/package.json +2 -1
  2. package/src/assets/web-panel/assets/{AIOps-DDIUofA8.js → AIOps-CavM7W3k.js} +1 -1
  3. package/src/assets/web-panel/assets/{ActionButton-Bm-5xYRn.js → ActionButton-CUvZGabQ.js} +1 -1
  4. package/src/assets/web-panel/assets/{Analytics-D5UH4ljI.js → Analytics-DeBnWnbe.js} +3 -3
  5. package/src/assets/web-panel/assets/{AppLayout-D_ifjOOP.js → AppLayout-DbI5kxvd.js} +4 -4
  6. package/src/assets/web-panel/assets/{Artifacts-BY1mXdC7.js → Artifacts-D93bigKm.js} +1 -1
  7. package/src/assets/web-panel/assets/{Audit-Bujr4Ml3.js → Audit-CBNvfUZa.js} +1 -1
  8. package/src/assets/web-panel/assets/{BackgroundAgents-sioKSTcC.js → BackgroundAgents-CJLyh_YU.js} +1 -1
  9. package/src/assets/web-panel/assets/{Backup-DDOAK8RK.js → Backup-D_0yoehD.js} +1 -1
  10. package/src/assets/web-panel/assets/{BaseInput-CtCsVVke.js → BaseInput-TJxmbObW.js} +1 -1
  11. package/src/assets/web-panel/assets/{Chat-DpNj0vnd.js → Chat-CE0dto1q.js} +5 -5
  12. package/src/assets/web-panel/assets/{ChatBubbleRenderer-CZta3Ftr.js → ChatBubbleRenderer-CZ5-yYiD.js} +1 -1
  13. package/src/assets/web-panel/assets/{Checkbox-DoHVNSXq.js → Checkbox-Ck1RVIVo.js} +1 -1
  14. package/src/assets/web-panel/assets/{Codegen-DlVl7Qmv.js → Codegen-qpoyf6DK.js} +1 -1
  15. package/src/assets/web-panel/assets/{Col-GIqoPYty.js → Col-DUyPWjIE.js} +1 -1
  16. package/src/assets/web-panel/assets/{Community-CIAPEVji.js → Community-D_S1BemS.js} +1 -1
  17. package/src/assets/web-panel/assets/{Compact-BN7JiI_h.js → Compact-BjxeK-Gc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Compliance-CqUWCM9B.js → Compliance-Dd3CEJsu.js} +1 -1
  19. package/src/assets/web-panel/assets/{Cowork-A4iPp7A4.js → Cowork-B4QG7-ad.js} +3 -3
  20. package/src/assets/web-panel/assets/{Cron-B2zeXXWb.js → Cron-BtZnids5.js} +2 -2
  21. package/src/assets/web-panel/assets/{Crosschain-BR2xmWr8.js → Crosschain-CHPfCBFD.js} +1 -1
  22. package/src/assets/web-panel/assets/{DID-BzFDjrIv.js → DID-DT8DCEOK.js} +2 -2
  23. package/src/assets/web-panel/assets/{Dashboard-DKtDo3yA.js → Dashboard-COQab5_U.js} +2 -2
  24. package/src/assets/web-panel/assets/{Dropdown-RNx43_YG.js → Dropdown-BY1PsQuU.js} +1 -1
  25. package/src/assets/web-panel/assets/{EmailListRenderer-SwMt4Rcy.js → EmailListRenderer-CsuAuaq3.js} +1 -1
  26. package/src/assets/web-panel/assets/{FamilyGuardDashboard-CsYebZ4X.js → FamilyGuardDashboard-BqpinD-j.js} +1 -1
  27. package/src/assets/web-panel/assets/{Federation-BmRKvBTy.js → Federation-D0gkfQFv.js} +1 -1
  28. package/src/assets/web-panel/assets/{FormItemContext-CVxGTA-0.js → FormItemContext-BqgE-axK.js} +1 -1
  29. package/src/assets/web-panel/assets/{GenericCardRenderer-x2iXpyB7.js → GenericCardRenderer-D0hJ2KvC.js} +1 -1
  30. package/src/assets/web-panel/assets/{Git-DfqbkiOP.js → Git-CmMB0uPY.js} +2 -2
  31. package/src/assets/web-panel/assets/{Governance-RuHyyj5O.js → Governance-BnVEI0Dk.js} +1 -1
  32. package/src/assets/web-panel/assets/{Inference-Bn7uZ7rI.js → Inference-YTAMihRP.js} +1 -1
  33. package/src/assets/web-panel/assets/{KnowledgeGraph-DlP7XefZ.js → KnowledgeGraph-0ax7VHop.js} +1 -1
  34. package/src/assets/web-panel/assets/{Logs-BYNdOiCd.js → Logs-B9TRcokL.js} +2 -2
  35. package/src/assets/web-panel/assets/MarkdownRenderer-yySN5YNM.js +1 -0
  36. package/src/assets/web-panel/assets/{Marketplace-JQYmDqM8.js → Marketplace-B6CSuD_H.js} +1 -1
  37. package/src/assets/web-panel/assets/{McpTools-Cyx4yZ-9.js → McpTools-CjMXvOVU.js} +4 -4
  38. package/src/assets/web-panel/assets/{Memory-VDuGZTN2.js → Memory-CXRF71U3.js} +2 -2
  39. package/src/assets/web-panel/assets/{MobileBridge-_yKo97gi.js → MobileBridge-DQgNp_oS.js} +1 -1
  40. package/src/assets/web-panel/assets/{MobileProjects-CXRXW3q7.js → MobileProjects-DlPwcCbq.js} +1 -1
  41. package/src/assets/web-panel/assets/{Mtc-acTGtfLH.js → Mtc-6hDTRPe1.js} +5 -5
  42. package/src/assets/web-panel/assets/{MtcAudit-ClpjXfkY.js → MtcAudit-BlVHU1DS.js} +4 -4
  43. package/src/assets/web-panel/assets/{Multisig-_6Tn3o96.js → Multisig-DP9pzEbV.js} +3 -3
  44. package/src/assets/web-panel/assets/{NLProgramming-CK7pbZzP.js → NLProgramming-Djorh8EV.js} +1 -1
  45. package/src/assets/web-panel/assets/{Notes-Czy6V_P8.js → Notes-oLZ-JkUg.js} +4 -4
  46. package/src/assets/web-panel/assets/{NotificationSettings-Cqx-UVv3.js → NotificationSettings-Cg288VH3.js} +1 -1
  47. package/src/assets/web-panel/assets/{OrderTableRenderer-C69WDxGy.js → OrderTableRenderer-Bb1O3Ofr.js} +1 -1
  48. package/src/assets/web-panel/assets/{Organization-DFnA9vLQ.js → Organization-CBdo-bHs.js} +4 -4
  49. package/src/assets/web-panel/assets/{Overflow-ReZkk2yT.js → Overflow-qZdnVumx.js} +1 -1
  50. package/src/assets/web-panel/assets/{P2P-DzjSI0aI.js → P2P-D4kNfGNQ.js} +2 -2
  51. package/src/assets/web-panel/assets/PdhVaultBrowser-DnlMemM7.js +7 -0
  52. package/src/assets/web-panel/assets/{Permissions-DhQ5klhR.js → Permissions-DHucHFBJ.js} +3 -3
  53. package/src/assets/web-panel/assets/{PersonalDataHub-CUL1iHrW.js → PersonalDataHub-BovlOIPR.js} +4 -4
  54. package/src/assets/web-panel/assets/{Pipeline-DU88iu4N.js → Pipeline-Deru3CQY.js} +1 -1
  55. package/src/assets/web-panel/assets/{Privacy-Bw-sYfyK.js → Privacy-Bq5oTTbU.js} +1 -1
  56. package/src/assets/web-panel/assets/{ProjectInit-Bq3Q5y0z.js → ProjectInit-BfzxVWAz.js} +2 -2
  57. package/src/assets/web-panel/assets/{ProjectSettings-C8spzpho.js → ProjectSettings-CKC6XBtH.js} +2 -2
  58. package/src/assets/web-panel/assets/Projects-CMolGhae.js +1 -0
  59. package/src/assets/web-panel/assets/{Providers-Bf4eTP9W.js → Providers-C_jx4TWX.js} +1 -1
  60. package/src/assets/web-panel/assets/{QrScannerModal-Dme9BDU1.js → QrScannerModal-BdIHeVGC.js} +1 -1
  61. package/src/assets/web-panel/assets/{QuickAsk-CIXfv1rE.js → QuickAsk-BwZwAcPD.js} +1 -1
  62. package/src/assets/web-panel/assets/{Recommend-CIxvdeZ-.js → Recommend-BNTt0L-m.js} +1 -1
  63. package/src/assets/web-panel/assets/{RemoteSession-C6k7MExI.js → RemoteSession-Biyn2-Ro.js} +2 -2
  64. package/src/assets/web-panel/assets/{Reputation-CISDz2bl.js → Reputation-D6VpG32B.js} +1 -1
  65. package/src/assets/web-panel/assets/{Row-CdnDxXyf.js → Row-D_74OvQQ.js} +1 -1
  66. package/src/assets/web-panel/assets/{RssFeed-C-QpRHsl.js → RssFeed-BTr0a-BQ.js} +3 -3
  67. package/src/assets/web-panel/assets/{Search-DBjaGzSn.js → Search-C3MCFoNU.js} +1 -1
  68. package/src/assets/web-panel/assets/{Security-CQKukOeE.js → Security-CqW9aJ6s.js} +3 -3
  69. package/src/assets/web-panel/assets/{Services-DZz86jWb.js → Services-Cw5GNaHF.js} +2 -2
  70. package/src/assets/web-panel/assets/{Skeleton-jb8RMK0d.js → Skeleton-DZps5qeY.js} +1 -1
  71. package/src/assets/web-panel/assets/{Skills-CdY76fZG.js → Skills-C6NQ1znT.js} +1 -1
  72. package/src/assets/web-panel/assets/{Sla-C_CSiZX9.js → Sla-DFP8G2Sh.js} +1 -1
  73. package/src/assets/web-panel/assets/SpeechSettings-ESt6MB6v.js +1 -0
  74. package/src/assets/web-panel/assets/{SyncSettings-qvimGO0O.js → SyncSettings-BHnN98aM.js} +2 -2
  75. package/src/assets/web-panel/assets/{Tasks-Dng5LPJC.js → Tasks-NiSCaOf-.js} +1 -1
  76. package/src/assets/web-panel/assets/{Templates-Bwqq5Wll.js → Templates-DsKFhW2C.js} +1 -1
  77. package/src/assets/web-panel/assets/{Tenant-DNWuwP7Z.js → Tenant-CQ0E0ze5.js} +1 -1
  78. package/src/assets/web-panel/assets/{Terminal-B-6Othpp.js → Terminal-D_rBu_by.js} +2 -2
  79. package/src/assets/web-panel/assets/{TimelineRenderer-DKpKZfzx.js → TimelineRenderer-D3Vm4Po4.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tokens-DzfGMd2J.js → Tokens-DNTxRH6q.js} +1 -1
  81. package/src/assets/web-panel/assets/{Trigger-BXwUi74J.js → Trigger-Dgprz1ms.js} +1 -1
  82. package/src/assets/web-panel/assets/{Trust-BNzUq4ui.js → Trust-B2rUnVBD.js} +1 -1
  83. package/src/assets/web-panel/assets/{UkeySign-BYugxww4.js → UkeySign-DEGQNc6_.js} +1 -1
  84. package/src/assets/web-panel/assets/{VideoEditing-DdauhtSJ.js → VideoEditing-jlsAx3Eh.js} +1 -1
  85. package/src/assets/web-panel/assets/{Wallet-CSC9bCe_.js → Wallet-8jQih1ij.js} +4 -4
  86. package/src/assets/web-panel/assets/{WebAuthn-Q8AN3bTO.js → WebAuthn-XLeO6xIB.js} +5 -5
  87. package/src/assets/web-panel/assets/{WorkflowEditor-d-LBGCuA.js → WorkflowEditor-De_dgDAG.js} +1 -1
  88. package/src/assets/web-panel/assets/{chat-BLVDCgsZ.js → chat-CI19R_Sk.js} +1 -1
  89. package/src/assets/web-panel/assets/{colors-BZlPSEHl.js → colors-DsYTOYN3.js} +1 -1
  90. package/src/assets/web-panel/assets/{compact-item-IWseP6R6.js → compact-item-CM3-t_Qr.js} +1 -1
  91. package/src/assets/web-panel/assets/{createContext-DnVRV3Ao.js → createContext-BjxlBRZv.js} +1 -1
  92. package/src/assets/web-panel/assets/devWarning-S1ld2LwU.js +1 -0
  93. package/src/assets/web-panel/assets/{hasIn-DLQZA_Wn.js → hasIn-RDaWX_4i.js} +1 -1
  94. package/src/assets/web-panel/assets/{index-BSjilZ9L.js → index-9R6BxAr0.js} +1 -1
  95. package/src/assets/web-panel/assets/{index-B_N4-Gq9.js → index-B-Z8eFUJ.js} +1 -1
  96. package/src/assets/web-panel/assets/{index-Dy0R5ZED.js → index-B0PMlbMs.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-C1ifZtXo.js → index-B5REnKt8.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-CINJQEj6.js → index-B7WBt_4T.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-DocEhinm.js → index-B9O9YyWE.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DjWnONdy.js → index-BCnZyIMA.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-hwVDeoC0.js → index-BGqqJfL0.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-Bbj2NS_I.js → index-BHNYPO0b.js} +3 -3
  103. package/src/assets/web-panel/assets/{index-C5dgnilC.js → index-BKJr-TZp.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-CT9vVN-X.js → index-BN6UPD2E.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-DpVrK6fr.js → index-Bi46Xu4u.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-CpBaJ3TD.js → index-BlT2VAEK.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-1jeAudHd.js → index-C0yx-jtQ.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-DOoQpuQY.js → index-C4gkzxkw.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-DZpYeqrh.js → index-CVQMeiwH.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BhA3QEni.js → index-Cd3euP_4.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-N_GoWZX4.js → index-Cd9OJhHG.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-BOZJBTWZ.js → index-CiECJi-Q.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-CarMTIyQ.js → index-CjTrRt13.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-CZDekj7T.js → index-CnHH7bnD.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-M7wxfAbm.js → index-Cpqm1qfU.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-Bxp7uDD8.js → index-CyOGN6a5.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DalA0TKC.js → index-D0zcy54x.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-COev0W2g.js → index-D6sm5-Xq.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DUq0c7gq.js → index-DIUnNOjG.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-BZs5bBnk.js → index-DX7tuWVJ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CbQNL0ue.js → index-DXXtGMUJ.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-DTbxp4UH.js → index-DcPFB8qJ.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-YSw_gxlZ.js → index-DoQA0-52.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-D_LQodeJ.js → index-Drlnwr8F.js} +1 -1
  125. package/src/assets/web-panel/assets/index-Drz6yq0m.js +1 -0
  126. package/src/assets/web-panel/assets/{index-jWb70ZgZ.js → index-Dsij_KsN.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DB0MJgF_.js → index-Dxge-xWl.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BEu2lMBy.js → index-DyIWssPC.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-C2FqfMvU.js → index-IeiL9RKc.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-Dkwsi1Kn.js → index-nAH87mQP.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-gt8bNefW.js → index-pPL66J85.js} +1 -1
  132. package/src/assets/web-panel/assets/index-uWiUs7S_.js +1 -0
  133. package/src/assets/web-panel/assets/{initDefaultProps-Co67Kqmb.js → initDefaultProps-BTL88of4.js} +1 -1
  134. package/src/assets/web-panel/assets/{motion-BMOxQSF_.js → motion-BUB2pXwB.js} +1 -1
  135. package/src/assets/web-panel/assets/{move-C5fWDw-N.js → move-egCkkOMm.js} +1 -1
  136. package/src/assets/web-panel/assets/{mtc-parser-BJevpL0e.js → mtc-parser-DAWhZC8c.js} +1 -1
  137. package/src/assets/web-panel/assets/{omit-BCzNU8s6.js → omit-CvOxe_6d.js} +1 -1
  138. package/src/assets/web-panel/assets/{pickAttrs-CybWvDPk.js → pickAttrs-DZUSLZ5Z.js} +1 -1
  139. package/src/assets/web-panel/assets/{placementArrow-BMWS9HnW.js → placementArrow-BERxGNMY.js} +1 -1
  140. package/src/assets/web-panel/assets/{responsiveObserve-BoL2UnGY.js → responsiveObserve-DZuDfZ9n.js} +1 -1
  141. package/src/assets/web-panel/assets/{slide-DWNfXraU.js → slide-DO756sgI.js} +1 -1
  142. package/src/assets/web-panel/assets/{statusUtils-BquTM3tX.js → statusUtils-BRQlIz28.js} +1 -1
  143. package/src/assets/web-panel/assets/{styleChecker-BEkCleim.js → styleChecker-DCSfdybl.js} +1 -1
  144. package/src/assets/web-panel/assets/{useFlexGapSupport-Oecnq7EA.js → useFlexGapSupport-LD8dWVve.js} +1 -1
  145. package/src/assets/web-panel/assets/{useFs-CkDffJ4F.js → useFs-BX9uW2LK.js} +1 -1
  146. package/src/assets/web-panel/assets/{usePersonalDataHub-qbvKXesB.js → usePersonalDataHub-BPSlPuHU.js} +1 -1
  147. package/src/assets/web-panel/assets/{vnode-C6v8n6mA.js → vnode-BmOILC9V.js} +1 -1
  148. package/src/assets/web-panel/assets/{zoom-4CTeFILV.js → zoom-1iKowKGg.js} +1 -1
  149. package/src/assets/web-panel/index.html +1 -1
  150. package/src/command-help-index.json +5 -5
  151. package/src/commands/agent.js +90 -1
  152. package/src/commands/automation.js +103 -1
  153. package/src/commands/chat.js +11 -2
  154. package/src/commands/compact.js +106 -23
  155. package/src/commands/loop.js +28 -10
  156. package/src/commands/routine.js +1 -1
  157. package/src/commands/scheduler-daemon.js +359 -2
  158. package/src/commands/session-observability.js +305 -0
  159. package/src/commands/session.js +38 -0
  160. package/src/commands/team-merge-review.js +937 -0
  161. package/src/commands/team.js +2 -0
  162. package/src/data/changelog.json +27 -1
  163. package/src/gateways/ws/ws-agent-handler.js +439 -5
  164. package/src/harness/jsonl-session-store.js +463 -125
  165. package/src/harness/prompt-compressor.js +86 -13
  166. package/src/harness/provider-backed-compaction.js +100 -27
  167. package/src/lib/advisor-runtime.js +3 -1
  168. package/src/lib/agent-schedule-store.js +549 -28
  169. package/src/lib/agent-team/team-adjudication.js +40 -1
  170. package/src/lib/agent-team/team-merge-review-store.js +765 -0
  171. package/src/lib/agent-team/team-merge-review-transaction.js +1223 -0
  172. package/src/lib/agent-team/team-merge-review.js +1847 -0
  173. package/src/lib/automation-center-incidents.js +314 -0
  174. package/src/lib/automation-center-runtime.js +448 -0
  175. package/src/lib/automation-center.js +182 -38
  176. package/src/lib/automation-engine.js +535 -0
  177. package/src/lib/automation-execution-authority.js +241 -12
  178. package/src/lib/automation-execution-incident.js +737 -0
  179. package/src/lib/background-agent-supervisor.js +793 -215
  180. package/src/lib/background-command-argv.js +24 -0
  181. package/src/lib/background-interaction-journal.js +361 -52
  182. package/src/lib/background-interaction-resolver.js +32 -0
  183. package/src/lib/background-launch-profile.js +2 -0
  184. package/src/lib/causal-observability.js +2661 -0
  185. package/src/lib/chat-session-admission.js +76 -0
  186. package/src/lib/cost-budget.js +5 -7
  187. package/src/lib/cowork/ab-comparator-cli.js +11 -0
  188. package/src/lib/cowork/debate-review-cli.js +12 -0
  189. package/src/lib/cowork-adapter.js +159 -38
  190. package/src/lib/cowork-cron.js +442 -15
  191. package/src/lib/cowork-task-runner.js +112 -17
  192. package/src/lib/delivery-coordinator.js +142 -0
  193. package/src/lib/direct-model-usage.js +121 -0
  194. package/src/lib/file-lines.js +183 -47
  195. package/src/lib/llm-pricing.js +12 -17
  196. package/src/lib/loop.js +26 -2
  197. package/src/lib/routine-store.js +380 -21
  198. package/src/lib/runtime-usage-ledger.js +182 -0
  199. package/src/lib/scheduler-kernel/agenda-adapter.js +325 -10
  200. package/src/lib/scheduler-kernel/automation-adapter.js +514 -18
  201. package/src/lib/scheduler-kernel/automation-event-adapter.js +123 -11
  202. package/src/lib/scheduler-kernel/contract.js +91 -0
  203. package/src/lib/scheduler-kernel/cowork-cron-adapter.js +297 -4
  204. package/src/lib/scheduler-kernel/loop-adapter.js +547 -6
  205. package/src/lib/scheduler-kernel/migration-admin.js +346 -0
  206. package/src/lib/scheduler-kernel/migration-rollback-admin.js +932 -0
  207. package/src/lib/scheduler-kernel/routine-adapter.js +400 -20
  208. package/src/lib/scheduler-kernel/runtime-control-capabilities.js +31 -0
  209. package/src/lib/scheduler-kernel/runtime.js +237 -2
  210. package/src/lib/scheduler-kernel/source-locator-path.js +142 -0
  211. package/src/lib/scheduler-kernel/store.js +3957 -248
  212. package/src/lib/session-host-lease.js +171 -2
  213. package/src/lib/session-host-snapshot.js +14 -3
  214. package/src/lib/session-persistence-failure.js +1 -0
  215. package/src/lib/session-tail.js +179 -34
  216. package/src/lib/session-transcript-structure.js +96 -0
  217. package/src/lib/sub-agent-context.js +328 -22
  218. package/src/lib/ws-agent-handler.js +4 -1
  219. package/src/repl/agent-repl.js +732 -91
  220. package/src/repl/chat-repl.js +5 -1
  221. package/src/runtime/agent-core.js +1282 -207
  222. package/src/runtime/fallback-model.js +5 -0
  223. package/src/runtime/headless-runner.js +324 -82
  224. package/src/runtime/headless-stream.js +232 -26
  225. package/src/runtime/mcp-config.js +81 -10
  226. package/src/runtime/policies/agent-policy.js +4 -0
  227. package/src/workers/background-agent-worker.js +403 -96
  228. package/src/assets/web-panel/assets/MarkdownRenderer-aMtgN-R6.js +0 -1
  229. package/src/assets/web-panel/assets/PdhVaultBrowser-DKTf5xIP.js +0 -7
  230. package/src/assets/web-panel/assets/Projects-Dd-xuPIc.js +0 -1
  231. package/src/assets/web-panel/assets/SpeechSettings-C7tT9iad.js +0 -1
  232. package/src/assets/web-panel/assets/devWarning-Jzu62CLC.js +0 -1
  233. package/src/assets/web-panel/assets/index-Zb2MeDSy.js +0 -1
  234. package/src/assets/web-panel/assets/index-fikqml4k.js +0 -1
@@ -57,6 +57,7 @@ import {
57
57
  } from "../lib/agent-team/team-control-store.js";
58
58
  import { TeamProcessCheckpointBroker } from "../lib/agent-team/team-process-checkpoint.js";
59
59
  import { registerTeamDistributedCommands } from "./team-distributed.js";
60
+ import { registerTeamMergeReviewCommands } from "./team-merge-review.js";
60
61
  import {
61
62
  sameFileStatIdentity,
62
63
  samePathHandleFileIdentity,
@@ -1451,6 +1452,7 @@ export function registerTeamCommand(program, { logger } = {}) {
1451
1452
  agentExecutor: spawnAgent,
1452
1453
  buildAgentPrompt: buildTeamAgentPrompt,
1453
1454
  });
1455
+ registerTeamMergeReviewCommands(team, { logger: log });
1454
1456
 
1455
1457
  team
1456
1458
  .command("control-bindings")
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.163.8",
7
+ "cliVersions": ["0.163.7", "0.163.8"],
8
+ "date": "2026-08-14",
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Added — cc CLI 0.163.8: governed recovery, merge review, and MCP resource templates",
13
+ "body": "> `chainlesschain` **0.163.7 → 0.163.8** (candidate; not yet published,\n> 2026-08-14).\n> CLI-only candidate; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Crash-safe scheduler source persistence**: Agenda and Cowork authoritative\n stores now reject unreadable, malformed, and non-object records instead of\n treating them as empty state. Generation replacement uses private exclusive\n temporary files, complete short-write loops, file fsync, atomic rename, and\n POSIX directory fsync, while distinguishing pre-rename `not-committed`\n failures from post-rename durability-unknown outcomes.\n- **Deterministic scheduler disk-fault closure**: fault injection covers ENOSPC,\n partial writes, file and directory fsync failures, rename failures, corrupted\n source stores, native SQLite `SQLITE_FULL` transaction rollback, Automation\n source rollback atomicity, database truncation, and clean reopen behavior.\n Routine and Loop retain their existing durable-store and append/CAS\n protections.\n- **Governed Automation runtime recovery**: scheduler-backed Automation work can\n expose exact-fence, control-revision, capability-bound pause and resume safe\n points. Revisioned incidents support bounded retry or cancellation; retry\n revalidates the exact dead-letter occurrence, run identity, fence, and error\n evidence, while manual incidents are not silently replayed.\n- **Governed multi-agent merge review**: `cc team merge-review` subcommands\n `preview|show|apply|rollback` provide stable file and hunk selection,\n digest-bound decisions, durable conflict evidence, guarded cross-branch batch\n publication, and retained-history rollback. Git hooks, repository-local\n configuration, inherited environment, stale revisions, oversized selections,\n and changed branch identities fail closed.\n- **Read-only MCP resource templates**: templates-only MCP servers can now\n register the existing resource surface. The new\n `list_mcp_resource_templates {server?}` tool reads the bounded discovery\n cache, supports explicit server filtering, and lets the model instantiate a\n concrete URI before using the existing `read_mcp_resource` boundary. It does\n not add an implicit network request, subscription, or automatic URI\n expansion.\n- **Explicit optional-protocol decisions**: resource templates enter the\n production read-only surface; resource subscriptions, peer-controlled\n logging, and completion remain deferred pending bounded consumers and\n cancellation/recovery UX. MCP sampling remains undeclared and server\n `createMessage` requests continue to return JSON-RPC `-32601`.\n- **Transaction-time scheduler fencing**: claim, renewal, and settlement paths\n now read their lease clock inside the write transaction, preventing queue\n wait time from turning a pre-transaction timestamp into a stale lease or\n settlement decision.\n- **Formal scheduler soak evidence gate**: Linux, Windows, and macOS workflows\n now exercise two-worker contention, lease/fence recovery, heartbeat renewal,\n stale settlement rejection, outcome-unknown no-replay, DST/backlog behavior,\n SQLite integrity, descendant cleanup, and bounded resource trends. The\n campaign verifier requires at least four identity-bound formal segments whose\n authoritative starts span at least 72 natural hours, with no gap above\n 30 hours.\n- **Release boundary**: the scheduler soak implementation and smoke matrices are\n present, but the required 72-hour formal campaign has not completed; P2-4\n therefore remains partially complete. Signed native distribution,\n representative alias-removal telemetry, and the entire unmerged P2-2 native\n clipboard-image host work remain outside this candidate.\n- **Release status**: final tag, source SHA, workflow run IDs, package digests,\n provenance, and registry readback are intentionally omitted until the exact\n `0.163.8` release merge commit passes complete `CLI CI` and\n `CLI Strict Sandbox` matrices on Linux, Windows, and macOS, followed by the\n dedicated npm release and independent public readback workflows."
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "productVersion": null,
19
+ "cliVersion": "0.163.7",
20
+ "cliVersions": ["0.163.6", "0.163.7"],
21
+ "date": "2026-08-14",
22
+ "title": "",
23
+ "sections": [
24
+ {
25
+ "heading": "Added — cc CLI 0.163.7: governed scheduler migration and causal observability",
26
+ "body": "> `chainlesschain` **0.163.6 → 0.163.7** (published from exact SHA\n> `3e997168621c53708a1682868c6cc4edc9baf15b`, 2026-08-14).\n> CLI-only release; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Five-domain migration journal**: Agenda, Cowork Cron, Routine, Automation,\n and Loop migrations use the scheduler store schema-v5 journal with\n domain-typed source locators, immutable source/target digest bindings,\n idempotent recovery, and fail-closed rejection of conflicting or ambiguous\n legacy entries.\n- **Governed rollback controls**: the new scheduler migration `list`, `show`,\n and `rollback` commands expose redacted migration status and blockers.\n Rollback requires the latest evidence digest, an interactive TTY, and the\n exact typed challenge before reopening any legacy source.\n- **Target-first recovery and CAS fencing**: rollback stops or restores the\n scheduler target before restoring the legacy source, validates target\n revision, definition and execution evidence, and makes terminal source\n restoration retry-safe across process crashes. This is not a claim of one\n atomic transaction across independent stores or filesystems.\n- **Fail-closed source identity**: Windows drive and UNC paths are canonicalized\n while relative, incomplete and device-namespace paths are rejected.\n Automation migration requires an existing native SQLite database and refuses\n the non-durable sql.js fallback; Loop restoration remains bound to its durable\n retirement fence, marker and original source digest.\n- **Windows persistence hardening**: team adjudication atomic replacement\n retries only transient Windows `EACCES`, `EBUSY`, and `EPERM` sharing\n failures with bounded backoff and authority-path revalidation. Exhausted,\n non-transient, and non-Windows replacement failures continue to fail closed.\n- **Cross-platform CI hardening**: migration fixtures verify retirement fences\n and canonical source identities consistently across operating systems, while\n distributed-queue and authority test workers use bounded lifetimes and attach\n result observers before short-lived children can exit. Terminal Skill\n authority fixtures now use an explicit parent acknowledgement before clean\n exit, removing Windows IPC exit-before-message ordering ambiguity without\n weakening concurrent revocation assertions.\n- **Verified causal delivery reports**: scoped sessions can be bound by exact\n transcript head and event count to digest-protected delivery states. The new\n session observability commands export a redacted session-to-delivery graph\n spanning diffs, gates, artifacts, pull requests, and merges, with exact\n workspace, team, and policy filters.\n- **Fail-closed call-ledger budgets**: `call-ledger@1` brackets model, retry,\n compaction, subagent, isolated-skill, and tool calls with known or unknown\n settlements. Strict budget mode rejects exceeded and unevaluable results\n instead of treating missing token, cost, retry, or tool-latency evidence as\n zero.\n- **Background recovery authority hardening**: verified transcript CAS,\n delegated recovery leases, IPC sender/nonce binding, bootstrap guards, exact\n process-group termination checks, and terminal cleanup prevent uncertain or\n still-live descendants from authorizing recovery or worktree deletion.\n- **Causal evidence boundary**: report bindings prove exact verified revisions,\n not that a model call semantically caused a source hunk. Scope labels are not\n identity or membership proofs, digests are not signatures, anti-rollback is\n machine-local, and incomplete or legacy ledgers remain partial or unknown.\n- **Release boundary**: deterministic scheduler disk-fault closure landed after\n this immutable release and is not attributed to its tarball. The\n three-platform long-soak campaign, signed native distribution, and\n representative alias-removal telemetry remained outside this release.\n- **Published release evidence**: immutable tag `v-npm-0-163-7` resolves to\n exact source commit `3e997168621c53708a1682868c6cc4edc9baf15b`. Its Linux,\n Windows, and macOS `CLI CI` (`31745391661`, attempt 2) and\n `CLI Strict Sandbox` (`31745391321`) matrices passed; the dedicated npm\n release (`31748153519`) completed its exact-SHA gate, immutable package,\n Trusted Publishing, and signed provenance, and the independent public\n readback (`31749404980`) succeeded. npm reports `latest=0.163.7`; the public\n tarball SHA-1 is `5bfb7471643cfe4d4cd0b0a382b31c63fc1efdff` and SHA-256 is\n `d7ca295e6cdb4e442ee7ad6bb9cc0b9d923f40de4eae395974d91b4dfab83a9d`."
27
+ }
28
+ ]
29
+ },
4
30
  {
5
31
  "productVersion": null,
6
32
  "cliVersion": "0.163.6",
@@ -10,7 +36,7 @@
10
36
  "sections": [
11
37
  {
12
38
  "heading": "Added — cc CLI 0.163.6: unified scheduler authority and automation control",
13
- "body": "> `chainlesschain` **0.163.5 → 0.163.6** (candidate; not yet published,\n> 2026-08-12).\n> CLI-only candidate; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Complete scheduler adapter migration**: Agenda monitors, Loop iterations,\n Automation cron flows, Routine GitHub polling, channel automation events,\n and the standalone daemon now execute through the shared scheduler service\n with durable claims, definition snapshots, recovery fences, and bounded\n retry/dead-letter behavior.\n- **Timezone and missed-run consistency**: Agenda and Cowork cron definitions\n persist canonical IANA timezones, handle DST gaps and repeated civil times,\n and collapse downtime to one latest due occurrence without replay storms.\n- **Shared scheduler permission and budget authority**: Agenda, Routine,\n Cowork, Automation, and Loop bind exact capability policies to durable\n revisions and use one transactional reservation/settlement path. Missing,\n stale, disabled, exhausted, or inconsistent policy state fails closed;\n retries reuse the original reservation instead of charging twice.\n- **Layered Automation enforcement**: the shared scheduler authority composes\n with Automation's creator identity, connector permissions, live revocation,\n and per-flow run/action budgets. Domain evidence and the scheduler policy\n revision remain independently validated.\n- **Governed management surfaces**: scheduler policy inspection/update commands\n require exact capabilities and revision CAS, while the Automation Center\n exposes governed flow and Routine controls without bypassing backend\n permission or budget checks.\n- **Known residuals**: durable outcome-unknown adjudication, complete mixed-\n version migration/rollback, scheduler disk-fault closure, and the three-OS\n long-soak matrix remain open. Signed native distribution and representative\n alias-removal telemetry also remain outside this release.\n- **Release status**: final tag, source SHA, workflow run IDs, package digest,\n provenance, and registry readback are intentionally omitted until the exact\n `0.163.6` release commit passes the complete `CLI CI` and `CLI Strict Sandbox`\n Linux, Windows, and macOS matrices, followed by the dedicated npm release and\n independent public readback workflows."
39
+ "body": "> `chainlesschain` **0.163.5 → 0.163.6** (published from exact SHA\n> `85c3577c887003fea98d0a159603cd359506f09b`, 2026-08-12).\n> CLI-only release; `@chainlesschain/personal-data-hub` remains **0.4.57**\n> and `@chainlesschain/agent-sdk` remains **0.1.7**.\n\n- **Complete scheduler adapter migration**: Agenda monitors, Loop iterations,\n Automation cron flows, Routine GitHub polling, channel automation events,\n and the standalone daemon now execute through the shared scheduler service\n with durable claims, definition snapshots, recovery fences, and bounded\n retry/dead-letter behavior.\n- **Timezone and missed-run consistency**: Agenda and Cowork cron definitions\n persist canonical IANA timezones, handle DST gaps and repeated civil times,\n and collapse downtime to one latest due occurrence without replay storms.\n- **Shared scheduler permission and budget authority**: Agenda, Routine,\n Cowork, Automation, and Loop bind exact capability policies to durable\n revisions and use one transactional reservation/settlement path. Missing,\n stale, disabled, exhausted, or inconsistent policy state fails closed;\n retries reuse the original reservation instead of charging twice.\n- **Layered Automation enforcement**: the shared scheduler authority composes\n with Automation's creator identity, connector permissions, live revocation,\n and per-flow run/action budgets. Domain evidence and the scheduler policy\n revision remain independently validated.\n- **Governed management surfaces**: scheduler policy inspection/update commands\n require exact capabilities and revision CAS, while the Automation Center\n exposes governed flow and Routine controls without bypassing backend\n permission or budget checks.\n- **Known residuals**: durable outcome-unknown adjudication, complete mixed-\n version migration/rollback, scheduler disk-fault closure, and the three-OS\n long-soak matrix remain open. Signed native distribution and representative\n alias-removal telemetry also remain outside this release.\n- **Published release evidence**: immutable tag `v-npm-0-163-6` resolves to\n exact source commit `85c3577c887003fea98d0a159603cd359506f09b`. Its Linux,\n Windows, and macOS `CLI CI` (`31595865423`) and `CLI Strict Sandbox`\n (`31595865206`) matrices passed; the dedicated npm release (`31595865181`)\n completed its exact-SHA gate, immutable package, Trusted Publishing, and\n signed provenance, and the independent public readback (`31597577056`)\n succeeded. npm reports `latest=0.163.6`; the public tarball SHA-1 is\n `18bb9d807a4a35a36cf9049dcc15f67eb47bbfa6`."
14
40
  }
15
41
  ]
16
42
  },
@@ -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,