chainlesschain 0.166.103 → 0.166.104

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 (178) hide show
  1. package/package.json +1 -1
  2. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  3. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  4. package/src/assets/web-panel/assets/{AIOps-BLrXpdnP.js → AIOps-Bah3HREy.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-C0xy9uFy.js → ActionButton-DY2aeZMc.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-C6EephQP.js → Analytics-BFly8Xaa.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-ZCXdOD9y.js → AppLayout-dp0Zz-JM.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-D4MfZ-pl.js → Artifacts-DcIg09ai.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-BQ8c3bBu.js → Audit-DkN-lsjZ.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-BOA7_ljM.js → BackgroundAgents-BjzgusLx.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-60uiQjGT.js → Backup-CU8S6qu9.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-BDvEbGs_.js → BaseInput-B1pC2gjL.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-B3IkAuFQ.js → Chat-B6xFp6gD.js} +5 -5
  14. package/src/assets/web-panel/assets/ChatBubbleRenderer-DxNCLZ_X.js +1 -0
  15. package/src/assets/web-panel/assets/{Checkbox-njGbfJWq.js → Checkbox-QHw7Vc4U.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-CF7DtdxC.js → Codegen-gdecsfjg.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-C_3Zix40.js → Col-B0_JmAmc.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-CzU-ZC2d.js → Community-DRCcP5xR.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-BgeqsPRh.js → Compact-DZtoGzhX.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-6l7cwiqp.js → Compliance-BfNTvEnT.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-D4s905fI.js → Cowork-CDXTLm84.js} +3 -3
  22. package/src/assets/web-panel/assets/{Cron-CGTYSxRS.js → Cron-Big35CbN.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-BnSo-Yt3.js → Crosschain-C8ArrAVr.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-Dm4vk2X1.js → DID-D_77BI2O.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-D7H-PZ_N.js → Dashboard-D2SxTzEp.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-COslkgxn.js → Dropdown-mR1-b9ud.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-CJWEetmk.js → EmailListRenderer-DPl7TE1c.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-BbzebAWe.js → EvolutionSettings-BxRYLRSH.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-BsoTOXwk.js → FamilyGuardDashboard-rnGtXJ5Z.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-Ck5kM_5H.js → Federation-BpxenYK8.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-gShxCqtF.js → FormItemContext-Cz1kDf6l.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-DarN1G-z.js → GenericCardRenderer-CGV3KN6U.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-CJfpLyP5.js → Git-CIRP4UTx.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-CVcJmpQz.js → Governance-DX4r8Vmt.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-ComU_ig8.js → Inference-DQKk02Hl.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-35hprFJy.js → KnowledgeGraph-DdD6J-By.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-BQDqBTz0.js → Logs-DA2w-1_m.js} +2 -2
  38. package/src/assets/web-panel/assets/{MarkdownRenderer-BpdGAVCC.js → MarkdownRenderer-C9aSGETh.js} +1 -1
  39. package/src/assets/web-panel/assets/{Marketplace-B9O9OKnn.js → Marketplace-BsJ6_6KW.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-VMKxA4Wc.js → McpTools-_6k30z6u.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-CcBbf3Bc.js → Memory-C0_dYY0A.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-D7myz46N.js → MobileBridge-CCTnVqiC.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-Da5KBXyx.js → MobileProjects-RZdxDSwC.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-x3NPZfuL.js → Mtc-D4Ys8lvX.js} +5 -5
  45. package/src/assets/web-panel/assets/{MtcAudit-CwnzptEC.js → MtcAudit-BKTC--a2.js} +2 -2
  46. package/src/assets/web-panel/assets/{Multisig-CCAxf4Ye.js → Multisig-CGR1qOe1.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-CptHKz-Q.js → NLProgramming-hKKD4qWb.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-0uEp4DCJ.js → Notes-pCn7Ec40.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-DthvrOLd.js → NotificationSettings-B9eEJXEs.js} +1 -1
  50. package/src/assets/web-panel/assets/OrderTableRenderer-CmJuhaT2.js +1 -0
  51. package/src/assets/web-panel/assets/{Organization-BWf2tmQQ.js → Organization-CcQbrnwW.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-BbvAtEth.js → Overflow-HmD4Mn72.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-zBo6enit.js → P2P-B7LIgx5H.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-D_LMQ4A4.js → PdhVaultBrowser-CXiHnBfX.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-C1ucb2ck.js → Permissions-CQRI3y_l.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-Bz64RddJ.js → PersonalDataHub-1EeHmsy5.js} +5 -5
  57. package/src/assets/web-panel/assets/{Pipeline-DXJt3y3_.js → Pipeline-BFyoIdn8.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-DiZ8b_ut.js → Privacy-BxWthXMF.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-DfLKKrJ4.js → ProjectInit-DfigBilu.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-Ct6kJuIY.js → ProjectSettings-CFmIcVc-.js} +2 -2
  61. package/src/assets/web-panel/assets/{Projects-BBUMlZ3m.js → Projects-CR7H59v3.js} +1 -1
  62. package/src/assets/web-panel/assets/{Providers-DYVQPHvc.js → Providers-2ulom-76.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-23Il7iPp.js → QrScannerModal-BwhO07b_.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-WgOZKrv1.js → QuickAsk-_Wg34OwF.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-CRIka6xT.js → Recommend-D_jq6Svg.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-DOy3GjVZ.js → RemoteSession-BlzvEfsa.js} +2 -2
  67. package/src/assets/web-panel/assets/{Reputation-BXyi6xeR.js → Reputation-9CTXHfL4.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-CoMxuIcR.js → Row-DlCYCN-t.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-87hPkoM6.js → RssFeed-BvlInFCH.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-B1EqFCO4.js → Search-CfaUzKuL.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-HcC41eGs.js → Security-bAWgLyve.js} +3 -3
  72. package/src/assets/web-panel/assets/{Services-BqLwmvCM.js → Services-C4LOGACW.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-CIMmjW4r.js → Skeleton-Dd0Uwh3_.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-CgurezJU.js → Skills-ZYF1kYCU.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-CJuRuqPE.js → Sla-DpsmIaEo.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-BUwsbd1o.js → SpeechSettings-BBXoJ4yc.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-qo04TOX-.js → SyncSettings-SOnROi2Y.js} +2 -2
  78. package/src/assets/web-panel/assets/Tasks-HFA_ZlDk.js +1 -0
  79. package/src/assets/web-panel/assets/{Templates-D1PTczPW.js → Templates-fsK-RCEc.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-Bi0FkEPR.js → Tenant-CuqYxamb.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-DfSt3bIF.js → Terminal-GKlI2R5F.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-B7bIVs4R.js → TimelineRenderer-DMDMHLeY.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-B6w5XrMb.js → Tokens-BoV60rh3.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-XXVSDWiF.js → Trigger-CE344-Ws.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-DYvlgcK-.js → Trust-DENwgkVc.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-XyYwJMBM.js → UkeySign-FrcM7yfm.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-C47WbtHH.js → VideoEditing-DAY9WaC2.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-CYfqTj_C.js → Wallet-BuUR5i82.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-3AduFn1l.js → WebAuthn-nfSQuq85.js} +3 -3
  90. package/src/assets/web-panel/assets/{WorkflowEditor-DHYEHjMJ.js → WorkflowEditor-DHhPOp9l.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-AeehErSw.js → chat-C4nsLzYy.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-DKXJ8paX.js → colors-BwXH0Wjn.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-BOlCiomD.js → compact-item-uApFG30S.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-BAP6U85b.js → createContext-BpyYs4fe.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-Bk6HGn3N.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-BLmeL1Xe.js → hasIn-MXCLi00p.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-CdNSmvog.js → index-1LxX2IwJ.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-Dv8-g1pY.js → index-61CBBrHE.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-ClpwxOXo.js → index-B0P1Z_oa.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CgtaOzMo.js → index-B7jojVc7.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BRcJlKSa.js → index-BEGMfaOo.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-wyKpTsGM.js → index-BOhjapd5.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-BuUwKmEI.js → index-BaBwXpAp.js} +1 -1
  104. package/src/assets/web-panel/assets/index-Bb1LPYdi.js +1 -0
  105. package/src/assets/web-panel/assets/{index-Co7pjF53.js → index-Btv--Nnt.js} +1 -1
  106. package/src/assets/web-panel/assets/index-C-FsTuFG.js +1 -0
  107. package/src/assets/web-panel/assets/{index-CFKzWIo8.js → index-CF0bUOP4.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CaHhfpBi.js → index-CNjUPfJP.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-ZMbXl5lo.js → index-CRmNdEk_.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BTnp4Nt3.js → index-C_oOpXhP.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-OLKhib9T.js → index-ChUTKrOq.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-T28naovw.js → index-CiIpIYhs.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-Bpx54vfs.js → index-CwVvk2i7.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-BAS2QqLn.js → index-D3_tj06B.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-CRa4pAaM.js → index-DE4W4vLO.js} +3 -3
  116. package/src/assets/web-panel/assets/{index-BSOenF5s.js → index-DLxKx5_J.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-DE7cbDDe.js → index-DTXi_gQh.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DWYqOI1A.js → index-Daco83me.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-DQLQuwpA.js → index-DffWVpZv.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-CiqeF0Pf.js → index-Dkncxel3.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-IlzfIRNh.js → index-Dn12gJJU.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Bn54FU3i.js → index-Dt-nq2eF.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-Bt-FCVzh.js → index-Du01X9N9.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-EKNODw4P.js → index-DucLR6YX.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-C5AKY6bJ.js → index-Gz2rGWef.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-C8qi53Ki.js → index-IvgszJ3C.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-urPvyUVk.js → index-S80LLjdx.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-Bs2O3f81.js → index-WKbnwbKa.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-DpZqbc4w.js → index-XHBXtvqp.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-De2fPxdb.js → index-nn22NSDK.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-B0IjlB9m.js → index-pCIAE2yS.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-PEe9OWEQ.js → index-pRpMLhMt.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-FPXLIXoy.js → index-pgHGBAoF.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BhcpWl5z.js → index-ugIUt5TL.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-DsQ38fVY.js → index-xLGf7f9K.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-CDWa1rnn.js → initDefaultProps-C58CkKEo.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-CX2Cnsd5.js → motion-BLWPO2NV.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-Bfe1NcEF.js → move-BgrFMwYp.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-DbdqleHE.js → mtc-parser-Cq2AuGzl.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-CE2K7NVv.js → omit-Bb-9L7if.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-y_bZgxWG.js → pickAttrs-vLmOxYr1.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-BOHR4zwr.js → placementArrow-BNySU_dJ.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-B8Jwq05-.js → responsiveObserve-xnbwagnm.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-BD7RJ3Kn.js → slide-BccbY5Cn.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-BuxDJeDx.js → statusUtils-DOp9d2-w.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-DgYQ2Q0o.js → styleChecker-Bu1w6ho9.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-DAHF0Fwi.js → useFlexGapSupport-ZsUOrVdL.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-D4kDyLFp.js → useFs-C0zpzKtO.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-BHtSxW4A.js → usePersonalDataHub-DO1OdgXK.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-CHKtdqW0.js → vnode-jTIRyhR5.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-CIZAMma9.js → zoom-DKvS7-Qs.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/commands/agent.js +56 -20
  154. package/src/commands/batch.js +17 -12
  155. package/src/commands/eval.js +24 -8
  156. package/src/data/changelog.json +13 -0
  157. package/src/harness/mcp-client.js +187 -26
  158. package/src/lib/background-session-transport.js +21 -5
  159. package/src/lib/decision-layer/runtime.js +180 -10
  160. package/src/lib/direct-model-usage.js +34 -0
  161. package/src/lib/evolution/agent-evolution-ingress.js +63 -7
  162. package/src/lib/evolution/evolution-evidence-artifact-adapter.js +10 -0
  163. package/src/lib/evolution/evolution-evidence-projector.js +46 -7
  164. package/src/lib/evolution/skill-decision-projection.js +211 -0
  165. package/src/lib/evolution/skill-retrieval-revocation-authority.js +17 -2
  166. package/src/lib/skill-loader.js +16 -0
  167. package/src/repl/agent-repl.js +86 -7
  168. package/src/runtime/agent-core.js +111 -13
  169. package/src/runtime/headless-runner.js +212 -22
  170. package/src/runtime/headless-stream.js +189 -25
  171. package/src/runtime/mcp-config.js +26 -17
  172. package/src/runtime/mcp-tool-search.js +44 -14
  173. package/src/assets/web-panel/assets/ChatBubbleRenderer-n6BVStHf.js +0 -1
  174. package/src/assets/web-panel/assets/OrderTableRenderer-CxXuPzZg.js +0 -1
  175. package/src/assets/web-panel/assets/Tasks-QEFENVsp.js +0 -1
  176. package/src/assets/web-panel/assets/devWarning-rGldFhxo.js +0 -1
  177. package/src/assets/web-panel/assets/index-Cw-lfvvV.js +0 -1
  178. package/src/assets/web-panel/assets/index-QBXRSyoZ.js +0 -1
@@ -57,6 +57,7 @@ import {
57
57
  appendAuthorityEvent as jsonlAppendAuthorityEvent,
58
58
  readEvents as jsonlReadEvents,
59
59
  readVerifiedEvents as jsonlReadVerifiedEvents,
60
+ readVerifiedProjection as jsonlReadVerifiedProjection,
60
61
  findLatestEvent as jsonlFindLatestEvent,
61
62
  rebuildMessages as jsonlRebuildMessages,
62
63
  sessionExists as jsonlSessionExists,
@@ -137,7 +138,9 @@ import executionBroker from "../lib/process-execution-broker/index.js";
137
138
  import { extractPluginUsageAttribution } from "../lib/plugin-usage-attribution.js";
138
139
  import { formatManagedCheckpointEvent } from "../lib/managed-checkpoint-render.js";
139
140
  import {
141
+ normalizeSessionBudgetRootConfig,
140
142
  openProductionSessionBudgetRoot,
143
+ readProductionSessionBudget,
141
144
  sessionBudgetAdmissionError,
142
145
  } from "../lib/session-budget-production-root.js";
143
146
  import {
@@ -288,6 +291,74 @@ export function resolveHeadlessSkillDecisionOptions(options = {}) {
288
291
  });
289
292
  }
290
293
 
294
+ function createDecisionUsageRecoveryProjection() {
295
+ const started = new Map();
296
+ const seenCallIds = new Set();
297
+ let blocked = false;
298
+ return {
299
+ accept(event) {
300
+ if (blocked) return;
301
+ const data = event?.data;
302
+ const callId = data?.callId;
303
+ const isDecision =
304
+ typeof data?.operationId === "string" &&
305
+ data.operationId.startsWith("decision:");
306
+ if (event?.type === "model_usage_started" && isDecision) {
307
+ if (typeof callId !== "string" || !callId || seenCallIds.has(callId)) {
308
+ blocked = true;
309
+ return;
310
+ }
311
+ let boundary;
312
+ try {
313
+ boundary = projectRuntimeUsageBoundary(data, "started");
314
+ } catch {
315
+ blocked = true;
316
+ return;
317
+ }
318
+ seenCallIds.add(callId);
319
+ started.set(callId, boundary);
320
+ } else if (
321
+ event?.type === "model_usage_unknown" &&
322
+ (isDecision || started.has(callId))
323
+ ) {
324
+ blocked = true;
325
+ } else if (event?.type === "token_usage" && started.has(callId)) {
326
+ let settlement;
327
+ try {
328
+ settlement = projectRuntimeTokenUsage(data);
329
+ } catch {
330
+ blocked = true;
331
+ return;
332
+ }
333
+ const boundary = started.get(callId);
334
+ if (
335
+ settlement.callId !== boundary.callId ||
336
+ settlement.operationId !== boundary.operationId ||
337
+ settlement.provider !== boundary.provider ||
338
+ settlement.model !== boundary.model ||
339
+ settlement.source !== boundary.source
340
+ ) {
341
+ blocked = true;
342
+ return;
343
+ }
344
+ started.delete(callId);
345
+ }
346
+ },
347
+ finish() {
348
+ return blocked || started.size > 0;
349
+ },
350
+ };
351
+ }
352
+
353
+ function hasUnreconciledDecisionUsage(events) {
354
+ if (!Array.isArray(events)) return true;
355
+ const projection = createDecisionUsageRecoveryProjection();
356
+ for (const event of events) {
357
+ projection.accept(event);
358
+ }
359
+ return projection.finish();
360
+ }
361
+
291
362
  /**
292
363
  * Resolve a --permission-mode string into the session-policy tier + a
293
364
  * non-interactive confirmer + whether to clamp tools to the read-only set.
@@ -500,6 +571,7 @@ export function applyForkSession(opts = {}, store = {}) {
500
571
  */
501
572
  const HEADLESS_SESSION_RESOLUTION = Symbol("headlessSessionResolution");
502
573
  const HEADLESS_SESSION_HOST_LEASE = Symbol("headlessSessionHostLease");
574
+ const HEADLESS_CANONICAL_ADMISSION = Symbol("headlessCanonicalAdmission");
503
575
  const HEADLESS_HOOK_EVENT_CLEANUP = Symbol("headlessHookEventCleanup");
504
576
  const HOST_EVENT_BACKLOG_CODE = "CC_HOST_EVENT_BACKLOG_EXHAUSTED";
505
577
  const HOST_EVENT_BACKLOG_ERROR =
@@ -528,6 +600,7 @@ async function withHeadlessSessionHostLease(options, deps, task) {
528
600
  let lease = null;
529
601
  let budgetRoot = null;
530
602
  let scopedOptions = options;
603
+ let preflightAdmission;
531
604
  try {
532
605
  // Session authority/lease/budget setup can lazily initialize AppConfig and
533
606
  // DatabaseManager. Those legacy diagnostics use console.info (stdout), and
@@ -589,13 +662,101 @@ async function withHeadlessSessionHostLease(options, deps, task) {
589
662
  : lease.signal,
590
663
  }
591
664
  : options;
665
+ const canReadCanonical =
666
+ !hasInjectedSessionStore ||
667
+ typeof deps.readVerifiedEvents === "function";
668
+ if (
669
+ authoritySessionId &&
670
+ !canReadCanonical &&
671
+ (deps.sessionBudgetStore || options.sessionBudgetRoot?.enabled) &&
672
+ (resolution.resumeId ||
673
+ deps.sessionExists?.(authoritySessionId) !== false)
674
+ ) {
675
+ throw Object.assign(
676
+ new Error("budgeted resume requires verified session events"),
677
+ { code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
678
+ );
679
+ }
680
+ if (authoritySessionId && canReadCanonical) {
681
+ preflightAdmission = readSessionHostResumeState(authoritySessionId, {
682
+ sessionHasPersistedEvidence:
683
+ deps.sessionHasPersistedEvidence ||
684
+ (!hasInjectedSessionStore
685
+ ? jsonlSessionHasPersistedEvidence
686
+ : undefined),
687
+ sessionExists: deps.sessionExists || jsonlSessionExists,
688
+ readVerifiedEvents:
689
+ deps.readVerifiedEvents || jsonlReadVerifiedEvents,
690
+ });
691
+ }
692
+ if (preflightAdmission && !preflightAdmission.snapshot.verified) {
693
+ // The inner runner reports the canonical failure without opening or
694
+ // mutating a budget sidecar for an unverified transcript.
695
+ return;
696
+ }
697
+ const sidecar =
698
+ authoritySessionId &&
699
+ (process.platform === "linux" || deps.sessionBudgetStore)
700
+ ? readProductionSessionBudget(authoritySessionId, {
701
+ store: deps.sessionBudgetStore,
702
+ })
703
+ : null;
704
+ if (!preflightAdmission && !hasInjectedSessionStore && sidecar) {
705
+ throw Object.assign(
706
+ new Error("budget sidecar has no canonical JSONL session"),
707
+ { code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
708
+ );
709
+ }
710
+ let effectiveBudgetConfig = options.sessionBudgetRoot;
711
+ if (preflightAdmission) {
712
+ const canonicalConfig = preflightAdmission.sessionBudgetRoot;
713
+ const requestedConfig = options.sessionBudgetRoot?.enabled
714
+ ? normalizeSessionBudgetRootConfig(options.sessionBudgetRoot)
715
+ : null;
716
+ if (canonicalConfig?.enabled) {
717
+ if (!sidecar) {
718
+ throw Object.assign(
719
+ new Error(
720
+ "budgeted session is missing its durable budget sidecar",
721
+ ),
722
+ { code: "CC_SESSION_BUDGET_SIDECAR_REQUIRED" },
723
+ );
724
+ }
725
+ if (requestedConfig) {
726
+ if (
727
+ JSON.stringify(requestedConfig) !==
728
+ JSON.stringify(canonicalConfig)
729
+ ) {
730
+ throw Object.assign(
731
+ new Error(
732
+ "session budget does not match its JSONL declaration",
733
+ ),
734
+ { code: "CC_SESSION_BUDGET_CONFIG_MISMATCH" },
735
+ );
736
+ }
737
+ } else {
738
+ effectiveBudgetConfig = canonicalConfig;
739
+ }
740
+ } else if (requestedConfig || sidecar) {
741
+ throw Object.assign(
742
+ new Error(
743
+ "existing session has no canonical JSONL budget declaration",
744
+ ),
745
+ { code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
746
+ );
747
+ }
748
+ }
749
+ scopedOptions = {
750
+ ...scopedOptions,
751
+ sessionBudgetRoot: effectiveBudgetConfig,
752
+ };
592
753
  budgetRoot = openProductionSessionBudgetRoot(
593
754
  authoritySessionId,
594
- options.sessionBudgetRoot,
755
+ effectiveBudgetConfig,
595
756
  {
596
757
  persist: resolution.persist,
597
758
  signal: scopedOptions.signal || null,
598
- table: options.sessionBudgetRoot?.table,
759
+ table: effectiveBudgetConfig?.table || options.priceTable,
599
760
  open: deps.openSessionBudget,
600
761
  store: deps.sessionBudgetStore,
601
762
  registry: deps.sessionBudgetRegistry,
@@ -609,6 +770,7 @@ async function withHeadlessSessionHostLease(options, deps, task) {
609
770
  ...deps,
610
771
  [HEADLESS_SESSION_RESOLUTION]: resolution,
611
772
  [HEADLESS_SESSION_HOST_LEASE]: lease,
773
+ [HEADLESS_CANONICAL_ADMISSION]: preflightAdmission,
612
774
  });
613
775
  } finally {
614
776
  // Cleanup can touch the same lazy stores. Keep late diagnostics out of a
@@ -939,18 +1101,20 @@ async function runAgentHeadlessInWorkspace(
939
1101
  !hasInjectedSessionStore || typeof deps.readVerifiedEvents === "function";
940
1102
  const canonicalAdmissionId = resumeId || (persist ? sessionId : null);
941
1103
  const canonicalAdmission =
942
- canonicalAdmissionId && canReadCanonicalResume
943
- ? readSessionHostResumeState(canonicalAdmissionId, {
944
- sessionHasPersistedEvidence:
945
- deps.sessionHasPersistedEvidence ||
946
- (!hasInjectedSessionStore
947
- ? jsonlSessionHasPersistedEvidence
948
- : undefined),
949
- sessionExists: deps.sessionExists || jsonlSessionExists,
950
- readVerifiedEvents:
951
- deps.readVerifiedEvents || jsonlReadVerifiedEvents,
952
- })
953
- : null;
1104
+ deps[HEADLESS_CANONICAL_ADMISSION] !== undefined
1105
+ ? deps[HEADLESS_CANONICAL_ADMISSION]
1106
+ : canonicalAdmissionId && canReadCanonicalResume
1107
+ ? readSessionHostResumeState(canonicalAdmissionId, {
1108
+ sessionHasPersistedEvidence:
1109
+ deps.sessionHasPersistedEvidence ||
1110
+ (!hasInjectedSessionStore
1111
+ ? jsonlSessionHasPersistedEvidence
1112
+ : undefined),
1113
+ sessionExists: deps.sessionExists || jsonlSessionExists,
1114
+ readVerifiedEvents:
1115
+ deps.readVerifiedEvents || jsonlReadVerifiedEvents,
1116
+ })
1117
+ : null;
954
1118
  if (canonicalAdmission && !canonicalAdmission.snapshot.verified) {
955
1119
  const message =
956
1120
  "CC_SESSION_HOST_SNAPSHOT_UNVERIFIED: canonical JSONL session is not " +
@@ -2012,6 +2176,9 @@ async function runAgentHeadlessInWorkspace(
2012
2176
  provider,
2013
2177
  model,
2014
2178
  observabilityScope: options.observabilityScope,
2179
+ ...(options.sessionBudgetRoot?.enabled === true
2180
+ ? { sessionBudgetRoot: options.sessionBudgetRoot }
2181
+ : {}),
2015
2182
  executionLocation: captureAmbientExecutionLocation({
2016
2183
  provider,
2017
2184
  model,
@@ -2458,13 +2625,35 @@ async function runAgentHeadlessInWorkspace(
2458
2625
  const skillDecisionOptions = resolveHeadlessSkillDecisionOptions(options);
2459
2626
  let skillDecisionRuntime = null;
2460
2627
  if (skillDecisionOptions.mode !== "off") {
2461
- const previousUnknownDecisionUsage = store.findLatestEvent(
2462
- sessionId,
2463
- "model_usage_unknown",
2464
- (event) =>
2465
- typeof event?.data?.operationId === "string" &&
2466
- event.data.operationId.startsWith("decision:"),
2467
- );
2628
+ let previousUnreconciledDecisionUsage;
2629
+ if (
2630
+ !hasInjectedSessionStore ||
2631
+ typeof deps.readVerifiedEvents === "function"
2632
+ ) {
2633
+ try {
2634
+ previousUnreconciledDecisionUsage = hasInjectedSessionStore
2635
+ ? hasUnreconciledDecisionUsage(store.readVerifiedEvents(sessionId))
2636
+ : jsonlReadVerifiedProjection(
2637
+ sessionId,
2638
+ createDecisionUsageRecoveryProjection,
2639
+ );
2640
+ } catch {
2641
+ // Without a verified settlement, a resumed provider call could be paid twice.
2642
+ previousUnreconciledDecisionUsage = true;
2643
+ }
2644
+ } else {
2645
+ // Legacy injected stores cannot prove a prior call was settled. Their
2646
+ // explicit no-session answer still permits a fresh test/embedding run.
2647
+ previousUnreconciledDecisionUsage =
2648
+ store.sessionExists(sessionId) ||
2649
+ store.findLatestEvent(
2650
+ sessionId,
2651
+ "model_usage_unknown",
2652
+ (event) =>
2653
+ typeof event?.data?.operationId === "string" &&
2654
+ event.data.operationId.startsWith("decision:"),
2655
+ ) != null;
2656
+ }
2468
2657
  const decisionProvider =
2469
2658
  deps.decisionProvider ||
2470
2659
  createDecisionProvider({
@@ -2487,11 +2676,12 @@ async function runAgentHeadlessInWorkspace(
2487
2676
  options.decisionTenantId || evolutionIngress?.tenantId || "cli-local",
2488
2677
  sessionId,
2489
2678
  provider: decisionProvider,
2679
+ evolutionIngress,
2490
2680
  persist: persistDecisionEvent,
2491
2681
  observe: (observation) =>
2492
2682
  persistDecisionEvent("skill_decision_observation", observation),
2493
2683
  sessionBudget: options.sessionBudget || null,
2494
- initialUsageUnknown: previousUnknownDecisionUsage != null,
2684
+ initialUsageUnknown: previousUnreconciledDecisionUsage,
2495
2685
  timeoutMs: skillDecisionOptions.timeoutMs,
2496
2686
  });
2497
2687
  }
@@ -151,7 +151,9 @@ import {
151
151
  } from "../lib/session-host-snapshot.js";
152
152
  import { acquireSessionHostLease } from "../lib/session-host-lease.js";
153
153
  import {
154
+ normalizeSessionBudgetRootConfig,
154
155
  openProductionSessionBudgetRoot,
156
+ readProductionSessionBudget,
155
157
  sessionBudgetAdmissionError,
156
158
  } from "../lib/session-budget-production-root.js";
157
159
  import {
@@ -1441,6 +1443,7 @@ async function withStreamSessionHostLease(options, deps, streamCleanup, task) {
1441
1443
  let lease = null;
1442
1444
  let budgetRoot = null;
1443
1445
  let onLeaseAbort = null;
1446
+ let taskStarted = false;
1444
1447
  try {
1445
1448
  if (persist && typeof acquireHostLease === "function") {
1446
1449
  lease = acquireHostLease(sessionId, { hostKind: "headless-stream" });
@@ -1461,13 +1464,109 @@ async function withStreamSessionHostLease(options, deps, streamCleanup, task) {
1461
1464
  : lease.signal,
1462
1465
  }
1463
1466
  : options;
1467
+ const canReadCanonical =
1468
+ !hasInjectedSessionStore ||
1469
+ typeof deps.readVerifiedEvents === "function" ||
1470
+ typeof deps.readVerifiedProjection === "function";
1471
+ const budgetStore = deps.sessionBudgetStore;
1472
+ const sidecar =
1473
+ persist && (process.platform === "linux" || budgetStore)
1474
+ ? readProductionSessionBudget(sessionId, { store: budgetStore })
1475
+ : null;
1476
+ const needsBudgetAdmission =
1477
+ persist &&
1478
+ (!hasInjectedSessionStore ||
1479
+ options.sessionBudgetRoot?.enabled === true ||
1480
+ Boolean(budgetStore) ||
1481
+ Boolean(deps.openSessionBudget) ||
1482
+ Boolean(sidecar));
1483
+ let effectiveBudgetConfig = options.sessionBudgetRoot;
1484
+ if (needsBudgetAdmission) {
1485
+ const existing = (
1486
+ deps.sessionHasPersistedEvidence ||
1487
+ deps.sessionExists ||
1488
+ jsonlSessionHasPersistedEvidence
1489
+ )(sessionId);
1490
+ if (typeof existing !== "boolean") {
1491
+ throw Object.assign(
1492
+ new Error("stream session existence must be checked synchronously"),
1493
+ { code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
1494
+ );
1495
+ }
1496
+ if (existing && !canReadCanonical) {
1497
+ throw Object.assign(
1498
+ new Error("budgeted stream resume requires verified session events"),
1499
+ { code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
1500
+ );
1501
+ }
1502
+ const canonical = existing
1503
+ ? readSessionHostResumeState(sessionId, {
1504
+ sessionExists: () => true,
1505
+ readVerifiedEvents:
1506
+ deps.readVerifiedEvents || jsonlReadVerifiedEvents,
1507
+ ...(!hasInjectedSessionStore || deps.readVerifiedProjection
1508
+ ? {
1509
+ readVerifiedProjection:
1510
+ deps.readVerifiedProjection || jsonlReadVerifiedProjection,
1511
+ }
1512
+ : {}),
1513
+ })
1514
+ : null;
1515
+ if (canonical && !isVerifiedSessionHostSnapshot(canonical.snapshot)) {
1516
+ throw Object.assign(
1517
+ new Error("canonical stream session could not be verified"),
1518
+ { code: "CC_SESSION_HOST_SNAPSHOT_UNVERIFIED" },
1519
+ );
1520
+ }
1521
+ if (!canonical && sidecar) {
1522
+ throw Object.assign(
1523
+ new Error("budget sidecar has no canonical JSONL session"),
1524
+ { code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
1525
+ );
1526
+ }
1527
+ if (canonical) {
1528
+ const declared = canonical.sessionBudgetRoot;
1529
+ const requested = options.sessionBudgetRoot?.enabled
1530
+ ? normalizeSessionBudgetRootConfig(options.sessionBudgetRoot)
1531
+ : null;
1532
+ if (declared?.enabled) {
1533
+ if (!sidecar) {
1534
+ throw Object.assign(
1535
+ new Error(
1536
+ "budgeted stream session is missing its budget sidecar",
1537
+ ),
1538
+ { code: "CC_SESSION_BUDGET_SIDECAR_REQUIRED" },
1539
+ );
1540
+ }
1541
+ if (
1542
+ requested &&
1543
+ JSON.stringify(requested) !== JSON.stringify(declared)
1544
+ ) {
1545
+ throw Object.assign(
1546
+ new Error("stream budget does not match its JSONL declaration"),
1547
+ { code: "CC_SESSION_BUDGET_CONFIG_MISMATCH" },
1548
+ );
1549
+ }
1550
+ effectiveBudgetConfig = declared;
1551
+ } else if (requested || sidecar) {
1552
+ throw Object.assign(
1553
+ new Error("existing stream has no canonical budget declaration"),
1554
+ { code: "CC_SESSION_BUDGET_JSONL_REQUIRED" },
1555
+ );
1556
+ }
1557
+ }
1558
+ }
1559
+ scopedOptions = {
1560
+ ...scopedOptions,
1561
+ sessionBudgetRoot: effectiveBudgetConfig,
1562
+ };
1464
1563
  budgetRoot = openProductionSessionBudgetRoot(
1465
1564
  persist ? sessionId : null,
1466
- options.sessionBudgetRoot,
1565
+ effectiveBudgetConfig,
1467
1566
  {
1468
1567
  persist,
1469
1568
  signal: scopedOptions.signal || null,
1470
- table: options.sessionBudgetRoot?.table,
1569
+ table: effectiveBudgetConfig?.table,
1471
1570
  open: deps.openSessionBudget,
1472
1571
  store: deps.sessionBudgetStore,
1473
1572
  registry: deps.sessionBudgetRegistry,
@@ -1476,11 +1575,40 @@ async function withStreamSessionHostLease(options, deps, streamCleanup, task) {
1476
1575
  if (budgetRoot.enabled) {
1477
1576
  scopedOptions = { ...scopedOptions, ...budgetRoot.options };
1478
1577
  }
1578
+ taskStarted = true;
1479
1579
  return await task(scopedOptions, {
1480
1580
  ...deps,
1481
1581
  [STREAM_SESSION_ID]: sessionId,
1482
1582
  [STREAM_SESSION_HOST_LEASE]: lease,
1483
1583
  });
1584
+ } catch (error) {
1585
+ // Admission can write a lease or take the Linux budget-sidecar read lock
1586
+ // before the workspace runner installs its persistence boundary. Preserve
1587
+ // the lock's filesystem cause, but never reclassify an executing task.
1588
+ if (taskStarted) throw error;
1589
+ const persistence = projectSessionPersistenceFailure(
1590
+ createSessionPersistenceFailure(error, {
1591
+ sessionId,
1592
+ operation: "session-start",
1593
+ }),
1594
+ { phase: "before-model" },
1595
+ );
1596
+ if (!persistence) throw error;
1597
+ deps.writeOut(
1598
+ `${JSON.stringify({
1599
+ type: "result",
1600
+ subtype: "error_persistence",
1601
+ is_error: true,
1602
+ code: persistence.code,
1603
+ error: "Canonical stream admission failed",
1604
+ session_id: sessionId,
1605
+ persistence,
1606
+ })}\n`,
1607
+ );
1608
+ deps.writeErr(
1609
+ `${persistence.code}: canonical stream admission was refused\n`,
1610
+ );
1611
+ return { exitCode: 1, turns: 0, persistence };
1484
1612
  } finally {
1485
1613
  budgetRoot?.close?.();
1486
1614
  if (lease?.signal && onLeaseAbort) {
@@ -1914,7 +2042,29 @@ async function runAgentHeadlessStreamInWorkspace(
1914
2042
  };
1915
2043
  }
1916
2044
  }
1917
- } catch {
2045
+ } catch (error) {
2046
+ const persistence = projectSessionPersistenceFailure(
2047
+ createSessionPersistenceFailure(error, {
2048
+ sessionId,
2049
+ operation: "session-start",
2050
+ }),
2051
+ { phase: "before-model" },
2052
+ );
2053
+ if (persistence) {
2054
+ emit({
2055
+ type: "result",
2056
+ subtype: "error_persistence",
2057
+ is_error: true,
2058
+ code: persistence.code,
2059
+ error: "Canonical stream session preparation failed",
2060
+ session_id: sessionId,
2061
+ persistence,
2062
+ });
2063
+ writeErr(
2064
+ `${persistence.code}: canonical stream preparation was refused\n`,
2065
+ );
2066
+ return { exitCode: 1, turns: 0, persistence };
2067
+ }
1918
2068
  const code = "CC_SESSION_HOST_SNAPSHOT_UNVERIFIED";
1919
2069
  emit({
1920
2070
  type: "result",
@@ -1986,8 +2136,9 @@ async function runAgentHeadlessStreamInWorkspace(
1986
2136
  const { loadHooks, projectHookTrustNotice, attachAuthorityErrors } =
1987
2137
  await import("../lib/settings-hooks.cjs");
1988
2138
  const loaded = loadHooks({ cwd, settingsFile: options.settingsFile });
1989
- const { mergePluginHooks } =
1990
- await import("../lib/plugin-runtime/hooks.js");
2139
+ const { mergePluginHooks } = await import(
2140
+ "../lib/plugin-runtime/hooks.js"
2141
+ );
1991
2142
  const effectiveHooks = mergePluginHooks(
1992
2143
  attachAuthorityErrors(loaded.hooks, loaded.authorityErrors),
1993
2144
  { cwd },
@@ -2069,8 +2220,9 @@ async function runAgentHeadlessStreamInWorkspace(
2069
2220
  });
2070
2221
 
2071
2222
  if (managedSettings) {
2072
- const { assertManagedPermissionMode } =
2073
- await import("../lib/settings-loader.cjs");
2223
+ const { assertManagedPermissionMode } = await import(
2224
+ "../lib/settings-loader.cjs"
2225
+ );
2074
2226
  assertManagedPermissionMode(options.permissionMode, managedSettings);
2075
2227
  }
2076
2228
  const perm = resolvePermissionMode(options.permissionMode);
@@ -2909,8 +3061,9 @@ async function runAgentHeadlessStreamInWorkspace(
2909
3061
  : null;
2910
3062
  if (!instructionExcludes) {
2911
3063
  try {
2912
- const { readStringArraySetting } =
2913
- await import("../lib/settings-loader.cjs");
3064
+ const { readStringArraySetting } = await import(
3065
+ "../lib/settings-loader.cjs"
3066
+ );
2914
3067
  const fromSettings = readStringArraySetting("instructionExcludes", {
2915
3068
  cwd,
2916
3069
  settingsFile: options.settingsFile,
@@ -2975,8 +3128,9 @@ async function runAgentHeadlessStreamInWorkspace(
2975
3128
  // Best-effort; no-op when project memory is off or no hook is registered.
2976
3129
  if (settingsHooks && _loadedInstructions) {
2977
3130
  try {
2978
- const { runInstructionsLoadedHooks } =
2979
- await import("../lib/settings-hook-events.js");
3131
+ const { runInstructionsLoadedHooks } = await import(
3132
+ "../lib/settings-hook-events.js"
3133
+ );
2980
3134
  const ctx = (
2981
3135
  await runInstructionsLoadedHooks(settingsHooks, {
2982
3136
  files: _loadedInstructions.files,
@@ -3018,8 +3172,9 @@ async function runAgentHeadlessStreamInWorkspace(
3018
3172
  // settings.json SessionStart hooks → inject session context once (observe-only).
3019
3173
  if (settingsHooks) {
3020
3174
  try {
3021
- const { runSessionStartHooks } =
3022
- await import("../lib/settings-hook-events.js");
3175
+ const { runSessionStartHooks } = await import(
3176
+ "../lib/settings-hook-events.js"
3177
+ );
3023
3178
  const ctx = (
3024
3179
  await runSessionStartHooks(settingsHooks, {
3025
3180
  source: "startup",
@@ -3069,6 +3224,9 @@ async function runAgentHeadlessStreamInWorkspace(
3069
3224
  provider,
3070
3225
  model,
3071
3226
  observabilityScope: options.observabilityScope,
3227
+ ...(options.sessionBudgetRoot?.enabled === true
3228
+ ? { sessionBudgetRoot: options.sessionBudgetRoot }
3229
+ : {}),
3072
3230
  executionLocation: captureAmbientExecutionLocation({
3073
3231
  provider,
3074
3232
  model,
@@ -3453,8 +3611,9 @@ async function runAgentHeadlessStreamInWorkspace(
3453
3611
  // the single-prompt runner + the REPL /add-dir path. Best-effort.
3454
3612
  if (hostMcp?.mcpClient && additionalDirectories.length > 0) {
3455
3613
  try {
3456
- const { notifyMcpRootsChanged, workspaceRootDirs } =
3457
- await import("../repl/add-dir.js");
3614
+ const { notifyMcpRootsChanged, workspaceRootDirs } = await import(
3615
+ "../repl/add-dir.js"
3616
+ );
3458
3617
  notifyMcpRootsChanged(
3459
3618
  [hostMcp.mcpClient],
3460
3619
  workspaceRootDirs(options.cwd || process.cwd(), additionalDirectories),
@@ -4376,15 +4535,17 @@ async function runAgentHeadlessStreamInWorkspace(
4376
4535
  return compactionCallId;
4377
4536
  },
4378
4537
  };
4379
- const { resolveCliContextMemoryCutover } =
4380
- await import("../lib/context-memory-kernel/authority.js");
4538
+ const { resolveCliContextMemoryCutover } = await import(
4539
+ "../lib/context-memory-kernel/authority.js"
4540
+ );
4381
4541
  const cutover = resolveCliContextMemoryCutover({
4382
4542
  env: options.contextMemoryEnv || process.env,
4383
4543
  scopeKey: `cli:session:${sessionId}`,
4384
4544
  });
4385
4545
  if (cutover.canonical) {
4386
- const { compactLiveMessagesCanonical } =
4387
- await import("../lib/context-memory-kernel/live-compaction.js");
4546
+ const { compactLiveMessagesCanonical } = await import(
4547
+ "../lib/context-memory-kernel/live-compaction.js"
4548
+ );
4388
4549
  const canonical = await compactLiveMessagesCanonical(messages, {
4389
4550
  compressor: {
4390
4551
  maxTokens: Math.max(
@@ -4472,8 +4633,9 @@ async function runAgentHeadlessStreamInWorkspace(
4472
4633
  } catch (error) {
4473
4634
  if (isAbortError(error) || options.signal?.aborted) throw error;
4474
4635
  if (error?.runtimeLedgerPersistence === true) throw error;
4475
- const { getRejectedCompactionUsage } =
4476
- await import("../lib/context-memory-kernel/live-compaction.js");
4636
+ const { getRejectedCompactionUsage } = await import(
4637
+ "../lib/context-memory-kernel/live-compaction.js"
4638
+ );
4477
4639
  const rejectedUsage = getRejectedCompactionUsage(error);
4478
4640
  if (
4479
4641
  rejectedUsage &&
@@ -4901,8 +5063,9 @@ async function runAgentHeadlessStreamInWorkspace(
4901
5063
  // session can honour the user's standing preferences ("越用越聪明"
4902
5064
  // flywheel). Best-effort — a learning ledger must never break the chat.
4903
5065
  try {
4904
- const { appendFeedback } =
4905
- await import("../lib/pdh-feedback-ledger.js");
5066
+ const { appendFeedback } = await import(
5067
+ "../lib/pdh-feedback-ledger.js"
5068
+ );
4906
5069
  appendFeedback({ sessionId, turnId, kind, comment });
4907
5070
  } catch {
4908
5071
  /* persistence is best-effort */
@@ -5074,8 +5237,9 @@ async function runAgentHeadlessStreamInWorkspace(
5074
5237
  // settings.json UserPromptSubmit hooks. block → skip this turn; context → inject.
5075
5238
  if (settingsHooks) {
5076
5239
  try {
5077
- const { runUserPromptSubmitHooks } =
5078
- await import("../lib/settings-hook-events.js");
5240
+ const { runUserPromptSubmitHooks } = await import(
5241
+ "../lib/settings-hook-events.js"
5242
+ );
5079
5243
  const ups = await runUserPromptSubmitHooks(settingsHooks, {
5080
5244
  prompt: userContent,
5081
5245
  cwd,