chainlesschain 0.166.97 → 0.166.98

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 (175) hide show
  1. package/package.json +3 -3
  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-BB9kKNVw.js → AIOps-DCIQFtF1.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-DTg-lWE0.js → ActionButton-BxhHU3nE.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-BWUZ0Tpc.js → Analytics-DdM_307O.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-Dj8WDnCf.js → AppLayout-C43-kSrh.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-x8NiiPTg.js → Artifacts-B2Vp2Am6.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-q7otRAqO.js → Audit-s-lYUfOp.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-f6qlO2au.js → BackgroundAgents-DTE7Kzio.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-BbuX9qQS.js → Backup-9k1q4Mt6.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-amgV-Y0y.js → BaseInput-DlpUtK5R.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-CZW3DW7j.js → Chat-CR9S8Rmb.js} +5 -5
  14. package/src/assets/web-panel/assets/ChatBubbleRenderer-Xtgfw3-c.js +1 -0
  15. package/src/assets/web-panel/assets/{Checkbox-DXHXC52i.js → Checkbox-DpFRu7Df.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-DQh47r4e.js → Codegen-BIl72E4Y.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-lBOOXCD7.js → Col-91tl_err.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-BNFPnBu9.js → Community-CswahO9-.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-7MOWfBGb.js → Compact-D9pfHmaM.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-x0UA-rxk.js → Compliance-CXSZzAO9.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-C_eLfk_Q.js → Cowork-CuT9RWTn.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-BP2-_Fja.js → Cron-B71aJWDV.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-Dn-e1217.js → Crosschain-CcUuWyx8.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-D_jverif.js → DID-CtVVGOPL.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-BysweBms.js → Dashboard-CV7ZCYQq.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-osJi0Pci.js → Dropdown-DKHxwLgE.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-C72k1SKQ.js → EmailListRenderer-Bd03UIvv.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-CAtA1F9s.js → EvolutionSettings-CTrG03B_.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-Bi0luzvO.js → FamilyGuardDashboard-DXS4bS6Q.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-CIwntDLI.js → Federation-BODG2Szj.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-DRfwhPW-.js → FormItemContext-D32ccUqD.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-COJTzZ61.js → GenericCardRenderer-ClsyrKvF.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-CwsR46lj.js → Git-DcM2yhbL.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-B1U-u9BN.js → Governance-BhUzM87n.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-vPsdYTS_.js → Inference-Dq1n0Ifg.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-CVDRZM5h.js → KnowledgeGraph-dmmPwEks.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-YRslKbRL.js → Logs-CBSYrPmh.js} +2 -2
  38. package/src/assets/web-panel/assets/MarkdownRenderer-CRoDI77y.js +1 -0
  39. package/src/assets/web-panel/assets/{Marketplace-CtxYHchd.js → Marketplace-Cfw7XLck.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-BkfCbpAk.js → McpTools-CNrZRy4n.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-COp-8Z20.js → Memory-BESjTxdd.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-7fX-n_xn.js → MobileBridge-Boyjo07i.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-DUyTVgId.js → MobileProjects-BmxmpTWz.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-CLXFZ5dV.js → Mtc-CBkrD0Fq.js} +5 -5
  45. package/src/assets/web-panel/assets/{MtcAudit-yJ4eP1wB.js → MtcAudit-BA7cAK8h.js} +5 -5
  46. package/src/assets/web-panel/assets/{Multisig-Cwb_qTh0.js → Multisig-m0RGzkKO.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-CkuojSSJ.js → NLProgramming-D_TgzifU.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-ju-QtUhJ.js → Notes-Dr-Yr9LL.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-DjryXIC3.js → NotificationSettings-DGanpkqO.js} +1 -1
  50. package/src/assets/web-panel/assets/{OrderTableRenderer-B4KNF8xr.js → OrderTableRenderer-D1FX50QY.js} +1 -1
  51. package/src/assets/web-panel/assets/{Organization-6-EtcVaO.js → Organization-DRbPg-gs.js} +2 -2
  52. package/src/assets/web-panel/assets/{Overflow-BKja8nqr.js → Overflow-flEO37z6.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-BX20f9uL.js → P2P-DqfqFbCW.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-C9zwOEUo.js → PdhVaultBrowser-Cmi5a5dW.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-YQjQVrfE.js → Permissions-DBVRlvBW.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-yZYclXxq.js → PersonalDataHub-gQqjPr9X.js} +4 -4
  57. package/src/assets/web-panel/assets/{Pipeline-ChZCCXAI.js → Pipeline-6HlifUc9.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-Ds7R-a0H.js → Privacy-bm_2-Zwg.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-B3qz_xab.js → ProjectInit-BJW3isuq.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-BlwNctdF.js → ProjectSettings-DD3yolz7.js} +2 -2
  61. package/src/assets/web-panel/assets/{Projects-BxtYpNl7.js → Projects-BF3GtWny.js} +1 -1
  62. package/src/assets/web-panel/assets/{Providers-BE_1SS_-.js → Providers-CQA6WAK7.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-CMQ25oLb.js → QrScannerModal-DOAwp5Xo.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-DQRFLDeP.js → QuickAsk-qeFXsAZT.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-ChVra4Pk.js → Recommend-zDWXwZN8.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-9vPBIowJ.js → RemoteSession-toe6Ip06.js} +3 -3
  67. package/src/assets/web-panel/assets/{Reputation-MdbWbyQQ.js → Reputation-DRDi_Eqp.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-JLcBncLR.js → Row-Do2UbYkf.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-CnMXnpFv.js → RssFeed-B57C6_Sa.js} +3 -3
  70. package/src/assets/web-panel/assets/{Search-Cf5ISVUe.js → Search-DfDyBpe9.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-CywFo2EM.js → Security-CulNxeAM.js} +3 -3
  72. package/src/assets/web-panel/assets/{Services-CLYnSCG3.js → Services-COfAYvs4.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-BtbhOlo1.js → Skeleton-0fn0T146.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-DPeqcIo2.js → Skills-pPQgAhvJ.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-BRb4SqDn.js → Sla-CIsRmePR.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-0Wuxts-7.js → SpeechSettings-Bn01d-8b.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-BXtsOjXL.js → SyncSettings-Cx_Znk7L.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-D455Wfhx.js → Tasks-DvaskzpG.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-LGc4O0fj.js → Templates-DmHCEiDO.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-DA--0GFz.js → Tenant-CqHyvnbW.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-DQsA0xCq.js → Terminal-DTt3yqWL.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-VH8AuSLp.js → TimelineRenderer-BhkIxcR3.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-B8RyzFRN.js → Tokens-mhjYcBBP.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-CA7lVVEf.js → Trigger-CdlMQfwX.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-wUoRRLg9.js → Trust-Bzovg_Gw.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-ByoT_alW.js → UkeySign-ph3EuYi7.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-D9fgAxJV.js → VideoEditing-Bo2B4VZE.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-CRkTndvj.js → Wallet-BQTKsSUT.js} +2 -2
  89. package/src/assets/web-panel/assets/{WebAuthn-VwmHOxJK.js → WebAuthn-nJxsXNHV.js} +5 -5
  90. package/src/assets/web-panel/assets/{WorkflowEditor-Z0bPZc2O.js → WorkflowEditor-CjH8g2N7.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-CfX_5qUm.js → chat-CkbNmnQD.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-BK7mXUnR.js → colors-BY9JcObR.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-Uq755CeO.js → compact-item-Dzzq-d8n.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-DWXq8Qnk.js → createContext-DiJxxdTx.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-D502_Z3w.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-BXgy5JZA.js → hasIn-DaXPOw3D.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-_I4nSJFc.js → index-6Z6Z4UwN.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-D4yvdQCj.js → index-7YVCjSqG.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-D63nsr0a.js → index-B31oMRmK.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-DdwC1i3O.js → index-B4Sf1AMk.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-CRLOeoFE.js → index-BGvIb1Sr.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-JX7mXB5a.js → index-BHeHyLRM.js} +3 -3
  103. package/src/assets/web-panel/assets/{index-Ct41B4y4.js → index-BQvtlYUd.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-VrR8eMCk.js → index-Bhsxh-rH.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-C8e4SYX4.js → index-BlWg1bRA.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-C3VnhfYU.js → index-BqCHe05H.js} +1 -1
  107. package/src/assets/web-panel/assets/index-BrQ4nI4W.js +1 -0
  108. package/src/assets/web-panel/assets/{index-DSb7SKp5.js → index-BvgMt6Io.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-Y77S-ZC0.js → index-BycyBM6g.js} +1 -1
  110. package/src/assets/web-panel/assets/index-C0_sewGO.js +1 -0
  111. package/src/assets/web-panel/assets/{index-CGy7b2rd.js → index-C6XSCXeb.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-XdoslBhl.js → index-CAzfu6k5.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-B09haI0M.js → index-CVblRqUN.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-Bt3tjvj-.js → index-CWLpEg34.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-wYTro42F.js → index-C_OMH_FT.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-H13lvPme.js → index-CbOOm8I8.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-TDPkVyse.js → index-CnLO1_yN.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DuhlVXh4.js → index-CqOkm6kW.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-CfYb8FjC.js → index-DDnqjZa2.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-VPLA-GO7.js → index-DObXhPhH.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-CarQiRSA.js → index-DSqQyS9-.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Ait-_UUh.js → index-DWT9-E5b.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-D-8lN1rG.js → index-D_Eoh740.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-DiVH_NiY.js → index-DaylJfw6.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DbjUfyVq.js → index-DbmHmeP-.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-LsBPnXHh.js → index-Djeh6rAb.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-Dg9P9EDV.js → index-Dl8U-0hn.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-BRQSkXde.js → index-EiaWq1TH.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-BZD1My0S.js → index-Igq-72Ep.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-QXKuGlOS.js → index-Jmlk_lDX.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-p3BlIre2.js → index-LRZSVBxC.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-CUR7dnMg.js → index-Uh9SjtgW.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-CqJw5WsH.js → index-cu1J4avY.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-9XsaovMH.js → index-dC2JACyJ.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-BxSClhg5.js → index-i9eu2Kir.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-DTuF67Yy.js → initDefaultProps-B0WuG3fa.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-DZasLgsl.js → motion-1r5YB22w.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-pPR4O1Du.js → move-CvtXWA_V.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-Dc7fidhm.js → mtc-parser-ChedmEE_.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-CZ1IcubN.js → omit-DpEA3MP0.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-BMtJilhr.js → pickAttrs-BWgrUZF6.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-D0EXaZA7.js → placementArrow-BWfo_VbI.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-HftdThc5.js → responsiveObserve-CRft03Vk.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-CT1JEPWV.js → slide-l5LeXusH.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-rwE-IPZB.js → statusUtils-CCEC0JR-.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-B2B8XHVq.js → styleChecker-Bw5Gw_2w.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-TXNvIFVa.js → useFlexGapSupport-BAuxWB7K.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-BcWgJKvf.js → useFs-CxUP97Cw.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-DWBDnOSR.js → usePersonalDataHub-BJDjT4Sy.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-Cf_LjUuu.js → vnode-BcCsFzIs.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-DM2Bfuyl.js → zoom-MLmG09h6.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/commands/eval.js +79 -3
  154. package/src/commands/llm.js +40 -5
  155. package/src/data/changelog.json +13 -0
  156. package/src/lib/context-memory-kernel/message-adapter.js +41 -24
  157. package/src/lib/context-memory-kernel/segmented-memory-port.js +18 -0
  158. package/src/lib/eval/runner.js +22 -1
  159. package/src/lib/eval/verify01-contracts.js +106 -51
  160. package/src/lib/eval/verify01-execution.js +148 -166
  161. package/src/lib/eval/verify01-host-evidence.js +34 -2
  162. package/src/lib/eval/verify01-workspace.js +302 -0
  163. package/src/lib/execution-location-failure-site.js +18 -0
  164. package/src/lib/execution-location-target.js +10 -0
  165. package/src/lib/llm-connection-probe.js +147 -6
  166. package/src/lib/provider-http-error.js +30 -11
  167. package/src/lib/task-progress-tracker.js +1 -0
  168. package/src/runtime/agent-core.js +22 -0
  169. package/src/runtime/headless-runner.js +30 -20
  170. package/src/runtime/headless-stream.js +15 -10
  171. package/src/assets/web-panel/assets/ChatBubbleRenderer-DgMYDmBW.js +0 -1
  172. package/src/assets/web-panel/assets/MarkdownRenderer-CUBuc97a.js +0 -1
  173. package/src/assets/web-panel/assets/devWarning-CbtBfs7a.js +0 -1
  174. package/src/assets/web-panel/assets/index-CicoHC0s.js +0 -1
  175. package/src/assets/web-panel/assets/index-DttyUwDx.js +0 -1
@@ -15,8 +15,12 @@ import { fileURLToPath } from "url";
15
15
  import { runEvalSuite } from "../lib/eval/runner.js";
16
16
  import { getSuite } from "../lib/eval/tasks.js";
17
17
  import { verifyAgentTerminal } from "../lib/eval/stream-terminal.js";
18
- import { persistVerify01Receipts } from "../lib/eval/verify01-execution.js";
18
+ import {
19
+ captureVerify01AgentBinding,
20
+ persistVerify01Receipts,
21
+ } from "../lib/eval/verify01-execution.js";
19
22
  import executionBroker from "../lib/process-execution-broker/index.js";
23
+ import { BUILT_IN_PROVIDERS } from "../lib/llm-providers.js";
20
24
  import {
21
25
  TelemetryRecorder,
22
26
  formatTelemetry,
@@ -93,7 +97,68 @@ function killAgentTree(child) {
93
97
  * workspace. acceptEdits lets it write files without an interactive prompt.
94
98
  */
95
99
  function makeHeadlessRunAgent(opts = {}) {
96
- return function runAgent({ prompt, cwd, timeoutMs, costBudgetUsd }) {
100
+ return function runAgent({
101
+ prompt,
102
+ cwd,
103
+ timeoutMs,
104
+ costBudgetUsd,
105
+ verify01Binding,
106
+ }) {
107
+ const binding =
108
+ verify01Binding === undefined
109
+ ? null
110
+ : captureVerify01AgentBinding(verify01Binding, cwd);
111
+ if (opts.requireVerify01Binding && !binding)
112
+ throw new Error("frozen suite requires a task-specific agent binding");
113
+ if (
114
+ binding &&
115
+ (binding.provider !== opts.provider || binding.model !== opts.model)
116
+ )
117
+ throw new Error(
118
+ "VERIFY01 provider/model binding differs from the launcher",
119
+ );
120
+ const inherited = { ...process.env, ...(opts.env || {}) };
121
+ const environmentValue = (name) => {
122
+ if (process.platform !== "win32") return inherited[name];
123
+ // Windows environment keys are case-insensitive, but spreading env into
124
+ // a plain object loses that lookup behavior (PATH is usually Path).
125
+ const key = Object.keys(inherited)
126
+ .reverse()
127
+ .find((candidate) => candidate.toLowerCase() === name.toLowerCase());
128
+ return key === undefined ? undefined : inherited[key];
129
+ };
130
+ const providerKey = BUILT_IN_PROVIDERS[binding?.provider]?.apiKeyEnv;
131
+ // Formal children retain platform plumbing and only the selected provider's
132
+ // credential (or the explicitly selected generic CC_API_KEY). Hooks,
133
+ // fallback configuration, NODE_OPTIONS and unrelated account tokens are
134
+ // excluded. Normal, non-formal Eval retains its existing environment.
135
+ const childEnvironment = binding
136
+ ? {
137
+ ...Object.fromEntries(
138
+ [
139
+ "PATH",
140
+ "SystemRoot",
141
+ "WINDIR",
142
+ "ComSpec",
143
+ "PATHEXT",
144
+ "TEMP",
145
+ "TMP",
146
+ "TMPDIR",
147
+ "LANG",
148
+ "LC_ALL",
149
+ "LC_CTYPE",
150
+ "CC_API_KEY",
151
+ ...(providerKey ? [providerKey] : []),
152
+ ]
153
+ .map((key) => [key, environmentValue(key)])
154
+ .filter(([, value]) => value !== undefined),
155
+ ),
156
+ ...binding.environment,
157
+ CC_MAX_RETRIES: "0",
158
+ CLAUDE_CODE_MAX_RETRIES: "0",
159
+ CLAUDECODE: "1",
160
+ }
161
+ : { ...inherited, CLAUDECODE: "1" };
97
162
  return new Promise((resolve) => {
98
163
  let args;
99
164
  if (opts._argv) {
@@ -115,12 +180,22 @@ function makeHeadlessRunAgent(opts = {}) {
115
180
  if (opts.provider) args.push("--provider", opts.provider);
116
181
  if (opts.ephemeral === true) args.push("--ephemeral");
117
182
  if (opts.sandboxMode) args.push("--sandbox-mode", opts.sandboxMode);
183
+ if (binding)
184
+ args.push(
185
+ "--no-project-memory",
186
+ "--no-file-refs",
187
+ "--no-slash-macros",
188
+ "--no-mcp",
189
+ "--no-ide",
190
+ "--no-pdh",
191
+ "--no-jetbrains",
192
+ );
118
193
  if (Number.isFinite(costBudgetUsd) && costBudgetUsd >= 0)
119
194
  args.push("--max-budget-usd", String(costBudgetUsd));
120
195
  }
121
196
  const child = _deps.spawn(process.execPath, args, {
122
197
  cwd,
123
- env: { ...process.env, ...(opts.env || {}), CLAUDECODE: "1" },
198
+ env: childEnvironment,
124
199
  windowsHide: true,
125
200
  // Own process group on POSIX so a timeout can reap the whole tree.
126
201
  detached: _deps.platform !== "win32",
@@ -417,6 +492,7 @@ export function registerEvalCommand(program, { logger } = {}) {
417
492
  ? {
418
493
  ephemeral: true,
419
494
  sandboxMode: tasks.verification.requiredSandboxMode,
495
+ requireVerify01Binding: true,
420
496
  }
421
497
  : {}),
422
498
  });
@@ -47,7 +47,10 @@ import {
47
47
  readLlmConnectionInput,
48
48
  saveLlmConnection,
49
49
  } from "../lib/llm-connection-config.js";
50
- import { probeLlmConnection } from "../lib/llm-connection-probe.js";
50
+ import {
51
+ probeLlmConnection,
52
+ llmProbeReceipt,
53
+ } from "../lib/llm-connection-probe.js";
51
54
  import { resolveModelCapabilityProfile } from "../lib/model-capabilities.js";
52
55
 
53
56
  /**
@@ -313,6 +316,10 @@ export function registerLlmCommand(program) {
313
316
  .option("--model <model>", "Model to test (default: configured)")
314
317
  .option("--base-url <url>", "API base URL (default: configured/provider)")
315
318
  .option("--api-key <key>", "API key (default: configured)")
319
+ .option(
320
+ "--json",
321
+ "Output connection result and token cost estimate as JSON",
322
+ )
316
323
  .action(async (options) => {
317
324
  const config = loadConfig();
318
325
  const target = resolveLlmTestTarget(
@@ -321,18 +328,46 @@ export function registerLlmCommand(program) {
321
328
  BUILT_IN_PROVIDERS,
322
329
  process.env,
323
330
  );
324
- const spinner = ora(`Testing ${target.provider}...`).start();
331
+ const spinner = options.json
332
+ ? null
333
+ : ora(`Testing ${target.provider}...`).start();
334
+ const safe = (text) =>
335
+ target.apiKey
336
+ ? String(text).replaceAll(target.apiKey, "[REDACTED]")
337
+ : String(text);
325
338
  try {
326
339
  const start = Date.now();
327
340
 
328
- const reply = await probeLlmConnection(target);
341
+ const reply = await probeLlmConnection(target, {
342
+ includeUsage: !!options.json,
343
+ });
344
+ if (options.json) {
345
+ console.log(
346
+ JSON.stringify({
347
+ ...reply,
348
+ reply: safe(reply.reply),
349
+ elapsedMs: Date.now() - start,
350
+ }),
351
+ );
352
+ return;
353
+ }
329
354
  spinner.succeed(
330
355
  `${chalk.green("Connected")} to ${target.label} (${target.model}) in ${Date.now() - start}ms`,
331
356
  );
332
357
  logger.log(` Response: ${chalk.gray(reply)}`);
333
358
  } catch (err) {
334
- spinner.fail(`Test failed: ${err.message}`);
335
- process.exit(1);
359
+ if (options.json) {
360
+ console.log(
361
+ JSON.stringify({
362
+ ...(err.probe || llmProbeReceipt(target)),
363
+ error: safe(err.message),
364
+ }),
365
+ );
366
+ process.exitCode = 1;
367
+ } else {
368
+ spinner.fail(`Test failed: ${err.message}`);
369
+ process.exit(1);
370
+ }
336
371
  }
337
372
  });
338
373
 
@@ -1,6 +1,19 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.166.98",
7
+ "cliVersions": ["0.166.98"],
8
+ "date": null,
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Fixed - cc CLI 0.166.98: apply real-task findings and preserve task delivery",
13
+ "body": "- Bind formal task file scope and tool allowlists to isolated per-task configuration;\n preserve rejected call identities and strict trace acceptance.\n- Keep authentication usage on failed answers, redact credentials before truncation,\n and separate tool estimates from unknown authentication or whole-journey costs.\n- Bootstrap first-run diagnostics without development dependencies and retain the\n actual failed journey, empty candidate, and unexecuted semantic outcomes.\n- Give finite-budget runs fresh delivery guidance without placing the changing\n counter before the stable OpenAI-compatible conversation prefix. Preserve the\n current user task across host and goal/hook suffixes in the canonical planner.\n- Publish changed Session Core 0.3.19 before CLI 0.166.98; retain unchanged child\n versions only after exact-source, registry-byte and provenance verification.\n- Pair VS Code 0.37.142 and JetBrains 0.4.160 after the final source gates pass\n and CLI 0.166.98 is publicly available. Formal 36+9 evaluation and native\n durable authority acceptance remain open."
14
+ }
15
+ ]
16
+ },
4
17
  {
5
18
  "productVersion": null,
6
19
  "cliVersion": "0.166.97",
@@ -68,8 +68,7 @@ function trustForBundle(messages) {
68
68
  if (
69
69
  messages.every(
70
70
  (message) =>
71
- message.role === "system" &&
72
- getDurableSystemMessageProvenance(message),
71
+ message.role === "system" && getDurableSystemMessageProvenance(message),
73
72
  )
74
73
  ) {
75
74
  return "verified";
@@ -135,12 +134,16 @@ function createItem({
135
134
  observedAt: new Date(sequence).toISOString(),
136
135
  },
137
136
  trust:
138
- trustedSystemPolicy && messages.every((message) => message.role === "system")
137
+ trustedSystemPolicy &&
138
+ messages.every((message) => message.role === "system")
139
139
  ? "host"
140
140
  : trustForBundle(messages),
141
141
  sensitivity: "personal",
142
142
  allowedSinks: allowedSinks || DEFAULT_ALLOWED_SINKS,
143
- tokenEstimate: Math.max(1, Math.ceil(Buffer.byteLength(content, "utf8") / 4)),
143
+ tokenEstimate: Math.max(
144
+ 1,
145
+ Math.ceil(Buffer.byteLength(content, "utf8") / 4),
146
+ ),
144
147
  priority: priorityForBundle(messages, sequence, pendingTool),
145
148
  pinned: false,
146
149
  createdAt: new Date(sequence).toISOString(),
@@ -195,7 +198,8 @@ export function messagesToContextItems(messagesInput, options = {}) {
195
198
  seen.add(resultId);
196
199
  cursor += 1;
197
200
  }
198
- const pending = ids.length !== calls.length || seen.size !== expected.size;
201
+ const pending =
202
+ ids.length !== calls.length || seen.size !== expected.size;
199
203
  const groupDigest = canonicalDigest(
200
204
  { sessionId, index, ids: [...expected].sort() },
201
205
  "chainlesschain.cli-tool-group/v1",
@@ -245,7 +249,14 @@ export function messagesToContextItems(messagesInput, options = {}) {
245
249
  );
246
250
  }
247
251
 
248
- const last = items.at(-1);
252
+ // Ephemeral host guidance and hook suffixes can follow the current user
253
+ // request. They must not turn that request into optional conversation.
254
+ // Stop at the last conversational/tool bundle, so completed historical
255
+ // user turns are not promoted over a newer assistant or tool result.
256
+ const lastIndex = items.findLastIndex(
257
+ (item) => item.kind !== "system-policy",
258
+ );
259
+ const last = items[lastIndex];
249
260
  if (last) {
250
261
  const payload = JSON.parse(last.content);
251
262
  if (payload.messages.at(-1)?.role === "user") {
@@ -257,7 +268,7 @@ export function messagesToContextItems(messagesInput, options = {}) {
257
268
  taskState: "waiting",
258
269
  requiredForRecovery: true,
259
270
  };
260
- items[items.length - 1] = normalizeContextItem(protectedItem);
271
+ items[lastIndex] = normalizeContextItem(protectedItem);
261
272
  }
262
273
  }
263
274
  return items;
@@ -317,7 +328,9 @@ export function memoryRecordsToContextItems(recordsInput, options = {}) {
317
328
 
318
329
  function decodeBundle(item) {
319
330
  if (typeof item?.content !== "string") {
320
- throw new TypeError(`ContextItem ${item?.itemId || "unknown"} has no inline content`);
331
+ throw new TypeError(
332
+ `ContextItem ${item?.itemId || "unknown"} has no inline content`,
333
+ );
321
334
  }
322
335
  const payload = JSON.parse(item.content);
323
336
  if (
@@ -327,17 +340,19 @@ function decodeBundle(item) {
327
340
  !Array.isArray(payload.durableSystemKinds) ||
328
341
  payload.durableSystemKinds.length !== payload.messages.length
329
342
  ) {
330
- throw new TypeError(`ContextItem ${item.itemId} is not a CLI message bundle`);
343
+ throw new TypeError(
344
+ `ContextItem ${item.itemId} is not a CLI message bundle`,
345
+ );
331
346
  }
332
347
  return payload.messages.map((message, index) => {
333
348
  if (!message || typeof message !== "object" || Array.isArray(message)) {
334
- throw new TypeError(`ContextItem ${item.itemId} contains an invalid message`);
349
+ throw new TypeError(
350
+ `ContextItem ${item.itemId} contains an invalid message`,
351
+ );
335
352
  }
336
353
  const copy = structuredClone(message);
337
354
  const durableKind = payload.durableSystemKinds[index];
338
- return durableKind
339
- ? markDurableSystemMessage(copy, durableKind)
340
- : copy;
355
+ return durableKind ? markDurableSystemMessage(copy, durableKind) : copy;
341
356
  });
342
357
  }
343
358
 
@@ -376,7 +391,9 @@ export function createSummaryContextItem({
376
391
  if (parents.length === 0) throw new TypeError("summary parents are required");
377
392
  const scope = parents[0].scope;
378
393
  const scopeId = parents[0].scopeId;
379
- if (parents.some((item) => item.scope !== scope || item.scopeId !== scopeId)) {
394
+ if (
395
+ parents.some((item) => item.scope !== scope || item.scopeId !== scopeId)
396
+ ) {
380
397
  throw new TypeError("summary parents must share one scope");
381
398
  }
382
399
  const summaryMessages = safeMessages(messages).map((message) =>
@@ -398,16 +415,16 @@ export function createSummaryContextItem({
398
415
  { operationId, parentDigests, content },
399
416
  "chainlesschain.cli-context-summary/v1",
400
417
  );
401
- const trust = TRUST_ORDER[
402
- Math.max(...parents.map((item) => TRUST_ORDER.indexOf(item.trust)))
403
- ];
404
- const sensitivity = SENSITIVITY_ORDER[
405
- Math.max(
406
- ...parents.map((item) =>
407
- SENSITIVITY_ORDER.indexOf(item.sensitivity),
408
- ),
409
- )
410
- ];
418
+ const trust =
419
+ TRUST_ORDER[
420
+ Math.max(...parents.map((item) => TRUST_ORDER.indexOf(item.trust)))
421
+ ];
422
+ const sensitivity =
423
+ SENSITIVITY_ORDER[
424
+ Math.max(
425
+ ...parents.map((item) => SENSITIVITY_ORDER.indexOf(item.sensitivity)),
426
+ )
427
+ ];
411
428
  const allowedSinks = [...intersectAllowedSinks(parents)].sort();
412
429
  if (allowedSinks.length === 0) {
413
430
  throw new TypeError("summary parents have no common allowed sink");
@@ -115,6 +115,24 @@ function directories(directory) {
115
115
  realpathSync(current) === `/private${current}`;
116
116
  if (!systemAlias && (!stat.isDirectory() || stat.isSymbolicLink()))
117
117
  throw corruptStore(current, "authority directory is unsafe");
118
+ if (process.platform === "win32") {
119
+ // Some Windows runtime adapters report an ordinary directory for a
120
+ // junction whose target cannot be decoded in their DOS namespace. Keep
121
+ // the lstat guard and independently reject a different native canonical
122
+ // coordinate before mkdir or lock acquisition. This is an additional
123
+ // consistency check, not a proof against every reparse tag or a race.
124
+ let canonical;
125
+ try {
126
+ canonical = realpathSync.native(current);
127
+ } catch {
128
+ throw corruptStore(current, "authority directory cannot be resolved");
129
+ }
130
+ if (
131
+ typeof canonical !== "string" ||
132
+ resolve(canonical).toLowerCase() !== current.toLowerCase()
133
+ )
134
+ throw corruptStore(current, "authority directory resolves elsewhere");
135
+ }
118
136
  const parent = dirname(current);
119
137
  if (parent === current) break;
120
138
  current = parent;
@@ -152,7 +152,13 @@ export async function runEvalSuite(tasks, opts = {}) {
152
152
  if (typeof task.check !== "function") {
153
153
  throw new Error(`task "${rec.id}": check() is required`);
154
154
  }
155
- dir = _deps.mkdtempSync(path.join(base, `cc-eval-${task.id}-`));
155
+ // Resolve the OS temporary directory first (macOS commonly aliases
156
+ // /var to /private/var), then create formal workspaces at canonical paths.
157
+ const taskBase =
158
+ typeof task.agentLaunchBinding === "function"
159
+ ? (fs.realpathSync.native || fs.realpathSync)(base)
160
+ : base;
161
+ dir = _deps.mkdtempSync(path.join(taskBase, `cc-eval-${task.id}-`));
156
162
  if (typeof task.setup === "function") {
157
163
  await task.setup(dir, budget);
158
164
  }
@@ -169,6 +175,9 @@ export async function runEvalSuite(tasks, opts = {}) {
169
175
  prompt: task.prompt,
170
176
  cwd: dir,
171
177
  timeoutMs: budget.remainingMs(),
178
+ ...(typeof task.agentLaunchBinding === "function"
179
+ ? { verify01Binding: task.agentLaunchBinding(dir) }
180
+ : {}),
172
181
  ...(task.costBudgetUsd === undefined
173
182
  ? {}
174
183
  : { costBudgetUsd: task.costBudgetUsd }),
@@ -234,6 +243,18 @@ export async function runEvalSuite(tasks, opts = {}) {
234
243
  });
235
244
  rec.pass = false;
236
245
  } finally {
246
+ try {
247
+ await task?.cleanup?.();
248
+ } catch (error) {
249
+ rec.pass = false;
250
+ rec.error ||= `task cleanup failed: ${error.message}`;
251
+ rec.failurePhase = "cleanup";
252
+ task.recordFailure?.({
253
+ phase: "cleanup",
254
+ code: error.code || null,
255
+ error: error.message,
256
+ });
257
+ }
237
258
  rec.ms = _deps.now() - started;
238
259
  if (span) {
239
260
  span.setAttribute("pass", rec.pass);
@@ -1,4 +1,9 @@
1
- import fs from "node:fs";
1
+ import { requireValue, relativeFile, readBytes } from "./verify01-workspace.js";
2
+ import {
3
+ LLM_PROBE_SCHEMA,
4
+ llmProbeReceipt,
5
+ priceLlmProbeUsage,
6
+ } from "../llm-connection-probe.js";
2
7
  import {
3
8
  createEvalComparison,
4
9
  EVAL_EXECUTION_PROTOCOL,
@@ -11,9 +16,92 @@ import {
11
16
  validateOutcomePlan,
12
17
  } from "./outcomes.js";
13
18
  const DIGEST = /^sha256:[a-f0-9]{64}$/u;
14
- const MAX_BYTES = 16 * 1024 * 1024;
15
- function requireValue(condition, message) {
16
- if (!condition) throw new Error(message);
19
+ /** Task terminals only cover the tool stage; authentication is a separate call. */
20
+ export function createVerify01FirstRunCost({
21
+ authentication,
22
+ authenticationReceipt,
23
+ authenticated,
24
+ comparison,
25
+ toolCostUsd,
26
+ }) {
27
+ requireValue(
28
+ DIGEST.test(authenticationReceipt || ""),
29
+ "first-run authentication receipt digest required",
30
+ );
31
+ requireValue(
32
+ toolCostUsd === null || (Number.isFinite(toolCostUsd) && toolCostUsd >= 0),
33
+ "invalid first-run tool cost",
34
+ );
35
+ let probe = null;
36
+ if (authentication !== null) {
37
+ requireValue(
38
+ authentication?.schema === LLM_PROBE_SCHEMA &&
39
+ authentication.provider === comparison.provider &&
40
+ authentication.model === comparison.model &&
41
+ authentication.ok === authenticated &&
42
+ authentication.currency === "USD" &&
43
+ authentication.costBasis === "token-estimate" &&
44
+ authentication.billingVerified === false,
45
+ "first-run authentication identity or estimate basis differs",
46
+ );
47
+ const usage = authentication.usage;
48
+ requireValue(
49
+ usage === null ||
50
+ (usage &&
51
+ [
52
+ usage.input_tokens,
53
+ usage.output_tokens,
54
+ usage.cache_read_input_tokens,
55
+ usage.cache_creation_input_tokens,
56
+ ].every((value) => Number.isSafeInteger(value) && value >= 0)),
57
+ "invalid first-run authentication usage",
58
+ );
59
+ const cost = priceLlmProbeUsage(comparison, usage);
60
+ requireValue(
61
+ authentication.totalCostUsd === cost,
62
+ "first-run authentication cost differs from its token estimate",
63
+ );
64
+ probe = llmProbeReceipt(comparison, { ok: authenticated, usage });
65
+ }
66
+ const authCostUsd = probe?.totalCostUsd ?? null;
67
+ const totalCostUsd =
68
+ authCostUsd !== null && toolCostUsd !== null
69
+ ? authCostUsd + toolCostUsd
70
+ : null;
71
+ requireValue(
72
+ totalCostUsd === null || Number.isFinite(totalCostUsd),
73
+ "first-run total cost overflow",
74
+ );
75
+ return {
76
+ schema: "chainlesschain.verify01-first-run-cost/v1",
77
+ authenticationReceipt,
78
+ authentication: probe,
79
+ toolCostUsd,
80
+ totalCostUsd,
81
+ };
82
+ }
83
+
84
+ function validateFirstRunCost(observation, comparison, toolCostUsd) {
85
+ const accounting = observation.firstRun?.costAccounting;
86
+ if (!accounting) {
87
+ requireValue(
88
+ observation.cost === null,
89
+ "first-run cost without authentication accounting must remain unknown",
90
+ );
91
+ return;
92
+ }
93
+ const expected = createVerify01FirstRunCost({
94
+ authentication: accounting.authentication,
95
+ authenticationReceipt: observation.firstRun.stages.authenticate.receipt,
96
+ authenticated: observation.firstRun.stages.authenticate.passed,
97
+ comparison,
98
+ toolCostUsd,
99
+ });
100
+ requireValue(
101
+ outcomeDigest(accounting) === outcomeDigest(expected) &&
102
+ observation.cost === expected.totalCostUsd,
103
+ "first-run journey cost differs from authentication plus tool cost",
104
+ );
17
105
  }
18
106
  function index(rows, key, label) {
19
107
  requireValue(Array.isArray(rows), `${label} must be an array`);
@@ -29,51 +117,6 @@ function index(rows, key, label) {
29
117
  }
30
118
  return result;
31
119
  }
32
- function relativeFile(value) {
33
- requireValue(
34
- typeof value === "string" &&
35
- value.length > 0 &&
36
- !/[\\:*?<>|"\u0000]/u.test(value) &&
37
- !value.startsWith("/") &&
38
- value.split("/").every((part) => part && !/[. ]$/u.test(part)),
39
- "review paths must be exact relative files",
40
- );
41
- return value;
42
- }
43
- function readBytes(file) {
44
- const descriptor = fs.openSync(file, "r");
45
- try {
46
- const before = fs.fstatSync(descriptor, { bigint: true });
47
- requireValue(
48
- before.isFile() && before.size <= BigInt(MAX_BYTES),
49
- "input must be a regular file within 16 MiB",
50
- );
51
- const bytes = Buffer.alloc(Number(before.size) + 1);
52
- let count = 0;
53
- while (count < bytes.length) {
54
- const size = fs.readSync(
55
- descriptor,
56
- bytes,
57
- count,
58
- bytes.length - count,
59
- null,
60
- );
61
- if (!size) break;
62
- count += size;
63
- }
64
- const after = fs.fstatSync(descriptor, { bigint: true });
65
- requireValue(
66
- count === Number(before.size) &&
67
- ["dev", "ino", "size", "mtimeNs", "ctimeNs"].every(
68
- (key) => before[key] === after[key],
69
- ),
70
- "input changed during read",
71
- );
72
- return bytes.subarray(0, count);
73
- } finally {
74
- fs.closeSync(descriptor);
75
- }
76
- }
77
120
  const readJson = (file) => JSON.parse(readBytes(file).toString("utf8"));
78
121
 
79
122
  export function validateVerify01Bundle({
@@ -278,6 +321,12 @@ export function validateVerify01Collection(
278
321
  row.reasons.every((reason) => failureReasons.has(reason)),
279
322
  "invalid first-run early-stop evidence",
280
323
  );
324
+ // A failed tool stage does not prove no billable request was attempted.
325
+ validateFirstRunCost(
326
+ observation,
327
+ bundle.bindings.comparisons[sample.stratum],
328
+ null,
329
+ );
281
330
  continue;
282
331
  }
283
332
  const run = runs.get(observation.runId);
@@ -309,10 +358,16 @@ export function validateVerify01Collection(
309
358
  used.add(key);
310
359
  const cost = result.totalCostUsd;
311
360
  requireValue(
312
- (cost === null || (Number.isFinite(cost) && cost >= 0)) &&
313
- observation.cost === cost,
361
+ cost === null || (Number.isFinite(cost) && cost >= 0),
314
362
  "unknown or mismatched cost must not become zero",
315
363
  );
364
+ if (sample.kind === "first-run")
365
+ validateFirstRunCost(observation, run.comparison, cost);
366
+ else
367
+ requireValue(
368
+ observation.cost === cost,
369
+ "unknown or mismatched cost must not become zero",
370
+ );
316
371
  requireValue(
317
372
  Array.isArray(result.changedFiles) &&
318
373
  new Set(result.changedFiles).size === result.changedFiles.length,