chainlesschain 0.166.86 → 0.166.87

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 (182) 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-DZwiXAIh.js → AIOps-DdQjhXg9.js} +1 -1
  5. package/src/assets/web-panel/assets/{ActionButton-aNzXoIJP.js → ActionButton-CuwA3hPA.js} +1 -1
  6. package/src/assets/web-panel/assets/{Analytics-ETQk4ZXt.js → Analytics-DTVXJSAC.js} +3 -3
  7. package/src/assets/web-panel/assets/{AppLayout-D5oEbeEC.js → AppLayout-j06JBfEQ.js} +5 -5
  8. package/src/assets/web-panel/assets/{Artifacts-ja48FAne.js → Artifacts-BFAK8LEW.js} +1 -1
  9. package/src/assets/web-panel/assets/{Audit-DlN0YnDt.js → Audit-BiGxRpOf.js} +1 -1
  10. package/src/assets/web-panel/assets/{BackgroundAgents-CzvyNsRg.js → BackgroundAgents-B6uHaPkZ.js} +1 -1
  11. package/src/assets/web-panel/assets/{Backup-DXgEC2MQ.js → Backup-BNAesB8q.js} +1 -1
  12. package/src/assets/web-panel/assets/{BaseInput-D9XqejLx.js → BaseInput-BOuetfCd.js} +1 -1
  13. package/src/assets/web-panel/assets/{Chat-BTwuYUlN.js → Chat-cVzo3m_D.js} +4 -4
  14. package/src/assets/web-panel/assets/{ChatBubbleRenderer-0anIC2Wn.js → ChatBubbleRenderer-DZ2Ys-CI.js} +1 -1
  15. package/src/assets/web-panel/assets/{Checkbox-CLuaQbDt.js → Checkbox-BaCTS-H8.js} +1 -1
  16. package/src/assets/web-panel/assets/{Codegen-KwQUZs8A.js → Codegen-CBE8NiYh.js} +1 -1
  17. package/src/assets/web-panel/assets/{Col-BCmROkzc.js → Col-C9wLiUTN.js} +1 -1
  18. package/src/assets/web-panel/assets/{Community-CXlUEHR4.js → Community-jdClBSIp.js} +1 -1
  19. package/src/assets/web-panel/assets/{Compact-Dzx-lWI2.js → Compact-BIjauIlM.js} +1 -1
  20. package/src/assets/web-panel/assets/{Compliance-CfXW82FF.js → Compliance-CZ-AoaNj.js} +1 -1
  21. package/src/assets/web-panel/assets/{Cowork-DIISTRm2.js → Cowork-BbTKtDS4.js} +2 -2
  22. package/src/assets/web-panel/assets/{Cron-nyJ-KcFE.js → Cron-ImKdtwNi.js} +2 -2
  23. package/src/assets/web-panel/assets/{Crosschain-Dtv1E4cV.js → Crosschain-B54GSHf5.js} +1 -1
  24. package/src/assets/web-panel/assets/{DID-BCTpektS.js → DID-BQt5WUzs.js} +2 -2
  25. package/src/assets/web-panel/assets/{Dashboard-C1Q_m0So.js → Dashboard--gNOffif.js} +2 -2
  26. package/src/assets/web-panel/assets/{Dropdown-BrQ5_PPL.js → Dropdown-342A5YJw.js} +1 -1
  27. package/src/assets/web-panel/assets/{EmailListRenderer-DjoNlONP.js → EmailListRenderer-CtIZ3ZHd.js} +1 -1
  28. package/src/assets/web-panel/assets/{EvolutionSettings-DaGaE6bX.js → EvolutionSettings-CyZPoTio.js} +1 -1
  29. package/src/assets/web-panel/assets/{FamilyGuardDashboard-nJDWBECt.js → FamilyGuardDashboard-B1MCkFEu.js} +1 -1
  30. package/src/assets/web-panel/assets/{Federation-DhMUY_wG.js → Federation-DZWoERUy.js} +1 -1
  31. package/src/assets/web-panel/assets/{FormItemContext-CbONJPuc.js → FormItemContext-Onmb0mp3.js} +1 -1
  32. package/src/assets/web-panel/assets/{GenericCardRenderer-CDdX4dX-.js → GenericCardRenderer-u1qhNNc7.js} +1 -1
  33. package/src/assets/web-panel/assets/{Git-DXbDVJdR.js → Git-BEowR1C5.js} +2 -2
  34. package/src/assets/web-panel/assets/{Governance-DbAfAvs1.js → Governance-BiYd3AAg.js} +1 -1
  35. package/src/assets/web-panel/assets/{Inference-Dy-fGea2.js → Inference-CsC4Vjh5.js} +1 -1
  36. package/src/assets/web-panel/assets/{KnowledgeGraph-DAxRpGUF.js → KnowledgeGraph-BXA7ikPM.js} +1 -1
  37. package/src/assets/web-panel/assets/{Logs-5L1UCR8X.js → Logs-C9WoplQm.js} +2 -2
  38. package/src/assets/web-panel/assets/{MarkdownRenderer-u0FPafvT.js → MarkdownRenderer-DecEsXsy.js} +1 -1
  39. package/src/assets/web-panel/assets/{Marketplace-DUk_McDG.js → Marketplace-CCoJBfRL.js} +1 -1
  40. package/src/assets/web-panel/assets/{McpTools-B6PNsZ_p.js → McpTools-CzaOWBoA.js} +3 -3
  41. package/src/assets/web-panel/assets/{Memory-BUUs8j5F.js → Memory-BPwh7u1-.js} +2 -2
  42. package/src/assets/web-panel/assets/{MobileBridge-pXRsgyuO.js → MobileBridge-Bk47v6z2.js} +1 -1
  43. package/src/assets/web-panel/assets/{MobileProjects-D7v-2Hwm.js → MobileProjects-D-CY--Sb.js} +1 -1
  44. package/src/assets/web-panel/assets/{Mtc-Deaj4faB.js → Mtc-ExVyAGlW.js} +4 -4
  45. package/src/assets/web-panel/assets/{MtcAudit-wUV0VUH1.js → MtcAudit-Rrw10csE.js} +5 -5
  46. package/src/assets/web-panel/assets/{Multisig-C67IIkts.js → Multisig-8TxxwxZZ.js} +3 -3
  47. package/src/assets/web-panel/assets/{NLProgramming-BCA_CWrW.js → NLProgramming-CNckjtnY.js} +1 -1
  48. package/src/assets/web-panel/assets/{Notes-D9eu14hQ.js → Notes-C4j6cZTu.js} +3 -3
  49. package/src/assets/web-panel/assets/{NotificationSettings-Cnd-J4LM.js → NotificationSettings-CchU8rWd.js} +1 -1
  50. package/src/assets/web-panel/assets/{OrderTableRenderer-C4pHUuyZ.js → OrderTableRenderer-ZJBoyJ16.js} +1 -1
  51. package/src/assets/web-panel/assets/{Organization-4YExAbnp.js → Organization-F0Je7EdZ.js} +4 -4
  52. package/src/assets/web-panel/assets/{Overflow-BF-wFuZz.js → Overflow-B2k-JA3u.js} +1 -1
  53. package/src/assets/web-panel/assets/{P2P-CdiajqCT.js → P2P-yui9Xxe6.js} +2 -2
  54. package/src/assets/web-panel/assets/{PdhVaultBrowser-BkjfS6Th.js → PdhVaultBrowser-CegM7hT6.js} +3 -3
  55. package/src/assets/web-panel/assets/{Permissions-DrZ4D78_.js → Permissions-CSFL0uvh.js} +4 -4
  56. package/src/assets/web-panel/assets/{PersonalDataHub-lDc6OXjz.js → PersonalDataHub-BrMcd-vr.js} +5 -5
  57. package/src/assets/web-panel/assets/{Pipeline-DqDS9ON1.js → Pipeline-fzrliaVP.js} +1 -1
  58. package/src/assets/web-panel/assets/{Privacy-BMekZRZu.js → Privacy-BrkUjJ_g.js} +1 -1
  59. package/src/assets/web-panel/assets/{ProjectInit-LYS7NFvJ.js → ProjectInit-CF_QCsW9.js} +2 -2
  60. package/src/assets/web-panel/assets/{ProjectSettings-CcJNHk9A.js → ProjectSettings-Duwrd8aC.js} +2 -2
  61. package/src/assets/web-panel/assets/{Projects-DrfAHgdF.js → Projects-B0dLVXzU.js} +1 -1
  62. package/src/assets/web-panel/assets/{Providers-aqsly9SR.js → Providers-Db8iS1xQ.js} +1 -1
  63. package/src/assets/web-panel/assets/{QrScannerModal-ZWvR3zqg.js → QrScannerModal-CHbNzEQs.js} +1 -1
  64. package/src/assets/web-panel/assets/{QuickAsk-BT5CgsvW.js → QuickAsk-CIESMfeR.js} +1 -1
  65. package/src/assets/web-panel/assets/{Recommend-Cz8Dz2RN.js → Recommend-BTMbCMtR.js} +1 -1
  66. package/src/assets/web-panel/assets/{RemoteSession-BlxPVbtQ.js → RemoteSession-DavyK6J-.js} +3 -3
  67. package/src/assets/web-panel/assets/{Reputation-B3VGBE-1.js → Reputation-BFKtMelA.js} +1 -1
  68. package/src/assets/web-panel/assets/{Row-Bwv7vSEA.js → Row-BI9AZUvw.js} +1 -1
  69. package/src/assets/web-panel/assets/{RssFeed-DHI085r_.js → RssFeed-1nwXt8NY.js} +2 -2
  70. package/src/assets/web-panel/assets/{Search-DBler5T0.js → Search-Ck8PDYbk.js} +1 -1
  71. package/src/assets/web-panel/assets/{Security-BZdw43NW.js → Security-BgDqpCbq.js} +3 -3
  72. package/src/assets/web-panel/assets/{Services-Cslk5lUj.js → Services-DF8anXm4.js} +2 -2
  73. package/src/assets/web-panel/assets/{Skeleton-Bur-C-25.js → Skeleton-CoHyY4ZX.js} +1 -1
  74. package/src/assets/web-panel/assets/{Skills-v0zgLy0X.js → Skills-dOaD4Ztl.js} +1 -1
  75. package/src/assets/web-panel/assets/{Sla-B1OWgQ51.js → Sla-XuOawvQY.js} +1 -1
  76. package/src/assets/web-panel/assets/{SpeechSettings-CaBcEaV4.js → SpeechSettings-DFJ7nAiu.js} +1 -1
  77. package/src/assets/web-panel/assets/{SyncSettings-CBbG8L6J.js → SyncSettings-B2xYj-Pi.js} +2 -2
  78. package/src/assets/web-panel/assets/{Tasks-C7EjXrnN.js → Tasks-D_SzNTLi.js} +1 -1
  79. package/src/assets/web-panel/assets/{Templates-VBBOZ1H5.js → Templates-BXFmKh7W.js} +1 -1
  80. package/src/assets/web-panel/assets/{Tenant-CtQTj7IF.js → Tenant-CRg2AXbd.js} +1 -1
  81. package/src/assets/web-panel/assets/{Terminal-DXVTQjnl.js → Terminal-DQgxnuep.js} +2 -2
  82. package/src/assets/web-panel/assets/{TimelineRenderer-BRIno0aN.js → TimelineRenderer-BrPQhQVc.js} +1 -1
  83. package/src/assets/web-panel/assets/{Tokens-uiiAfkYN.js → Tokens-RByy4USy.js} +1 -1
  84. package/src/assets/web-panel/assets/{Trigger-CPApN8o6.js → Trigger-pE3y8u73.js} +1 -1
  85. package/src/assets/web-panel/assets/{Trust-T2jKVwCE.js → Trust-DhID9C33.js} +1 -1
  86. package/src/assets/web-panel/assets/{UkeySign-C2U_gbzP.js → UkeySign-CPxEPNBH.js} +1 -1
  87. package/src/assets/web-panel/assets/{VideoEditing-BCdlr3Kj.js → VideoEditing-ZD8DUxeQ.js} +1 -1
  88. package/src/assets/web-panel/assets/{Wallet-CWnjoSc1.js → Wallet-Br9JREEd.js} +4 -4
  89. package/src/assets/web-panel/assets/{WebAuthn-CqSbYqHq.js → WebAuthn-Cn-YacJg.js} +4 -4
  90. package/src/assets/web-panel/assets/{WorkflowEditor-Dr_I3jcr.js → WorkflowEditor-BTu0oqMp.js} +1 -1
  91. package/src/assets/web-panel/assets/{chat-Cg21FKdE.js → chat-CEjws_QF.js} +1 -1
  92. package/src/assets/web-panel/assets/{colors-CK85tY9e.js → colors-Bv2RNebW.js} +1 -1
  93. package/src/assets/web-panel/assets/{compact-item-m-XYPC7W.js → compact-item-gSc3EofP.js} +1 -1
  94. package/src/assets/web-panel/assets/{createContext-BmiEeNvs.js → createContext-kyFDaqWC.js} +1 -1
  95. package/src/assets/web-panel/assets/devWarning-Dcc8pILJ.js +1 -0
  96. package/src/assets/web-panel/assets/{hasIn-CCw4KAoc.js → hasIn-BuMWcjhx.js} +1 -1
  97. package/src/assets/web-panel/assets/{index-ByVvAXdl.js → index--nrQmk8X.js} +1 -1
  98. package/src/assets/web-panel/assets/index-05NB95_V.js +1 -0
  99. package/src/assets/web-panel/assets/{index-BIOTRzaF.js → index-42PTBO7a.js} +1 -1
  100. package/src/assets/web-panel/assets/{index-8KzhlvJ9.js → index-BCS5j4SQ.js} +1 -1
  101. package/src/assets/web-panel/assets/{index-lhoexBDH.js → index-BSSIJ-rv.js} +1 -1
  102. package/src/assets/web-panel/assets/{index-6jXf-Lln.js → index-BUOCcXou.js} +1 -1
  103. package/src/assets/web-panel/assets/{index-D7gS_TJl.js → index-Bg5jis0q.js} +1 -1
  104. package/src/assets/web-panel/assets/{index-BtvVupUL.js → index-C-LPpwe9.js} +1 -1
  105. package/src/assets/web-panel/assets/{index-BGb1j2z9.js → index-C56Drzol.js} +1 -1
  106. package/src/assets/web-panel/assets/{index-DpIy2HzE.js → index-C7Jo20JB.js} +1 -1
  107. package/src/assets/web-panel/assets/{index-Cf5arJie.js → index-C9U9SjcT.js} +1 -1
  108. package/src/assets/web-panel/assets/{index-CBcgIWOe.js → index-CF3TjDNz.js} +1 -1
  109. package/src/assets/web-panel/assets/{index-J81uvUMN.js → index-CMS3Mk93.js} +1 -1
  110. package/src/assets/web-panel/assets/{index-BGUYgc96.js → index-CNt2X-aK.js} +1 -1
  111. package/src/assets/web-panel/assets/index-Cb6q8wlI.js +1 -0
  112. package/src/assets/web-panel/assets/{index-CN2xbLGz.js → index-Cj4RA7oA.js} +1 -1
  113. package/src/assets/web-panel/assets/{index-D1sU5-XA.js → index-CkfvP2dN.js} +1 -1
  114. package/src/assets/web-panel/assets/{index-DmSgfXuz.js → index-Cm8K8Evn.js} +1 -1
  115. package/src/assets/web-panel/assets/{index-DMbrl43d.js → index-CvSuM_CB.js} +1 -1
  116. package/src/assets/web-panel/assets/{index-B7xJkhtJ.js → index-Czo_hw97.js} +1 -1
  117. package/src/assets/web-panel/assets/{index-BvjC3t35.js → index-D3m3EXbL.js} +1 -1
  118. package/src/assets/web-panel/assets/{index-DAlGVix-.js → index-DR561Sqc.js} +1 -1
  119. package/src/assets/web-panel/assets/{index-B8IC9ZeZ.js → index-DRa4R7vv.js} +1 -1
  120. package/src/assets/web-panel/assets/{index-yYmjkf38.js → index-DYKSuD02.js} +3 -3
  121. package/src/assets/web-panel/assets/{index-Br9t_I1X.js → index-DYcPWVN9.js} +1 -1
  122. package/src/assets/web-panel/assets/{index-Bv90WEWa.js → index-DbVUA5l3.js} +1 -1
  123. package/src/assets/web-panel/assets/{index-BiVPFsat.js → index-DbkyTMj-.js} +1 -1
  124. package/src/assets/web-panel/assets/{index-IskAKXhx.js → index-Dej4AGOz.js} +1 -1
  125. package/src/assets/web-panel/assets/{index-CYEzWoyZ.js → index-EpxWlmip.js} +1 -1
  126. package/src/assets/web-panel/assets/{index-Br0ZNdu1.js → index-GpvWtvw3.js} +1 -1
  127. package/src/assets/web-panel/assets/{index-DIlGxS2W.js → index-NQ0c4hJ1.js} +1 -1
  128. package/src/assets/web-panel/assets/{index-sWUmvT8H.js → index-OjZUHz5z.js} +1 -1
  129. package/src/assets/web-panel/assets/{index-OIbfsi-o.js → index-U-ytt84A.js} +1 -1
  130. package/src/assets/web-panel/assets/{index-BUYyhYP6.js → index-_0bfDTDu.js} +1 -1
  131. package/src/assets/web-panel/assets/{index-DxRhnsEC.js → index-jmMAqBAm.js} +1 -1
  132. package/src/assets/web-panel/assets/{index-DI9GJFcn.js → index-nLemnBZ2.js} +1 -1
  133. package/src/assets/web-panel/assets/{index-BStyjmLG.js → index-q65c1kp8.js} +1 -1
  134. package/src/assets/web-panel/assets/{index-BHsiSoGY.js → index-sJ1F5Txa.js} +1 -1
  135. package/src/assets/web-panel/assets/{index-BcfVHmFK.js → index-xfS_WO9b.js} +1 -1
  136. package/src/assets/web-panel/assets/{initDefaultProps-Cc1XOmNe.js → initDefaultProps-B-wqiSu7.js} +1 -1
  137. package/src/assets/web-panel/assets/{motion-BehsX88u.js → motion-BK4_B4MD.js} +1 -1
  138. package/src/assets/web-panel/assets/{move-BPx2YsqY.js → move-BU2TgDDO.js} +1 -1
  139. package/src/assets/web-panel/assets/{mtc-parser-BSFJgFQA.js → mtc-parser-DA3E4_EX.js} +1 -1
  140. package/src/assets/web-panel/assets/{omit-DBN5KUeo.js → omit-CaHz1e_q.js} +1 -1
  141. package/src/assets/web-panel/assets/{pickAttrs-BDK1yZ-9.js → pickAttrs-NXZ19amf.js} +1 -1
  142. package/src/assets/web-panel/assets/{placementArrow-C4rMmKNJ.js → placementArrow-BCXI9AHO.js} +1 -1
  143. package/src/assets/web-panel/assets/{responsiveObserve-BoeoOnxX.js → responsiveObserve-DdlZ9tLk.js} +1 -1
  144. package/src/assets/web-panel/assets/{slide-BKlr1bl9.js → slide-DCZm_Vc4.js} +1 -1
  145. package/src/assets/web-panel/assets/{statusUtils-Ky1apWPI.js → statusUtils-CuEULKQr.js} +1 -1
  146. package/src/assets/web-panel/assets/{styleChecker-DxxR7uXk.js → styleChecker-Bo_UXG8x.js} +1 -1
  147. package/src/assets/web-panel/assets/{useFlexGapSupport-DmsUqVe9.js → useFlexGapSupport-B9PaTcFH.js} +1 -1
  148. package/src/assets/web-panel/assets/{useFs-CwkG7sOg.js → useFs-DwSTGdVR.js} +1 -1
  149. package/src/assets/web-panel/assets/{usePersonalDataHub-CddgeEfF.js → usePersonalDataHub-FswSxnDC.js} +1 -1
  150. package/src/assets/web-panel/assets/{vnode-C_-H8i4Y.js → vnode-EUztvYTj.js} +1 -1
  151. package/src/assets/web-panel/assets/{zoom-aAsHUMNE.js → zoom-D41MAgV-.js} +1 -1
  152. package/src/assets/web-panel/index.html +1 -1
  153. package/src/command-help-index.json +1 -1
  154. package/src/commands/eval.js +118 -18
  155. package/src/commands/memory.js +34 -15
  156. package/src/commands/sandbox.js +9 -0
  157. package/src/data/changelog.json +13 -0
  158. package/src/lib/causal-observability.js +6 -45
  159. package/src/lib/context-memory-kernel/durable-memory-port.js +49 -10
  160. package/src/lib/context-memory-kernel/memory-query-index.js +278 -0
  161. package/src/lib/context-memory-kernel/memory-service.js +17 -2
  162. package/src/lib/context-memory-kernel/segmented-memory-port.js +277 -9
  163. package/src/lib/eval/outcomes.js +20 -10
  164. package/src/lib/eval/runner.js +49 -5
  165. package/src/lib/eval/tasks.js +8 -3
  166. package/src/lib/eval/verify01-contracts.js +349 -0
  167. package/src/lib/eval/verify01-execution.js +605 -0
  168. package/src/lib/execution-support.js +58 -0
  169. package/src/lib/llm-pricing.js +98 -11
  170. package/src/lib/model-catalog-review.js +116 -0
  171. package/src/lib/model-context-catalog.js +23 -1
  172. package/src/lib/openai-responses.js +39 -0
  173. package/src/lib/process-execution-broker/index.js +8 -0
  174. package/src/lib/process-execution-broker/linux-subreaper-process.js +24 -2
  175. package/src/lib/process-execution-broker/process-ownership-journal.js +168 -7
  176. package/src/lib/process-execution-broker/process-ownership-quarantine.js +56 -1
  177. package/src/lib/process-execution-broker/process-recovery-cgroup.js +272 -0
  178. package/src/runtime/agent-core.js +9 -24
  179. package/src/runtime/permission-authority-host.js +14 -0
  180. package/src/assets/web-panel/assets/devWarning-CkMEODFC.js +0 -1
  181. package/src/assets/web-panel/assets/index-BjE5qaKn.js +0 -1
  182. package/src/assets/web-panel/assets/index-CsFH-2Zk.js +0 -1
@@ -0,0 +1,605 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { createHash } from "node:crypto";
4
+ import executionBroker from "../process-execution-broker/index.js";
5
+ import { evalDigest, createEvalComparison } from "./evidence.js";
6
+ import { outcomeDigest } from "./outcomes.js";
7
+ import {
8
+ readBytes,
9
+ readJson,
10
+ relativeFile,
11
+ requireValue,
12
+ validateVerify01Review,
13
+ } from "./verify01-contracts.js";
14
+
15
+ export const VERIFY01_SUITES = [
16
+ "verify01-plan-2026-10-04",
17
+ "verify01-project-36",
18
+ ];
19
+ const MAX_SNAPSHOT_BYTES = 512 * 1024 * 1024;
20
+ const MAX_DIFF_BYTES = 32 * 1024 * 1024;
21
+
22
+ function git(directory, args, options = {}) {
23
+ return executionBroker.execFileSync("git", ["-C", directory, ...args], {
24
+ encoding: "utf8",
25
+ maxBuffer: 32 * 1024 * 1024,
26
+ timeout: 30000,
27
+ windowsHide: true,
28
+ origin: "eval:verify01-checkout",
29
+ policy: "allow",
30
+ scope: "eval",
31
+ shell: false,
32
+ ...options,
33
+ });
34
+ }
35
+
36
+ function within(root, file) {
37
+ const relative = path.relative(root, file);
38
+ requireValue(
39
+ relative &&
40
+ relative !== ".." &&
41
+ !relative.startsWith(`..${path.sep}`) &&
42
+ !path.isAbsolute(relative),
43
+ "path escapes its declared root",
44
+ );
45
+ }
46
+
47
+ function regularPath(root, relative) {
48
+ relativeFile(relative);
49
+ const file = path.join(root, relative);
50
+ within(root, file);
51
+ let current = root;
52
+ for (const segment of relative.split("/")) {
53
+ current = path.join(current, segment);
54
+ requireValue(
55
+ !fs.lstatSync(current).isSymbolicLink(),
56
+ "review/project paths must not traverse links",
57
+ );
58
+ }
59
+ requireValue(
60
+ fs.lstatSync(file).isFile(),
61
+ "review/project artifact must be a regular file",
62
+ );
63
+ return file;
64
+ }
65
+
66
+ /** Copy only committed blobs, checking their actual Git object identities.
67
+ * Untracked credentials, .git metadata, and development dependency junctions
68
+ * are never part of the evaluation checkout. Setup owns dependency preparation.
69
+ */
70
+ async function materializeCheckout(projectRoot, commit, destination, budget) {
71
+ requireValue(
72
+ git(projectRoot, ["rev-parse", "HEAD"]).trim() === commit,
73
+ "actual checkout SHA changed",
74
+ );
75
+ const entries = git(projectRoot, ["ls-tree", "-rz", "--full-tree", commit])
76
+ .split("\0")
77
+ .filter(Boolean)
78
+ .map((entry) => {
79
+ const match = /^(100644|100755) blob ([a-f0-9]{40})\t(.+)$/su.exec(entry);
80
+ requireValue(
81
+ match,
82
+ "evaluation checkout contains unsupported links or submodules",
83
+ );
84
+ relativeFile(match[3]);
85
+ return { mode: match[1], oid: match[2], relative: match[3] };
86
+ });
87
+ let total = 0;
88
+ // Read Git objects, rather than mutable checkout files or platform CRLF
89
+ // conversions. A single bounded batch avoids one Git process per file.
90
+ await new Promise((resolvePromise, reject) => {
91
+ const child = executionBroker.spawn(
92
+ "git",
93
+ ["-C", projectRoot, "cat-file", "--batch"],
94
+ {
95
+ windowsHide: true,
96
+ origin: "eval:verify01-checkout-blobs",
97
+ policy: "allow",
98
+ scope: "eval",
99
+ shell: false,
100
+ stdio: ["pipe", "pipe", "pipe"],
101
+ },
102
+ );
103
+ let pending = Buffer.alloc(0),
104
+ offset = 0,
105
+ size = null,
106
+ failed = false,
107
+ stderr = "";
108
+ const stop = (error) => {
109
+ if (failed) return;
110
+ failed = true;
111
+ clearTimeout(timer);
112
+ child.kill();
113
+ reject(error);
114
+ };
115
+ const timer = setTimeout(
116
+ () => stop(new Error("frozen checkout materialization timed out")),
117
+ Math.min(120000, budget.remainingMs("checkout")),
118
+ );
119
+ child.on("error", stop);
120
+ child.stderr.on("data", (bytes) => {
121
+ stderr = (stderr + bytes.toString("utf8")).slice(-4096);
122
+ });
123
+ child.stdout.on("data", (chunk) => {
124
+ if (failed) return;
125
+ try {
126
+ pending = Buffer.concat([pending, chunk]);
127
+ while (offset < entries.length) {
128
+ const entry = entries[offset];
129
+ if (size === null) {
130
+ const newline = pending.indexOf(10);
131
+ if (newline < 0) {
132
+ requireValue(pending.length < 128, "invalid Git batch header");
133
+ break;
134
+ }
135
+ const parts = pending
136
+ .subarray(0, newline)
137
+ .toString("utf8")
138
+ .split(" ");
139
+ requireValue(
140
+ parts.length === 3 &&
141
+ parts[0] === entry.oid &&
142
+ parts[1] === "blob",
143
+ "Git batch object mismatch",
144
+ );
145
+ size = Number(parts[2]);
146
+ requireValue(
147
+ Number.isSafeInteger(size) &&
148
+ size >= 0 &&
149
+ size <= 16 * 1024 * 1024,
150
+ "Git blob exceeds materialization bound",
151
+ );
152
+ pending = pending.subarray(newline + 1);
153
+ }
154
+ if (pending.length < size + 1) break;
155
+ const bytes = pending.subarray(0, size);
156
+ requireValue(pending[size] === 10, "invalid Git batch terminator");
157
+ total += size;
158
+ requireValue(
159
+ total <= MAX_SNAPSHOT_BYTES,
160
+ "evaluation checkout exceeds 512 MiB",
161
+ );
162
+ const actual = createHash("sha1")
163
+ .update(`blob ${size}\0`)
164
+ .update(bytes)
165
+ .digest("hex");
166
+ requireValue(actual === entry.oid, "Git blob digest mismatch");
167
+ const target = path.join(destination, entry.relative);
168
+ within(destination, target);
169
+ fs.mkdirSync(path.dirname(target), { recursive: true });
170
+ fs.writeFileSync(target, bytes, {
171
+ flag: "wx",
172
+ mode: entry.mode === "100755" ? 0o755 : 0o644,
173
+ });
174
+ pending = pending.subarray(size + 1);
175
+ size = null;
176
+ offset++;
177
+ }
178
+ } catch (error) {
179
+ stop(error);
180
+ }
181
+ });
182
+ child.on("close", (code, signal) => {
183
+ clearTimeout(timer);
184
+ if (failed) return;
185
+ if (code !== 0 || signal || offset !== entries.length || pending.length)
186
+ reject(new Error(`incomplete frozen Git checkout: ${stderr}`));
187
+ else resolvePromise();
188
+ });
189
+ child.stdin.on("error", stop);
190
+ child.stdin.end(entries.map((entry) => entry.oid).join("\n") + "\n");
191
+ });
192
+ return { commit, files: entries.length, bytes: total };
193
+ }
194
+
195
+ function snapshot(directory, budget, stage) {
196
+ const files = new Map();
197
+ let total = 0;
198
+ let dependencyBytes = 0;
199
+ let dependencyFiles = 0;
200
+ const dependencyHash = createHash("sha256");
201
+ const buffer = Buffer.alloc(64 * 1024);
202
+ const visit = (current) => {
203
+ for (const entry of fs
204
+ .readdirSync(current, { withFileTypes: true })
205
+ .sort((a, b) => a.name.localeCompare(b.name, "en"))) {
206
+ budget.remainingMs(stage);
207
+ const full = path.join(current, entry.name);
208
+ const relative = path.relative(directory, full).split(path.sep).join("/");
209
+ if (entry.isDirectory()) visit(full);
210
+ else {
211
+ requireValue(
212
+ entry.isFile() || entry.isSymbolicLink(),
213
+ "task snapshot contains an unsupported filesystem object",
214
+ );
215
+ // Preserve link identities without following them into another root.
216
+ const dependency = relative.split("/").includes("node_modules");
217
+ if (dependency && entry.isSymbolicLink()) {
218
+ // A dependency linked outside the isolated workspace cannot be
219
+ // fingerprinted by this capture contract; never silently omit it.
220
+ within(directory, fs.realpathSync(full));
221
+ }
222
+ let bytes = entry.isSymbolicLink()
223
+ ? Buffer.from(fs.readlinkSync(full))
224
+ : dependency
225
+ ? null
226
+ : readBytes(full);
227
+ let digest, size;
228
+ if (dependency && bytes === null) {
229
+ const hash = createHash("sha256");
230
+ const fd = fs.openSync(full, "r");
231
+ size = 0;
232
+ try {
233
+ let count;
234
+ while (
235
+ (count = fs.readSync(fd, buffer, 0, buffer.length, null)) > 0
236
+ ) {
237
+ budget.remainingMs(stage);
238
+ size += count;
239
+ requireValue(
240
+ dependencyBytes + size <= 16 * 1024 ** 3,
241
+ "dependency fingerprint exceeds 16 GiB",
242
+ );
243
+ hash.update(buffer.subarray(0, count));
244
+ }
245
+ } finally {
246
+ fs.closeSync(fd);
247
+ }
248
+ digest = `sha256:${hash.digest("hex")}`;
249
+ } else {
250
+ size = bytes.length;
251
+ digest = evalDigest(bytes);
252
+ }
253
+ if (dependency) {
254
+ dependencyBytes += size;
255
+ dependencyFiles++;
256
+ bytes = null;
257
+ } else total += size;
258
+ requireValue(
259
+ total <= MAX_SNAPSHOT_BYTES &&
260
+ files.size - dependencyFiles < 100000 &&
261
+ dependencyFiles <= 1000000,
262
+ "task snapshot exceeds its capture bound",
263
+ );
264
+ const value = {
265
+ type: entry.isSymbolicLink() ? "link" : "file",
266
+ mode: fs.lstatSync(full).mode & 0o777,
267
+ bytes,
268
+ size,
269
+ digest,
270
+ dependency,
271
+ };
272
+ files.set(relative, value);
273
+ if (dependency)
274
+ dependencyHash.update(
275
+ JSON.stringify([relative, value.type, value.mode, size, digest]) +
276
+ "\n",
277
+ );
278
+ }
279
+ }
280
+ };
281
+ visit(directory);
282
+ files.dependencyBoundary = {
283
+ contract:
284
+ "all node_modules files and link identities streamed with SHA-256; links never followed; dependency bodies omitted; every change rejected",
285
+ files: dependencyFiles,
286
+ bytes: dependencyBytes,
287
+ digest: `sha256:${dependencyHash.digest("hex")}`,
288
+ };
289
+ return files;
290
+ }
291
+
292
+ function diff(before, after) {
293
+ const result = [];
294
+ let total = 0;
295
+ for (const file of [...new Set([...before.keys(), ...after.keys()])].sort()) {
296
+ const old = before.get(file),
297
+ next = after.get(file);
298
+ if (
299
+ old?.digest === next?.digest &&
300
+ old?.type === next?.type &&
301
+ old?.mode === next?.mode
302
+ )
303
+ continue;
304
+ total += (old?.bytes?.length || 0) + (next?.bytes?.length || 0);
305
+ requireValue(
306
+ total <= MAX_DIFF_BYTES,
307
+ "task diff exceeds 32 MiB; preserve workspace for independent inspection",
308
+ );
309
+ const describe = (value) =>
310
+ value
311
+ ? {
312
+ type: value.type,
313
+ mode: value.mode,
314
+ digest: value.digest,
315
+ bytes: value.size,
316
+ dependency: value.dependency,
317
+ bytesBase64: value.bytes?.toString("base64") ?? null,
318
+ }
319
+ : null;
320
+ result.push({ path: file, before: describe(old), after: describe(next) });
321
+ }
322
+ return result;
323
+ }
324
+
325
+ function reviewedProcess(bytes, directory, reviewRoot, kind, timeout) {
326
+ // Execute the captured bytes, not a path that task code could replace between
327
+ // digest verification and process startup. Evaluators are explicitly trusted
328
+ // operator code; their digest is not an independent-review attestation.
329
+ const result = executionBroker.spawnSync(
330
+ process.execPath,
331
+ ["--input-type=module", "--eval", bytes.toString("utf8"), directory],
332
+ {
333
+ cwd: reviewRoot,
334
+ encoding: "utf8",
335
+ timeout,
336
+ maxBuffer: 8 * 1024 * 1024,
337
+ windowsHide: true,
338
+ origin: `eval:verify01-${kind}`,
339
+ policy: "allow",
340
+ scope: "eval",
341
+ shell: false,
342
+ },
343
+ );
344
+ return {
345
+ exitCode: result.status ?? null,
346
+ signal: result.signal ?? null,
347
+ stdout: result.stdout || "",
348
+ stderr: result.stderr || "",
349
+ error: result.error?.message || null,
350
+ sourceDigest: evalDigest(bytes),
351
+ };
352
+ }
353
+
354
+ /** Prepare a frozen suite. No evaluator or agent runs during admission. */
355
+ export function loadVerify01Suite(options = {}) {
356
+ for (const field of [
357
+ "planDir",
358
+ "planDigest",
359
+ "reviewFile",
360
+ "reviewDigest",
361
+ "reviewRoot",
362
+ "projectRoot",
363
+ "sampleIds",
364
+ ])
365
+ requireValue(
366
+ options[field],
367
+ `VERIFY-01 requires ${field}; an independent review binding is not optional`,
368
+ );
369
+ const planDir = path.resolve(options.planDir);
370
+ const bundle = {
371
+ plan: readJson(path.join(planDir, "plan.json")),
372
+ catalog: readJson(path.join(planDir, "tasks.json")),
373
+ bindings: readJson(path.join(planDir, "comparison-bindings.json")),
374
+ expectedPlanDigest: options.planDigest,
375
+ };
376
+ requireValue(
377
+ readBytes(path.join(planDir, "plan.sha256")).toString("utf8").trim() ===
378
+ options.planDigest,
379
+ "pinned plan.sha256 differs from external plan binding",
380
+ );
381
+ const projectRoot = fs.realpathSync(options.projectRoot),
382
+ reviewRoot = fs.realpathSync(options.reviewRoot);
383
+ requireValue(
384
+ projectRoot !== reviewRoot &&
385
+ !reviewRoot.startsWith(`${projectRoot}${path.sep}`),
386
+ "review root must be outside the task project",
387
+ );
388
+ const projectCommit = git(projectRoot, ["rev-parse", "HEAD"]).trim();
389
+ const artifacts = new Map();
390
+ const preparation = {
391
+ review: readJson(options.reviewFile),
392
+ expectedReviewDigest: options.reviewDigest,
393
+ projectCommit,
394
+ readReviewedFile(relative) {
395
+ const bytes = readBytes(regularPath(reviewRoot, relative));
396
+ artifacts.set(relative, bytes);
397
+ return bytes;
398
+ },
399
+ };
400
+ const validated = validateVerify01Review(bundle, preparation);
401
+ const ids = Array.isArray(options.sampleIds)
402
+ ? options.sampleIds
403
+ : String(options.sampleIds).split(",");
404
+ requireValue(
405
+ ids.length > 0 && new Set(ids).size === ids.length,
406
+ "selected sample IDs are missing or duplicated",
407
+ );
408
+ const samples = ids.map((id) => validated.samples.get(id));
409
+ requireValue(samples.every(Boolean), "sample outside frozen population");
410
+ requireValue(
411
+ samples.every((sample) => sample.kind === "task"),
412
+ "first-run samples require actual installation journey collection; task execution cannot replace it",
413
+ );
414
+ requireValue(
415
+ new Set(samples.map((sample) => sample.stratum)).size === 1,
416
+ "one execution must retain one frozen comparison stratum",
417
+ );
418
+ const sampleComparison = bundle.bindings.comparisons[samples[0].stratum];
419
+ const entry = options.entry || "cli";
420
+ requireValue(
421
+ entry === "cli" &&
422
+ samples.every((sample) => sample.stratum.includes("-cli-")),
423
+ "IDE samples require an actual IDE host adapter; CLI cannot impersonate that entry",
424
+ );
425
+ const comparison = createEvalComparison({
426
+ ...sampleComparison,
427
+ context: sampleComparison.declared,
428
+ platform: process.platform,
429
+ arch: process.arch,
430
+ node: process.version,
431
+ provider: options.provider,
432
+ model: options.model,
433
+ });
434
+ requireValue(
435
+ outcomeDigest(comparison) === samples[0].comparisonDigest,
436
+ "actual provider/model/runtime differs from frozen comparison",
437
+ );
438
+ const receipts = [];
439
+ const tasks = samples.map((sample) => {
440
+ const task = validated.tasks.get(sample.taskId),
441
+ reviewed = validated.reviewed.get(sample.taskId);
442
+ let baseline, after;
443
+ const receipt = {
444
+ sampleId: sample.id,
445
+ taskId: task.id,
446
+ planDigest: options.planDigest,
447
+ reviewDigest: options.reviewDigest,
448
+ projectCommit,
449
+ comparisonDigest: sample.comparisonDigest,
450
+ entry,
451
+ productionAttested: false,
452
+ dependencyBoundary: null,
453
+ setup: null,
454
+ check: null,
455
+ diff: null,
456
+ execution: null,
457
+ };
458
+ receipts.push(receipt);
459
+ return {
460
+ id: task.id,
461
+ description: task.description,
462
+ prompt: task.prompt,
463
+ timeoutMs: sample.timeBudgetMs,
464
+ totalTimeoutMs: sample.timeBudgetMs,
465
+ costBudgetUsd: sample.costBudget,
466
+ expectedFiles: [...reviewed.allowedChangedPaths],
467
+ async setup(directory, budget) {
468
+ receipt.workspace = directory;
469
+ receipt.checkout = await materializeCheckout(
470
+ projectRoot,
471
+ projectCommit,
472
+ directory,
473
+ budget,
474
+ );
475
+ receipt.setup = reviewedProcess(
476
+ artifacts.get(reviewed.setup.path),
477
+ directory,
478
+ reviewRoot,
479
+ "setup",
480
+ budget.remainingMs("setup"),
481
+ );
482
+ requireValue(
483
+ receipt.setup.exitCode === 0 &&
484
+ !receipt.setup.signal &&
485
+ !receipt.setup.error,
486
+ "reviewed setup failed",
487
+ );
488
+ },
489
+ snapshotWorkspace(directory, budget, stage) {
490
+ const captured = snapshot(directory, budget, stage);
491
+ if (stage === "baseline") baseline = captured;
492
+ else after = captured;
493
+ receipt.dependencyBoundary = {
494
+ before: baseline?.dependencyBoundary || null,
495
+ after: after?.dependencyBoundary || null,
496
+ };
497
+ return new Map(
498
+ [...captured].map(([file, value]) => [
499
+ file,
500
+ JSON.stringify([value.digest, value.type, value.mode]),
501
+ ]),
502
+ );
503
+ },
504
+ recordFailure(failure) {
505
+ receipt.failure = failure;
506
+ baseline = after = null;
507
+ },
508
+ recordExecution(agentResult) {
509
+ receipt.execution = {
510
+ output: agentResult?.output ?? null,
511
+ error: agentResult?.error ?? null,
512
+ evidence: agentResult?.executionEvidence ?? null,
513
+ usage: agentResult?.usage ?? null,
514
+ totalCostUsd: agentResult?.totalCostUsd ?? null,
515
+ };
516
+ },
517
+ check(directory, agentResult, budget) {
518
+ receipt.diff = diff(baseline, after);
519
+ baseline = null;
520
+ requireValue(
521
+ receipt.diff.every(
522
+ (change) =>
523
+ reviewed.allowedChangedPaths.includes(change.path) &&
524
+ !change.before?.dependency &&
525
+ !change.after?.dependency &&
526
+ change.after?.type !== "link",
527
+ ),
528
+ "task modified a path outside independent review or introduced a deliverable link",
529
+ );
530
+ requireValue(
531
+ task.expectedFiles.every((file) => after.get(file)?.type === "file"),
532
+ "task did not produce all expected regular-file deliverables",
533
+ );
534
+ after = null;
535
+ receipt.check = reviewedProcess(
536
+ artifacts.get(reviewed.check.path),
537
+ directory,
538
+ reviewRoot,
539
+ "check",
540
+ budget.remainingMs("check"),
541
+ );
542
+ requireValue(
543
+ receipt.check.exitCode === 0 &&
544
+ !receipt.check.signal &&
545
+ !receipt.check.error,
546
+ "reviewed acceptance process failed",
547
+ );
548
+ const verdict = JSON.parse(receipt.check.stdout.trim());
549
+ requireValue(
550
+ typeof verdict?.pass === "boolean" &&
551
+ typeof verdict?.detail === "string",
552
+ "reviewed check must emit one JSON pass/detail verdict",
553
+ );
554
+ return verdict;
555
+ },
556
+ };
557
+ });
558
+ Object.defineProperty(tasks, "verification", {
559
+ value: {
560
+ comparison,
561
+ projectCommit,
562
+ planDigest: options.planDigest,
563
+ reviewDigest: options.reviewDigest,
564
+ population: { tasks: 36, firstRuns: 9 },
565
+ selectedSamples: ids,
566
+ receipts,
567
+ productionAttested: false,
568
+ requiredSandboxMode: "workspace-write",
569
+ },
570
+ });
571
+ return tasks;
572
+ }
573
+
574
+ export function persistVerify01Receipts(verification, directory, runId) {
575
+ requireValue(
576
+ typeof runId === "string" && /^[a-f0-9-]{36}$/u.test(runId),
577
+ "invalid evaluation run ID",
578
+ );
579
+ const root = path.resolve(directory);
580
+ fs.mkdirSync(root, { recursive: true, mode: 0o700 });
581
+ const stat = fs.lstatSync(root);
582
+ requireValue(
583
+ stat.isDirectory() && !stat.isSymbolicLink(),
584
+ "evidence directory must not be a link",
585
+ );
586
+ const { receipts, ...binding } = verification;
587
+ const artifacts = receipts.map((receipt, index) => {
588
+ const bytes = Buffer.from(`${JSON.stringify(receipt, null, 2)}\n`);
589
+ const file = path.join(root, `verify-${runId}-${index}.json`);
590
+ const fd = fs.openSync(file, "wx", 0o600);
591
+ try {
592
+ fs.writeFileSync(fd, bytes);
593
+ fs.fsyncSync(fd);
594
+ } finally {
595
+ fs.closeSync(fd);
596
+ }
597
+ return {
598
+ sampleId: receipt.sampleId,
599
+ path: file,
600
+ digest: evalDigest(bytes),
601
+ bytes: bytes.length,
602
+ };
603
+ });
604
+ return { ...binding, artifacts };
605
+ }
@@ -0,0 +1,58 @@
1
+ import { permissionRulesProviderAuthority } from "./permission-authority.js";
2
+
3
+ /** Diagnostic projection only. Admission remains with the broker and authority. */
4
+ export function describeExecutionSupport({
5
+ capabilityReport,
6
+ permissionRulesProvider,
7
+ } = {}) {
8
+ const report = capabilityReport;
9
+ if (!report?.host || !report?.backend)
10
+ throw new TypeError("sandbox capability report is required");
11
+ let authority = "process-local",
12
+ authorityAvailable = true;
13
+ try {
14
+ const bound = permissionRulesProviderAuthority(permissionRulesProvider);
15
+ if (bound?.getSnapshot()?.durable) authority = "durable-controlled-host";
16
+ else if (permissionRulesProvider && !bound) authority = "sampled-callback";
17
+ } catch {
18
+ authority = "unavailable";
19
+ authorityAvailable = false;
20
+ }
21
+ const supportedHost =
22
+ report.host.platform === "linux" &&
23
+ ["x64", "arm64"].includes(report.host.arch);
24
+ const domainRoute =
25
+ report.backend.engine === "docker-egress" &&
26
+ report.unsupported.length === 0;
27
+ const durable =
28
+ supportedHost && domainRoute && authority === "durable-controlled-host";
29
+ return {
30
+ schema: "chainlesschain.execution-support/v1",
31
+ platform: report.host.platform,
32
+ arch: report.host.arch,
33
+ engine: report.backend.engine,
34
+ entrypoint: "agent-shell",
35
+ io: {
36
+ stdin: "noninteractive",
37
+ stdout: "captured",
38
+ stderr: "captured",
39
+ interactiveTerminal: false,
40
+ },
41
+ permissionSource: authority,
42
+ permissionSourceAvailable: authorityAvailable,
43
+ persistentNetworkRevocation: {
44
+ status: durable ? "configured" : "unavailable",
45
+ reason: !supportedHost
46
+ ? "requires-linux-x64-or-arm64-controlled-host"
47
+ : !domainRoute
48
+ ? "requires-docker-egress-domain-policy"
49
+ : authority !== "durable-controlled-host"
50
+ ? "requires-explicit-durable-authority-binding"
51
+ : null,
52
+ executionObserved: durable && report.execution.started === true,
53
+ backendAvailable: report.backend.available,
54
+ modelRequestGovernance: "not-established-by-shell-capabilities",
55
+ },
56
+ nativeReleaseValidation: "not-established-by-this-probe",
57
+ };
58
+ }