chainlesschain 0.166.87 → 0.166.89

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 (171) hide show
  1. package/README.md +31 -17
  2. package/package.json +1 -1
  3. package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
  4. package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
  5. package/src/assets/web-panel/assets/{AIOps-DdQjhXg9.js → AIOps-C8AkN9R5.js} +1 -1
  6. package/src/assets/web-panel/assets/{ActionButton-CuwA3hPA.js → ActionButton-BrAzSQor.js} +1 -1
  7. package/src/assets/web-panel/assets/{Analytics-DTVXJSAC.js → Analytics-Cu56X8Oh.js} +3 -3
  8. package/src/assets/web-panel/assets/{AppLayout-j06JBfEQ.js → AppLayout-BP1Riofl.js} +5 -5
  9. package/src/assets/web-panel/assets/{Artifacts-BFAK8LEW.js → Artifacts-CIW-nNAz.js} +1 -1
  10. package/src/assets/web-panel/assets/{Audit-BiGxRpOf.js → Audit-CJtDabk-.js} +1 -1
  11. package/src/assets/web-panel/assets/{BackgroundAgents-B6uHaPkZ.js → BackgroundAgents-DYIHeQ_P.js} +1 -1
  12. package/src/assets/web-panel/assets/{Backup-BNAesB8q.js → Backup-B4CsFzj7.js} +1 -1
  13. package/src/assets/web-panel/assets/{BaseInput-BOuetfCd.js → BaseInput-3eoJ5kfb.js} +1 -1
  14. package/src/assets/web-panel/assets/{Chat-cVzo3m_D.js → Chat-BBhX2L_E.js} +4 -4
  15. package/src/assets/web-panel/assets/ChatBubbleRenderer-RN8cbv7w.js +1 -0
  16. package/src/assets/web-panel/assets/{Checkbox-BaCTS-H8.js → Checkbox-5UvmwHVk.js} +1 -1
  17. package/src/assets/web-panel/assets/{Codegen-CBE8NiYh.js → Codegen-BFy8zsBN.js} +1 -1
  18. package/src/assets/web-panel/assets/{Col-C9wLiUTN.js → Col-4M6bKRRO.js} +1 -1
  19. package/src/assets/web-panel/assets/{Community-jdClBSIp.js → Community-D6LC0j7_.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compact-BIjauIlM.js → Compact-Dd48xMcv.js} +1 -1
  21. package/src/assets/web-panel/assets/{Compliance-CZ-AoaNj.js → Compliance-Ba85ggmy.js} +1 -1
  22. package/src/assets/web-panel/assets/{Cowork-BbTKtDS4.js → Cowork-D1BXlkuK.js} +2 -2
  23. package/src/assets/web-panel/assets/{Cron-ImKdtwNi.js → Cron-Ca2Uy7Ia.js} +2 -2
  24. package/src/assets/web-panel/assets/{Crosschain-B54GSHf5.js → Crosschain-C2bDRXZg.js} +1 -1
  25. package/src/assets/web-panel/assets/{DID-BQt5WUzs.js → DID-DySZKAJf.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dashboard--gNOffif.js → Dashboard-DDpYf-TT.js} +2 -2
  27. package/src/assets/web-panel/assets/{Dropdown-342A5YJw.js → Dropdown-DGjROfPv.js} +1 -1
  28. package/src/assets/web-panel/assets/{EmailListRenderer-CtIZ3ZHd.js → EmailListRenderer-DxX9QYiB.js} +1 -1
  29. package/src/assets/web-panel/assets/{EvolutionSettings-CyZPoTio.js → EvolutionSettings-TBCZyrSJ.js} +1 -1
  30. package/src/assets/web-panel/assets/{FamilyGuardDashboard-B1MCkFEu.js → FamilyGuardDashboard-BeqwTXBa.js} +1 -1
  31. package/src/assets/web-panel/assets/{Federation-DZWoERUy.js → Federation-CiCpKJQ1.js} +1 -1
  32. package/src/assets/web-panel/assets/{FormItemContext-Onmb0mp3.js → FormItemContext-CdTmbLkU.js} +1 -1
  33. package/src/assets/web-panel/assets/{GenericCardRenderer-u1qhNNc7.js → GenericCardRenderer-BwbkEY-5.js} +1 -1
  34. package/src/assets/web-panel/assets/{Git-BEowR1C5.js → Git-VnAga2vv.js} +2 -2
  35. package/src/assets/web-panel/assets/{Governance-BiYd3AAg.js → Governance-i-4Ebs-H.js} +1 -1
  36. package/src/assets/web-panel/assets/{Inference-CsC4Vjh5.js → Inference-CirjTgNw.js} +1 -1
  37. package/src/assets/web-panel/assets/{KnowledgeGraph-BXA7ikPM.js → KnowledgeGraph-CunS7vhA.js} +1 -1
  38. package/src/assets/web-panel/assets/Logs-DBuTF0c6.js +2 -0
  39. package/src/assets/web-panel/assets/MarkdownRenderer-B-iE-tt_.js +1 -0
  40. package/src/assets/web-panel/assets/{Marketplace-CCoJBfRL.js → Marketplace-BK6ZivTS.js} +1 -1
  41. package/src/assets/web-panel/assets/{McpTools-CzaOWBoA.js → McpTools-CUnCRnd3.js} +3 -3
  42. package/src/assets/web-panel/assets/{Memory-BPwh7u1-.js → Memory-CBGGr8Gy.js} +2 -2
  43. package/src/assets/web-panel/assets/{MobileBridge-Bk47v6z2.js → MobileBridge-reB6iaWD.js} +1 -1
  44. package/src/assets/web-panel/assets/{MobileProjects-D-CY--Sb.js → MobileProjects-o1YdVB7i.js} +1 -1
  45. package/src/assets/web-panel/assets/{Mtc-ExVyAGlW.js → Mtc-if5OE3GH.js} +2 -2
  46. package/src/assets/web-panel/assets/{MtcAudit-Rrw10csE.js → MtcAudit-BTZWpq0j.js} +5 -5
  47. package/src/assets/web-panel/assets/{Multisig-8TxxwxZZ.js → Multisig-8cvMAYFL.js} +3 -3
  48. package/src/assets/web-panel/assets/{NLProgramming-CNckjtnY.js → NLProgramming-BMvUXAWo.js} +1 -1
  49. package/src/assets/web-panel/assets/{Notes-C4j6cZTu.js → Notes-BWWjColh.js} +3 -3
  50. package/src/assets/web-panel/assets/{NotificationSettings-CchU8rWd.js → NotificationSettings-Ccr4lIhS.js} +1 -1
  51. package/src/assets/web-panel/assets/OrderTableRenderer-DhksGy6D.js +1 -0
  52. package/src/assets/web-panel/assets/{Organization-F0Je7EdZ.js → Organization-DciXQfdY.js} +2 -2
  53. package/src/assets/web-panel/assets/{Overflow-B2k-JA3u.js → Overflow-8DR7uMSx.js} +1 -1
  54. package/src/assets/web-panel/assets/{P2P-yui9Xxe6.js → P2P-DE6euHYl.js} +2 -2
  55. package/src/assets/web-panel/assets/{PdhVaultBrowser-CegM7hT6.js → PdhVaultBrowser-ByuWoauq.js} +4 -4
  56. package/src/assets/web-panel/assets/{Permissions-CSFL0uvh.js → Permissions-DkjM87ac.js} +4 -4
  57. package/src/assets/web-panel/assets/{PersonalDataHub-BrMcd-vr.js → PersonalDataHub-2DLp0KTL.js} +6 -6
  58. package/src/assets/web-panel/assets/{Pipeline-fzrliaVP.js → Pipeline-Ci2Qlkfr.js} +1 -1
  59. package/src/assets/web-panel/assets/{Privacy-BrkUjJ_g.js → Privacy-DlwDnDVA.js} +1 -1
  60. package/src/assets/web-panel/assets/{ProjectInit-CF_QCsW9.js → ProjectInit-CmMifW39.js} +2 -2
  61. package/src/assets/web-panel/assets/{ProjectSettings-Duwrd8aC.js → ProjectSettings-DJVFIh-6.js} +2 -2
  62. package/src/assets/web-panel/assets/{Projects-B0dLVXzU.js → Projects-P2nWBS70.js} +1 -1
  63. package/src/assets/web-panel/assets/{Providers-Db8iS1xQ.js → Providers-B2cxaGCU.js} +1 -1
  64. package/src/assets/web-panel/assets/{QrScannerModal-CHbNzEQs.js → QrScannerModal-CpO77kcE.js} +1 -1
  65. package/src/assets/web-panel/assets/{QuickAsk-CIESMfeR.js → QuickAsk-BDQl1hb0.js} +1 -1
  66. package/src/assets/web-panel/assets/{Recommend-BTMbCMtR.js → Recommend-DTD2f3IN.js} +1 -1
  67. package/src/assets/web-panel/assets/{RemoteSession-DavyK6J-.js → RemoteSession-DGZAnwvs.js} +3 -3
  68. package/src/assets/web-panel/assets/{Reputation-BFKtMelA.js → Reputation-B_R4vitb.js} +1 -1
  69. package/src/assets/web-panel/assets/{Row-BI9AZUvw.js → Row-4Jj6JyXN.js} +1 -1
  70. package/src/assets/web-panel/assets/{RssFeed-1nwXt8NY.js → RssFeed-D1t1MCZ-.js} +2 -2
  71. package/src/assets/web-panel/assets/{Search-Ck8PDYbk.js → Search-CyOUlIn7.js} +1 -1
  72. package/src/assets/web-panel/assets/{Security-BgDqpCbq.js → Security-BmknPT5Q.js} +4 -4
  73. package/src/assets/web-panel/assets/{Services-DF8anXm4.js → Services-DkEK8mpa.js} +2 -2
  74. package/src/assets/web-panel/assets/{Skeleton-CoHyY4ZX.js → Skeleton-Bvo5bpuk.js} +1 -1
  75. package/src/assets/web-panel/assets/Skills-AMmG8fim.js +1 -0
  76. package/src/assets/web-panel/assets/{Sla-XuOawvQY.js → Sla-Dl7-OKOV.js} +1 -1
  77. package/src/assets/web-panel/assets/{SpeechSettings-DFJ7nAiu.js → SpeechSettings-DtiGKu0E.js} +1 -1
  78. package/src/assets/web-panel/assets/{SyncSettings-B2xYj-Pi.js → SyncSettings-Ch7mp3ES.js} +2 -2
  79. package/src/assets/web-panel/assets/Tasks-Ck-sEgj-.js +1 -0
  80. package/src/assets/web-panel/assets/{Templates-BXFmKh7W.js → Templates-BlV22Il8.js} +1 -1
  81. package/src/assets/web-panel/assets/{Tenant-CRg2AXbd.js → Tenant-CaaAu0mX.js} +1 -1
  82. package/src/assets/web-panel/assets/{Terminal-DQgxnuep.js → Terminal-lA9g3FtJ.js} +2 -2
  83. package/src/assets/web-panel/assets/{TimelineRenderer-BrPQhQVc.js → TimelineRenderer-CG26IFC3.js} +1 -1
  84. package/src/assets/web-panel/assets/{Tokens-RByy4USy.js → Tokens-iaJUBLBm.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trigger-pE3y8u73.js → Trigger-DWQJtLK3.js} +1 -1
  86. package/src/assets/web-panel/assets/{Trust-DhID9C33.js → Trust-CTjmUwqp.js} +1 -1
  87. package/src/assets/web-panel/assets/{UkeySign-CPxEPNBH.js → UkeySign-CMnxufgD.js} +1 -1
  88. package/src/assets/web-panel/assets/{VideoEditing-ZD8DUxeQ.js → VideoEditing-diCFSWJw.js} +1 -1
  89. package/src/assets/web-panel/assets/{Wallet-Br9JREEd.js → Wallet-Ba1oND1K.js} +4 -4
  90. package/src/assets/web-panel/assets/{WebAuthn-Cn-YacJg.js → WebAuthn-DZDqPS-S.js} +4 -4
  91. package/src/assets/web-panel/assets/{WorkflowEditor-BTu0oqMp.js → WorkflowEditor-CfN8fPMe.js} +1 -1
  92. package/src/assets/web-panel/assets/{chat-CEjws_QF.js → chat-BiqMsO_i.js} +1 -1
  93. package/src/assets/web-panel/assets/{colors-Bv2RNebW.js → colors-By8LkjqH.js} +1 -1
  94. package/src/assets/web-panel/assets/{compact-item-gSc3EofP.js → compact-item-B0mxvRe3.js} +1 -1
  95. package/src/assets/web-panel/assets/{createContext-kyFDaqWC.js → createContext-Li2ub348.js} +1 -1
  96. package/src/assets/web-panel/assets/devWarning-D90arbUg.js +1 -0
  97. package/src/assets/web-panel/assets/{hasIn-BuMWcjhx.js → hasIn-DYbHPkbl.js} +1 -1
  98. package/src/assets/web-panel/assets/{index-C9U9SjcT.js → index-1lVoRUrQ.js} +1 -1
  99. package/src/assets/web-panel/assets/{index-BUOCcXou.js → index-B0D0HkkM.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-CNt2X-aK.js → index-BFhksbXp.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-BCS5j4SQ.js → index-BRzewWeE.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-42PTBO7a.js → index-BSk0xuXP.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-DRa4R7vv.js → index-BZqTG7fP.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-q65c1kp8.js → index-Bc6bxU24.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-xfS_WO9b.js → index-BcOJEgBE.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-Czo_hw97.js → index-Bd5znvCV.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-CMS3Mk93.js → index-Bm2P2Kgp.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-NQ0c4hJ1.js → index-ByqFKMWL.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-CkfvP2dN.js → index-C-RE3mFh.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-EpxWlmip.js → index-C5Se6Lnv.js} +1 -1
  111. package/src/assets/web-panel/assets/{index-jmMAqBAm.js → index-CA0AOURT.js} +1 -1
  112. package/src/assets/web-panel/assets/{index-Dej4AGOz.js → index-CEp_3fKJ.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-GpvWtvw3.js → index-CGZzexNa.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-OjZUHz5z.js → index-CHgiSV6R.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-Bg5jis0q.js → index-CMh3VxgO.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-DR561Sqc.js → index-CTVPeUh3.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-D3m3EXbL.js → index-CVZNYRzM.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-C7Jo20JB.js → index-CYv3JIzl.js} +1 -1
  119. package/src/assets/web-panel/assets/index-CeP1oROI.js +1 -0
  120. package/src/assets/web-panel/assets/{index-DYcPWVN9.js → index-CgyrklzQ.js} +1 -1
  121. package/src/assets/web-panel/assets/{index-DYKSuD02.js → index-ClsJN8sW.js} +3 -3
  122. package/src/assets/web-panel/assets/{index-Cj4RA7oA.js → index-Cpfn4YbT.js} +1 -1
  123. package/src/assets/web-panel/assets/index-Cu9gkyRc.js +1 -0
  124. package/src/assets/web-panel/assets/{index-U-ytt84A.js → index-Czt7WAtA.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-DbkyTMj-.js → index-D6qL3QBU.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-C56Drzol.js → index-DAOpBv3C.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-CF3TjDNz.js → index-DB4DCzqU.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-sJ1F5Txa.js → index-DIImi0cd.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-CvSuM_CB.js → index-DPRgnazi.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BSSIJ-rv.js → index-DgMFnBOv.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-nLemnBZ2.js → index-KWt8Owo8.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DbVUA5l3.js → index-KqfqSdAC.js} +1 -1
  133. package/src/assets/web-panel/assets/{index--nrQmk8X.js → index-b4O_YBVR.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-C-LPpwe9.js → index-beDji-cB.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-Cm8K8Evn.js → index-hw3sCYAz.js} +1 -1
  136. package/src/assets/web-panel/assets/{index-_0bfDTDu.js → index-zSzXsF9b.js} +1 -1
  137. package/src/assets/web-panel/assets/{initDefaultProps-B-wqiSu7.js → initDefaultProps-TgDL_7OY.js} +1 -1
  138. package/src/assets/web-panel/assets/{motion-BK4_B4MD.js → motion-fHosyV5c.js} +1 -1
  139. package/src/assets/web-panel/assets/{move-BU2TgDDO.js → move-C_QfW5qg.js} +1 -1
  140. package/src/assets/web-panel/assets/{mtc-parser-DA3E4_EX.js → mtc-parser-u7ywDVOg.js} +1 -1
  141. package/src/assets/web-panel/assets/{omit-CaHz1e_q.js → omit-BEJdUgE9.js} +1 -1
  142. package/src/assets/web-panel/assets/{pickAttrs-NXZ19amf.js → pickAttrs-DGkQFAJ5.js} +1 -1
  143. package/src/assets/web-panel/assets/{placementArrow-BCXI9AHO.js → placementArrow-DUyZXAjt.js} +1 -1
  144. package/src/assets/web-panel/assets/{responsiveObserve-DdlZ9tLk.js → responsiveObserve-B4xDxO7Q.js} +1 -1
  145. package/src/assets/web-panel/assets/{slide-DCZm_Vc4.js → slide-B8WuJtst.js} +1 -1
  146. package/src/assets/web-panel/assets/{statusUtils-CuEULKQr.js → statusUtils-DLUqy7JO.js} +1 -1
  147. package/src/assets/web-panel/assets/{styleChecker-Bo_UXG8x.js → styleChecker-BYOJOyqL.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFlexGapSupport-B9PaTcFH.js → useFlexGapSupport-WChWQURv.js} +1 -1
  149. package/src/assets/web-panel/assets/{useFs-DwSTGdVR.js → useFs-vLNpm3dv.js} +1 -1
  150. package/src/assets/web-panel/assets/{usePersonalDataHub-FswSxnDC.js → usePersonalDataHub-DSZ8unoU.js} +1 -1
  151. package/src/assets/web-panel/assets/{vnode-EUztvYTj.js → vnode-C4Xf7Kg1.js} +1 -1
  152. package/src/assets/web-panel/assets/{zoom-D41MAgV-.js → zoom-BulmeAGy.js} +1 -1
  153. package/src/assets/web-panel/index.html +1 -1
  154. package/src/command-help-index.json +1 -1
  155. package/src/commands/agent-controlled-host.js +220 -0
  156. package/src/commands/agent.js +3 -1
  157. package/src/commands/eval.js +3 -54
  158. package/src/data/changelog.json +26 -0
  159. package/src/lib/eval/stream-terminal.js +51 -0
  160. package/src/lib/eval/verify01-execution.js +16 -1
  161. package/src/lib/eval/verify01-host-capture.js +430 -0
  162. package/src/lib/eval/verify01-host-evidence.js +604 -0
  163. package/src/assets/web-panel/assets/ChatBubbleRenderer-DZ2Ys-CI.js +0 -1
  164. package/src/assets/web-panel/assets/Logs-C9WoplQm.js +0 -2
  165. package/src/assets/web-panel/assets/MarkdownRenderer-DecEsXsy.js +0 -1
  166. package/src/assets/web-panel/assets/OrderTableRenderer-ZJBoyJ16.js +0 -1
  167. package/src/assets/web-panel/assets/Skills-dOaD4Ztl.js +0 -1
  168. package/src/assets/web-panel/assets/Tasks-D_SzNTLi.js +0 -1
  169. package/src/assets/web-panel/assets/devWarning-Dcc8pILJ.js +0 -1
  170. package/src/assets/web-panel/assets/index-05NB95_V.js +0 -1
  171. package/src/assets/web-panel/assets/index-Cb6q8wlI.js +0 -1
@@ -0,0 +1,220 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ import {
5
+ normalizeAgentSandbox,
6
+ assertSandboxCapabilities,
7
+ assertSandboxAvailable,
8
+ } from "../lib/agent-sandbox.js";
9
+ import { isFormalQualityHermeticRuntime } from "../lib/formal-quality-eval-runtime.js";
10
+ import { resolveCredentialEnvironmentValue } from "../lib/process-execution-broker/credential-transport.js";
11
+
12
+ const MAX_JSON_BYTES = 1024 * 1024;
13
+
14
+ function invalid(message, code = "CC_CONTROLLED_HOST_INVALID") {
15
+ return Object.assign(new Error(message), { code });
16
+ }
17
+
18
+ /** Read one bounded regular file through its opened identity, never create it. */
19
+ function readJson(file) {
20
+ if (typeof file !== "string" || !path.isAbsolute(file))
21
+ throw invalid("Controlled-host JSON paths must be absolute");
22
+ const before = fs.lstatSync(file, { bigint: true });
23
+ if (!before.isFile() || before.isSymbolicLink())
24
+ throw invalid("Controlled-host JSON must be a regular non-symlink file");
25
+ const fd = fs.openSync(file, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
26
+ try {
27
+ const opened = fs.fstatSync(fd, { bigint: true });
28
+ if (
29
+ !opened.isFile() ||
30
+ opened.dev !== before.dev ||
31
+ opened.ino !== before.ino ||
32
+ opened.size < 1n ||
33
+ opened.size > BigInt(MAX_JSON_BYTES)
34
+ )
35
+ throw invalid("Controlled-host JSON identity or size is invalid");
36
+ const bytes = Buffer.alloc(Number(opened.size) + 1);
37
+ let size = 0;
38
+ while (size < bytes.length) {
39
+ const read = fs.readSync(fd, bytes, size, bytes.length - size, null);
40
+ if (!read) break;
41
+ size += read;
42
+ }
43
+ const after = fs.fstatSync(fd, { bigint: true });
44
+ if (
45
+ BigInt(size) !== opened.size ||
46
+ after.size !== opened.size ||
47
+ after.mtimeNs !== opened.mtimeNs ||
48
+ after.ctimeNs !== opened.ctimeNs
49
+ )
50
+ throw invalid("Controlled-host JSON changed while reading");
51
+ const value = JSON.parse(
52
+ new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(0, size)),
53
+ );
54
+ if (!value || typeof value !== "object" || Array.isArray(value))
55
+ throw invalid("Controlled-host JSON must contain an object");
56
+ return value;
57
+ } finally {
58
+ fs.closeSync(fd);
59
+ }
60
+ }
61
+
62
+ /** Explicit one-shot entry. Provisioning is deliberately not available here. */
63
+ export async function runControlledHost(options, dependencies = {}) {
64
+ const platform = dependencies.platform ?? process.platform;
65
+ if (platform !== "linux")
66
+ throw invalid(
67
+ "Controlled-host permission authority requires Linux",
68
+ "CC_SETTINGS_AUTHORITY_PLATFORM_UNSUPPORTED",
69
+ );
70
+ const env = dependencies.env ?? process.env;
71
+ if (isFormalQualityHermeticRuntime(env))
72
+ throw invalid(
73
+ "Controlled-host authority cannot run in a hermetic evaluator that suppresses permission providers",
74
+ );
75
+ if (!/^[a-zA-Z0-9._:-]{1,128}$/.test(options.context || ""))
76
+ throw invalid("An explicit controlled-host context is required");
77
+ if (
78
+ (options.check === true) ===
79
+ (typeof options.prompt === "string" && options.prompt.trim().length > 0)
80
+ )
81
+ throw invalid("Choose exactly one of --check or a non-empty --prompt");
82
+ if (
83
+ !options.check &&
84
+ ["provider", "model", "baseUrl"].some(
85
+ (key) => typeof options[key] !== "string" || !options[key].trim(),
86
+ )
87
+ )
88
+ throw invalid("A run requires explicit --provider, --model and --base-url");
89
+ const maxTurns =
90
+ options.maxTurns === undefined ? 10 : Number(options.maxTurns);
91
+ if (!Number.isSafeInteger(maxTurns) || maxTurns < 1 || maxTurns > 100)
92
+ throw invalid("--max-turns must be an integer from 1 to 100");
93
+ if (!["text", "json", "stream-json"].includes(options.outputFormat || "text"))
94
+ throw invalid("--output-format must be text, json or stream-json");
95
+ const cwd = dependencies.cwd ?? process.cwd();
96
+ const launch = readJson(options.launch);
97
+ const settings = readJson(options.sandboxSettings);
98
+ if (settings.engine !== "docker-egress" || settings.enabled === false)
99
+ throw invalid(
100
+ "Controlled-host entry requires enabled docker-egress sandbox settings",
101
+ );
102
+ const sandbox = normalizeAgentSandbox(true, { cwd, settings, network: true });
103
+ assertSandboxCapabilities(sandbox, {
104
+ host: { platform, arch: process.arch, release: os.release() },
105
+ });
106
+ const open =
107
+ dependencies.openHost ??
108
+ (await import("../runtime/permission-authority-host.js"))
109
+ .openPermissionAuthorityHost;
110
+ const host = open({ launch, contextId: options.context, env });
111
+ try {
112
+ // Reopening never provisions; runtimeOptions checks the actual invocation
113
+ // workspace and rejects writable roots overlapping the fixed authority.
114
+ host.runtimeOptions({ cwd, sandbox });
115
+ if (options.check) {
116
+ const capabilities = host.capabilities(sandbox);
117
+ const report = {
118
+ schema: "chainlesschain.controlled-host-check/v1",
119
+ authorityIdentityVerified: true,
120
+ backendExecutionVerified: false,
121
+ backendAvailabilityProbed: false,
122
+ capabilities,
123
+ };
124
+ (dependencies.writeOut ?? ((text) => process.stdout.write(text)))(
125
+ JSON.stringify(report) + "\n",
126
+ );
127
+ return { exitCode: 0, report };
128
+ }
129
+ // Availability is checked before resolving credentials or calling a model.
130
+ (dependencies.assertAvailable ?? assertSandboxAvailable)(sandbox);
131
+ let apiKey;
132
+ if (options.apiKeyEnv) {
133
+ apiKey = await resolveCredentialEnvironmentValue(options.apiKeyEnv, {
134
+ env,
135
+ });
136
+ if (!apiKey)
137
+ throw invalid("The selected API key environment source is unavailable");
138
+ }
139
+ return await host.runHeadless(
140
+ {
141
+ cwd,
142
+ sandbox,
143
+ prompt: options.prompt,
144
+ provider: options.provider,
145
+ model: options.model,
146
+ baseUrl: options.baseUrl,
147
+ apiKey,
148
+ maxTurns,
149
+ outputFormat: options.outputFormat || "text",
150
+ permissionMode: "dontAsk",
151
+ useRegisteredMcp: false,
152
+ strictMcpConfig: true,
153
+ ide: false,
154
+ pdh: false,
155
+ jetbrains: false,
156
+ slashMacros: false,
157
+ expandFileRefs: false,
158
+ },
159
+ dependencies.runtimeDependencies,
160
+ );
161
+ } finally {
162
+ host.close();
163
+ }
164
+ }
165
+
166
+ export function registerControlledHostCommand(agent, dependencies = {}) {
167
+ agent
168
+ .command("controlled-host")
169
+ .description(
170
+ "Run against a pre-provisioned Linux permission authority (one-shot, dontAsk)",
171
+ )
172
+ .requiredOption(
173
+ "--launch <file>",
174
+ "Absolute pre-provisioned launch descriptor JSON",
175
+ )
176
+ .requiredOption("--context <id>", "Exact provisioned workspace context ID")
177
+ .requiredOption(
178
+ "--sandbox-settings <file>",
179
+ "Absolute docker-egress sandbox settings JSON",
180
+ )
181
+ .option(
182
+ "--check",
183
+ "Verify configuration and authority identity only; no backend or model execution",
184
+ )
185
+ .option(
186
+ "--prompt <text>",
187
+ "Run one headless task in the bound current workspace",
188
+ )
189
+ .option("--provider <name>", "Explicit model provider")
190
+ .option("--model <name>", "Explicit model name")
191
+ .option("--base-url <url>", "Explicit provider endpoint")
192
+ .option(
193
+ "--api-key-env <name>",
194
+ "Credential environment variable or broker reference",
195
+ )
196
+ .option("--max-turns <n>", "Maximum task turns, 1-100", "10")
197
+ .option("--output-format <format>", "text | json | stream-json", "text")
198
+ .action(async (options, command) => {
199
+ try {
200
+ // Parent agent flags are a different launch contract. Never silently
201
+ // ignore a supplied --yolo, --bg, --settings or model override there.
202
+ if (
203
+ agent.options.some(
204
+ (option) =>
205
+ agent.getOptionValueSource(option.attributeName()) === "cli",
206
+ )
207
+ )
208
+ throw invalid(
209
+ "Place only controlled-host options after the subcommand; parent agent flags are unsupported",
210
+ );
211
+ const outcome = await runControlledHost(command.opts(), dependencies);
212
+ process.exitCode = outcome.exitCode;
213
+ } catch (error) {
214
+ process.stderr.write(
215
+ `${error.code || "CC_CONTROLLED_HOST_FAILED"}: ${error.message}\n`,
216
+ );
217
+ process.exitCode = 1;
218
+ }
219
+ });
220
+ }
@@ -46,6 +46,7 @@ import {
46
46
  isFormalQualityHermeticRuntime,
47
47
  } from "../lib/formal-quality-eval-runtime.js";
48
48
  import { withQuietStdout } from "../runtime/quiet-stdout.js";
49
+ import { registerControlledHostCommand } from "./agent-controlled-host.js";
49
50
  import { resolveCredentialEnvironmentValue } from "../lib/process-execution-broker/credential-transport.js";
50
51
  import {
51
52
  captureClaudeStorageLaunchEnvironment,
@@ -290,7 +291,7 @@ export function registerAgentCommand(program, dependencies = {}) {
290
291
  : captureSkillRetrievalRevocationReader(
291
292
  dependencies.skillRetrievalRevocationReader,
292
293
  );
293
- program
294
+ const agent = program
294
295
  .command("agent")
295
296
  .aliases(["a", "exec"])
296
297
  .description(
@@ -2259,6 +2260,7 @@ export function registerAgentCommand(program, dependencies = {}) {
2259
2260
  // Interactive session ended (REPL closed) — settle the worktree.
2260
2261
  await _finishWorktree();
2261
2262
  });
2263
+ registerControlledHostCommand(agent, dependencies.controlledHost);
2262
2264
  }
2263
2265
 
2264
2266
  export function registerSubAgentV2Command(program) {
@@ -14,6 +14,7 @@ import path from "path";
14
14
  import { fileURLToPath } from "url";
15
15
  import { runEvalSuite } from "../lib/eval/runner.js";
16
16
  import { getSuite } from "../lib/eval/tasks.js";
17
+ import { verifyAgentTerminal } from "../lib/eval/stream-terminal.js";
17
18
  import { persistVerify01Receipts } from "../lib/eval/verify01-execution.js";
18
19
  import executionBroker from "../lib/process-execution-broker/index.js";
19
20
  import {
@@ -49,57 +50,6 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
49
50
  // This file is src/commands/eval.js → the CLI entry is bin/chainlesschain.js.
50
51
  const BIN = path.resolve(__dirname, "..", "..", "bin", "chainlesschain.js");
51
52
 
52
- function verifyAgentTerminal(output) {
53
- try {
54
- const events = output
55
- .split(/\r?\n/u)
56
- .filter((line) => line.trim())
57
- .map((line) => JSON.parse(line));
58
- const results = events.filter((event) => event?.type === "result");
59
- const terminal = results[0];
60
- const usage = terminal?.usage;
61
- const normalizedUsage =
62
- usage &&
63
- [
64
- usage.input_tokens,
65
- usage.output_tokens,
66
- usage.cache_read_input_tokens,
67
- usage.cache_creation_input_tokens,
68
- ].every((value) => Number.isSafeInteger(value) && value >= 0)
69
- ? {
70
- inputTokens: usage.input_tokens,
71
- outputTokens: usage.output_tokens,
72
- cacheReadInputTokens: usage.cache_read_input_tokens,
73
- cacheCreationInputTokens: usage.cache_creation_input_tokens,
74
- }
75
- : null;
76
- return {
77
- terminalVerified:
78
- results.length === 1 &&
79
- events.at(-1) === terminal &&
80
- terminal.subtype === "success" &&
81
- terminal.is_error === false &&
82
- !events.some((event) => event?.type === "error"),
83
- observedFallback: events.some((event) =>
84
- ["provider_fallback", "model_fallback"].includes(event?.subtype),
85
- ),
86
- usage: normalizedUsage,
87
- totalCostUsd:
88
- Number.isFinite(terminal?.total_cost_usd) &&
89
- terminal.total_cost_usd >= 0
90
- ? terminal.total_cost_usd
91
- : null,
92
- };
93
- } catch {
94
- return {
95
- terminalVerified: false,
96
- observedFallback: null,
97
- usage: null,
98
- totalCostUsd: null,
99
- };
100
- }
101
- }
102
-
103
53
  /**
104
54
  * Kill an agent child AND its tool grandchildren. A bare child.kill("SIGTERM")
105
55
  * only reaches the direct child (and on Windows TerminateProcess never reaches
@@ -542,9 +492,8 @@ export function registerEvalCommand(program, { logger } = {}) {
542
492
  }
543
493
  }
544
494
  try {
545
- const { exportTelemetryRecorder } = await import(
546
- "../lib/observability/index.js"
547
- );
495
+ const { exportTelemetryRecorder } =
496
+ await import("../lib/observability/index.js");
548
497
  exportTelemetryRecorder(recorder);
549
498
  } catch {
550
499
  // Collector export is best-effort and never changes evaluation gates.
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "source": "CHANGELOG.md",
3
3
  "releases": [
4
+ {
5
+ "productVersion": null,
6
+ "cliVersion": "0.166.89",
7
+ "cliVersions": ["0.166.89"],
8
+ "date": null,
9
+ "title": "",
10
+ "sections": [
11
+ {
12
+ "heading": "Added - cc CLI 0.166.89: IDE capture journeys and controlled Linux entry",
13
+ "body": "- Prepare and finish frozen IDE tasks with byte-pinned baselines, complete diffs,\n a shared deadline and real protocol/UI evidence from both IDE hosts.\n- Add explicit `agent controlled-host` for pre-provisioned Linux permission domains;\n configuration checks do not claim backend execution or provision new authority.\n- Pair VS Code `0.37.134` and JetBrains `0.4.152` with CLI `0.166.89` for\n opt-in panel capture, deterministic initial/restart diagnostics and retained\n process-cleanup evidence. Add official MCP stdio interoperability checks."
14
+ }
15
+ ]
16
+ },
17
+ {
18
+ "productVersion": null,
19
+ "cliVersion": "0.166.88",
20
+ "cliVersions": ["0.166.88"],
21
+ "date": null,
22
+ "title": "",
23
+ "sections": [
24
+ {
25
+ "heading": "Added - cc CLI 0.166.88: reviewed acceptance packs and host evidence import",
26
+ "body": "- Generate byte-pinned setup/check scripts for all 36 frozen tasks, including\n behavior mutants, bounded Linux Docker execution and raw acceptance receipts.\n- Import IDE and first-run evidence through existing Eval/outcome contracts,\n requiring input acceptance, terminal state, drained exit and complete file diffs.\n Explicit failures stay failures; missing cost and identity attestation stay unknown.\n- Pair VS Code `0.37.133` and JetBrains `0.4.151` with CLI `0.166.88` for optional\n ordered protocol capture. Full container, GUI, provider and billing acceptance\n remain open; the frozen 36+9 samples remain `NOT_RUN`."
27
+ }
28
+ ]
29
+ },
4
30
  {
5
31
  "productVersion": null,
6
32
  "cliVersion": "0.166.87",
@@ -0,0 +1,51 @@
1
+ /** Parse raw agent NDJSON. A declaration of success is never terminal evidence. */
2
+ export function verifyAgentTerminal(output) {
3
+ try {
4
+ const events = output
5
+ .split(/\r?\n/u)
6
+ .filter((line) => line.trim())
7
+ .map((line) => JSON.parse(line));
8
+ const results = events.filter((event) => event?.type === "result");
9
+ const terminal = results[0];
10
+ const usage = terminal?.usage;
11
+ const normalizedUsage =
12
+ usage &&
13
+ [
14
+ usage.input_tokens,
15
+ usage.output_tokens,
16
+ usage.cache_read_input_tokens,
17
+ usage.cache_creation_input_tokens,
18
+ ].every((value) => Number.isSafeInteger(value) && value >= 0)
19
+ ? {
20
+ inputTokens: usage.input_tokens,
21
+ outputTokens: usage.output_tokens,
22
+ cacheReadInputTokens: usage.cache_read_input_tokens,
23
+ cacheCreationInputTokens: usage.cache_creation_input_tokens,
24
+ }
25
+ : null;
26
+ return {
27
+ terminalVerified:
28
+ results.length === 1 &&
29
+ events.at(-1) === terminal &&
30
+ terminal.subtype === "success" &&
31
+ terminal.is_error === false &&
32
+ !events.some((event) => event?.type === "error"),
33
+ observedFallback: events.some((event) =>
34
+ ["provider_fallback", "model_fallback"].includes(event?.subtype),
35
+ ),
36
+ usage: normalizedUsage,
37
+ totalCostUsd:
38
+ Number.isFinite(terminal?.total_cost_usd) &&
39
+ terminal.total_cost_usd >= 0
40
+ ? terminal.total_cost_usd
41
+ : null,
42
+ };
43
+ } catch {
44
+ return {
45
+ terminalVerified: false,
46
+ observedFallback: null,
47
+ usage: null,
48
+ totalCostUsd: null,
49
+ };
50
+ }
51
+ }
@@ -19,6 +19,15 @@ export const VERIFY01_SUITES = [
19
19
  const MAX_SNAPSHOT_BYTES = 512 * 1024 * 1024;
20
20
  const MAX_DIFF_BYTES = 32 * 1024 * 1024;
21
21
 
22
+ // Host drivers use the same checkout, complete scan, dependency boundary and
23
+ // pinned evaluator processes as the CLI executor; no second diff contract.
24
+ export {
25
+ materializeCheckout as materializeVerify01Checkout,
26
+ snapshot as snapshotVerify01Workspace,
27
+ diff as diffVerify01Workspace,
28
+ reviewedProcess as runVerify01ReviewedProcess,
29
+ };
30
+
22
31
  function git(directory, args, options = {}) {
23
32
  return executionBroker.execFileSync("git", ["-C", directory, ...args], {
24
33
  encoding: "utf8",
@@ -328,7 +337,13 @@ function reviewedProcess(bytes, directory, reviewRoot, kind, timeout) {
328
337
  // operator code; their digest is not an independent-review attestation.
329
338
  const result = executionBroker.spawnSync(
330
339
  process.execPath,
331
- ["--input-type=module", "--eval", bytes.toString("utf8"), directory],
340
+ [
341
+ "--input-type=module",
342
+ "--eval",
343
+ bytes.toString("utf8"),
344
+ directory,
345
+ String(Date.now() + timeout),
346
+ ],
332
347
  {
333
348
  cwd: reviewRoot,
334
349
  encoding: "utf8",