@cleocode/core 2026.6.12 → 2026.6.13

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 (385) hide show
  1. package/dist/conduit/local-transport.d.ts +12 -0
  2. package/dist/conduit/local-transport.d.ts.map +1 -1
  3. package/dist/conduit/local-transport.js +53 -23
  4. package/dist/conduit/local-transport.js.map +1 -1
  5. package/dist/crypto/credentials.d.ts +37 -0
  6. package/dist/crypto/credentials.d.ts.map +1 -1
  7. package/dist/crypto/credentials.js +110 -0
  8. package/dist/crypto/credentials.js.map +1 -1
  9. package/dist/dispatch/contracts/derive-output-contract.d.ts +86 -0
  10. package/dist/dispatch/contracts/derive-output-contract.d.ts.map +1 -0
  11. package/dist/dispatch/contracts/derive-output-contract.js +347 -0
  12. package/dist/dispatch/contracts/derive-output-contract.js.map +1 -0
  13. package/dist/dispatch/contracts/ensures-schema.d.ts +77 -0
  14. package/dist/dispatch/contracts/ensures-schema.d.ts.map +1 -0
  15. package/dist/dispatch/contracts/ensures-schema.js +91 -0
  16. package/dist/dispatch/contracts/ensures-schema.js.map +1 -0
  17. package/dist/dispatch/contracts/output-contracts.d.ts +27 -5
  18. package/dist/dispatch/contracts/output-contracts.d.ts.map +1 -1
  19. package/dist/dispatch/contracts/output-contracts.js +29 -6
  20. package/dist/dispatch/contracts/output-contracts.js.map +1 -1
  21. package/dist/docs/export-document.js +2294 -1250
  22. package/dist/docs/export-document.js.map +3 -3
  23. package/dist/go/driver.d.ts +132 -7
  24. package/dist/go/driver.d.ts.map +1 -1
  25. package/dist/go/driver.js +135 -10
  26. package/dist/go/driver.js.map +1 -1
  27. package/dist/go/index.d.ts +1 -1
  28. package/dist/go/index.d.ts.map +1 -1
  29. package/dist/go/index.js +1 -1
  30. package/dist/go/index.js.map +1 -1
  31. package/dist/index.d.ts +1 -0
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +5 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal.d.ts +13 -10
  36. package/dist/internal.d.ts.map +1 -1
  37. package/dist/internal.js +11 -11
  38. package/dist/internal.js.map +1 -1
  39. package/dist/lifecycle/engine-ops.d.ts.map +1 -1
  40. package/dist/lifecycle/engine-ops.js +7 -4
  41. package/dist/lifecycle/engine-ops.js.map +1 -1
  42. package/dist/lifecycle/ivtr-loop.d.ts +108 -183
  43. package/dist/lifecycle/ivtr-loop.d.ts.map +1 -1
  44. package/dist/lifecycle/ivtr-loop.js +207 -522
  45. package/dist/lifecycle/ivtr-loop.js.map +1 -1
  46. package/dist/llm/auxiliary-fallback.js +1 -1
  47. package/dist/llm/auxiliary-fallback.js.map +1 -1
  48. package/dist/llm/cli-ops.d.ts +14 -1
  49. package/dist/llm/cli-ops.d.ts.map +1 -1
  50. package/dist/llm/cli-ops.js +41 -12
  51. package/dist/llm/cli-ops.js.map +1 -1
  52. package/dist/llm/concrete-session.d.ts.map +1 -1
  53. package/dist/llm/concrete-session.js +4 -0
  54. package/dist/llm/concrete-session.js.map +1 -1
  55. package/dist/llm/credentials.d.ts +35 -0
  56. package/dist/llm/credentials.d.ts.map +1 -1
  57. package/dist/llm/credentials.js +49 -0
  58. package/dist/llm/credentials.js.map +1 -1
  59. package/dist/llm/index.d.ts +4 -0
  60. package/dist/llm/index.d.ts.map +1 -1
  61. package/dist/llm/index.js +4 -0
  62. package/dist/llm/index.js.map +1 -1
  63. package/dist/llm/pi/gondolin-loader.d.ts +241 -0
  64. package/dist/llm/pi/gondolin-loader.d.ts.map +1 -0
  65. package/dist/llm/pi/gondolin-loader.js +195 -0
  66. package/dist/llm/pi/gondolin-loader.js.map +1 -0
  67. package/dist/llm/pi/index.d.ts +28 -0
  68. package/dist/llm/pi/index.d.ts.map +1 -0
  69. package/dist/llm/pi/index.js +27 -0
  70. package/dist/llm/pi/index.js.map +1 -0
  71. package/dist/llm/pi/pi-agent-adapter.d.ts +135 -0
  72. package/dist/llm/pi/pi-agent-adapter.d.ts.map +1 -0
  73. package/dist/llm/pi/pi-agent-adapter.js +329 -0
  74. package/dist/llm/pi/pi-agent-adapter.js.map +1 -0
  75. package/dist/llm/pi/pi-errors.d.ts +161 -0
  76. package/dist/llm/pi/pi-errors.d.ts.map +1 -0
  77. package/dist/llm/pi/pi-errors.js +296 -0
  78. package/dist/llm/pi/pi-errors.js.map +1 -0
  79. package/dist/llm/pi/pi-execution-env.d.ts +286 -0
  80. package/dist/llm/pi/pi-execution-env.d.ts.map +1 -0
  81. package/dist/llm/pi/pi-execution-env.js +406 -0
  82. package/dist/llm/pi/pi-execution-env.js.map +1 -0
  83. package/dist/llm/pi/pi-gondolin-env.d.ts +227 -0
  84. package/dist/llm/pi/pi-gondolin-env.d.ts.map +1 -0
  85. package/dist/llm/pi/pi-gondolin-env.js +541 -0
  86. package/dist/llm/pi/pi-gondolin-env.js.map +1 -0
  87. package/dist/llm/pi/pi-session-storage.d.ts +154 -0
  88. package/dist/llm/pi/pi-session-storage.d.ts.map +1 -0
  89. package/dist/llm/pi/pi-session-storage.js +314 -0
  90. package/dist/llm/pi/pi-session-storage.js.map +1 -0
  91. package/dist/llm/pi/pi-stream-fn.d.ts +124 -0
  92. package/dist/llm/pi/pi-stream-fn.d.ts.map +1 -0
  93. package/dist/llm/pi/pi-stream-fn.js +504 -0
  94. package/dist/llm/pi/pi-stream-fn.js.map +1 -0
  95. package/dist/llm/pi/pi-tool-bridge.d.ts +99 -0
  96. package/dist/llm/pi/pi-tool-bridge.d.ts.map +1 -0
  97. package/dist/llm/pi/pi-tool-bridge.js +117 -0
  98. package/dist/llm/pi/pi-tool-bridge.js.map +1 -0
  99. package/dist/llm/pi/pi-types.d.ts +56 -0
  100. package/dist/llm/pi/pi-types.d.ts.map +1 -0
  101. package/dist/llm/pi/pi-types.js +16 -0
  102. package/dist/llm/pi/pi-types.js.map +1 -0
  103. package/dist/llm/pi/resolve-execution-env.d.ts +194 -0
  104. package/dist/llm/pi/resolve-execution-env.d.ts.map +1 -0
  105. package/dist/llm/pi/resolve-execution-env.js +132 -0
  106. package/dist/llm/pi/resolve-execution-env.js.map +1 -0
  107. package/dist/llm/plugin-facade.js +2253 -1151
  108. package/dist/llm/plugin-facade.js.map +3 -3
  109. package/dist/llm/role-executor.d.ts.map +1 -1
  110. package/dist/llm/role-executor.js +8 -5
  111. package/dist/llm/role-executor.js.map +1 -1
  112. package/dist/llm/role-resolver.d.ts +46 -14
  113. package/dist/llm/role-resolver.d.ts.map +1 -1
  114. package/dist/llm/role-resolver.js +178 -20
  115. package/dist/llm/role-resolver.js.map +1 -1
  116. package/dist/llm/sealed-credential.d.ts +125 -0
  117. package/dist/llm/sealed-credential.d.ts.map +1 -0
  118. package/dist/llm/sealed-credential.js +133 -0
  119. package/dist/llm/sealed-credential.js.map +1 -0
  120. package/dist/llm/session-factory.d.ts.map +1 -1
  121. package/dist/llm/session-factory.js +6 -2
  122. package/dist/llm/session-factory.js.map +1 -1
  123. package/dist/llm/system-key.d.ts +67 -0
  124. package/dist/llm/system-key.d.ts.map +1 -0
  125. package/dist/llm/system-key.js +87 -0
  126. package/dist/llm/system-key.js.map +1 -0
  127. package/dist/llm/system-of-use-registry.d.ts +119 -0
  128. package/dist/llm/system-of-use-registry.d.ts.map +1 -0
  129. package/dist/llm/system-of-use-registry.js +200 -0
  130. package/dist/llm/system-of-use-registry.js.map +1 -0
  131. package/dist/llm/system-resolver.d.ts +32 -10
  132. package/dist/llm/system-resolver.d.ts.map +1 -1
  133. package/dist/llm/system-resolver.js +70 -18
  134. package/dist/llm/system-resolver.js.map +1 -1
  135. package/dist/memory/brain-writer-thread.d.ts.map +1 -1
  136. package/dist/memory/brain-writer-thread.js +116 -11
  137. package/dist/memory/brain-writer-thread.js.map +1 -1
  138. package/dist/memory/claude-mem-migration.d.ts.map +1 -1
  139. package/dist/memory/claude-mem-migration.js +21 -0
  140. package/dist/memory/claude-mem-migration.js.map +1 -1
  141. package/dist/memory/graph-memory-bridge.d.ts.map +1 -1
  142. package/dist/memory/graph-memory-bridge.js +32 -25
  143. package/dist/memory/graph-memory-bridge.js.map +1 -1
  144. package/dist/memory/llm-backend-resolver.js +23 -5
  145. package/dist/memory/llm-backend-resolver.js.map +1 -1
  146. package/dist/nexus/migrations/M-split-graph.d.ts.map +1 -1
  147. package/dist/nexus/migrations/M-split-graph.js +60 -53
  148. package/dist/nexus/migrations/M-split-graph.js.map +1 -1
  149. package/dist/orchestrate/pivot.d.ts.map +1 -1
  150. package/dist/orchestrate/pivot.js +20 -2
  151. package/dist/orchestrate/pivot.js.map +1 -1
  152. package/dist/release/engine-ops.js +2 -2
  153. package/dist/release/engine-ops.js.map +1 -1
  154. package/dist/routing/capability-matrix.d.ts.map +1 -1
  155. package/dist/routing/capability-matrix.js +0 -57
  156. package/dist/routing/capability-matrix.js.map +1 -1
  157. package/dist/selfimprove/budget.d.ts +206 -0
  158. package/dist/selfimprove/budget.d.ts.map +1 -0
  159. package/dist/selfimprove/budget.js +203 -0
  160. package/dist/selfimprove/budget.js.map +1 -0
  161. package/dist/selfimprove/dhq-adapter.d.ts +105 -0
  162. package/dist/selfimprove/dhq-adapter.d.ts.map +1 -0
  163. package/dist/selfimprove/dhq-adapter.js +95 -0
  164. package/dist/selfimprove/dhq-adapter.js.map +1 -0
  165. package/dist/selfimprove/draft-pr.d.ts +129 -0
  166. package/dist/selfimprove/draft-pr.d.ts.map +1 -0
  167. package/dist/selfimprove/draft-pr.js +158 -0
  168. package/dist/selfimprove/draft-pr.js.map +1 -0
  169. package/dist/selfimprove/envelope-diff.d.ts +162 -0
  170. package/dist/selfimprove/envelope-diff.d.ts.map +1 -0
  171. package/dist/selfimprove/envelope-diff.js +321 -0
  172. package/dist/selfimprove/envelope-diff.js.map +1 -0
  173. package/dist/selfimprove/replay.d.ts +121 -0
  174. package/dist/selfimprove/replay.d.ts.map +1 -0
  175. package/dist/selfimprove/replay.js +109 -0
  176. package/dist/selfimprove/replay.js.map +1 -0
  177. package/dist/selfimprove/run-loop.d.ts +148 -0
  178. package/dist/selfimprove/run-loop.d.ts.map +1 -0
  179. package/dist/selfimprove/run-loop.js +240 -0
  180. package/dist/selfimprove/run-loop.js.map +1 -0
  181. package/dist/selfimprove/scenario.d.ts +145 -0
  182. package/dist/selfimprove/scenario.d.ts.map +1 -0
  183. package/dist/selfimprove/scenario.js +243 -0
  184. package/dist/selfimprove/scenario.js.map +1 -0
  185. package/dist/sentient/daemon-entry.js +5 -0
  186. package/dist/sentient/daemon-entry.js.map +1 -1
  187. package/dist/sentient/daemon.d.ts.map +1 -1
  188. package/dist/sentient/daemon.js +19 -0
  189. package/dist/sentient/daemon.js.map +1 -1
  190. package/dist/sentient/hygiene-scan.d.ts.map +1 -1
  191. package/dist/sentient/hygiene-scan.js +14 -6
  192. package/dist/sentient/hygiene-scan.js.map +1 -1
  193. package/dist/sessions/briefing.d.ts.map +1 -1
  194. package/dist/sessions/briefing.js +13 -9
  195. package/dist/sessions/briefing.js.map +1 -1
  196. package/dist/sessions/connection-session-handle.d.ts +161 -0
  197. package/dist/sessions/connection-session-handle.d.ts.map +1 -0
  198. package/dist/sessions/connection-session-handle.js +168 -0
  199. package/dist/sessions/connection-session-handle.js.map +1 -0
  200. package/dist/sessions/handoff.d.ts.map +1 -1
  201. package/dist/sessions/handoff.js +9 -0
  202. package/dist/sessions/handoff.js.map +1 -1
  203. package/dist/sessions/index.d.ts +4 -1
  204. package/dist/sessions/index.d.ts.map +1 -1
  205. package/dist/sessions/index.js +31 -1
  206. package/dist/sessions/index.js.map +1 -1
  207. package/dist/sessions/session-id.d.ts +34 -0
  208. package/dist/sessions/session-id.d.ts.map +1 -1
  209. package/dist/sessions/session-id.js +37 -0
  210. package/dist/sessions/session-id.js.map +1 -1
  211. package/dist/sessions/session-manifest-mirror.d.ts +115 -0
  212. package/dist/sessions/session-manifest-mirror.d.ts.map +1 -0
  213. package/dist/sessions/session-manifest-mirror.js +250 -0
  214. package/dist/sessions/session-manifest-mirror.js.map +1 -0
  215. package/dist/sessions/session-switch.d.ts.map +1 -1
  216. package/dist/sessions/session-switch.js +5 -2
  217. package/dist/sessions/session-switch.js.map +1 -1
  218. package/dist/store/converters.d.ts.map +1 -1
  219. package/dist/store/converters.js +2 -0
  220. package/dist/store/converters.js.map +1 -1
  221. package/dist/store/db-helpers.d.ts.map +1 -1
  222. package/dist/store/db-helpers.js +2 -0
  223. package/dist/store/db-helpers.js.map +1 -1
  224. package/dist/store/dual-scope-db.d.ts.map +1 -1
  225. package/dist/store/dual-scope-db.js +87 -47
  226. package/dist/store/dual-scope-db.js.map +1 -1
  227. package/dist/store/pi-session-store.d.ts +151 -0
  228. package/dist/store/pi-session-store.d.ts.map +1 -0
  229. package/dist/store/pi-session-store.js +166 -0
  230. package/dist/store/pi-session-store.js.map +1 -0
  231. package/dist/store/safety-data-accessor.d.ts +1 -0
  232. package/dist/store/safety-data-accessor.d.ts.map +1 -1
  233. package/dist/store/safety-data-accessor.js +5 -0
  234. package/dist/store/safety-data-accessor.js.map +1 -1
  235. package/dist/store/schema/cleo-global/accounts.d.ts +357 -0
  236. package/dist/store/schema/cleo-global/accounts.d.ts.map +1 -0
  237. package/dist/store/schema/cleo-global/accounts.js +136 -0
  238. package/dist/store/schema/cleo-global/accounts.js.map +1 -0
  239. package/dist/store/schema/cleo-global/index.d.ts +2 -0
  240. package/dist/store/schema/cleo-global/index.d.ts.map +1 -1
  241. package/dist/store/schema/cleo-global/index.js +2 -0
  242. package/dist/store/schema/cleo-global/index.js.map +1 -1
  243. package/dist/store/schema/cleo-global/session-manifest.d.ts +217 -0
  244. package/dist/store/schema/cleo-global/session-manifest.d.ts.map +1 -0
  245. package/dist/store/schema/cleo-global/session-manifest.js +99 -0
  246. package/dist/store/schema/cleo-global/session-manifest.js.map +1 -0
  247. package/dist/store/schema/cleo-project/tasks-core.d.ts +16 -0
  248. package/dist/store/schema/cleo-project/tasks-core.d.ts.map +1 -1
  249. package/dist/store/schema/cleo-project/tasks-core.js +14 -0
  250. package/dist/store/schema/cleo-project/tasks-core.js.map +1 -1
  251. package/dist/store/schema/tasks.d.ts +16 -0
  252. package/dist/store/schema/tasks.d.ts.map +1 -1
  253. package/dist/store/schema/tasks.js +10 -0
  254. package/dist/store/schema/tasks.js.map +1 -1
  255. package/dist/store/selfimprove-dhq-schema.d.ts +284 -0
  256. package/dist/store/selfimprove-dhq-schema.d.ts.map +1 -0
  257. package/dist/store/selfimprove-dhq-schema.js +128 -0
  258. package/dist/store/selfimprove-dhq-schema.js.map +1 -0
  259. package/dist/store/selfimprove-dhq-store.d.ts +175 -0
  260. package/dist/store/selfimprove-dhq-store.d.ts.map +1 -0
  261. package/dist/store/selfimprove-dhq-store.js +182 -0
  262. package/dist/store/selfimprove-dhq-store.js.map +1 -0
  263. package/dist/store/session-store.d.ts +52 -13
  264. package/dist/store/session-store.d.ts.map +1 -1
  265. package/dist/store/session-store.js +71 -13
  266. package/dist/store/session-store.js.map +1 -1
  267. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  268. package/dist/store/sqlite-data-accessor.js +7 -0
  269. package/dist/store/sqlite-data-accessor.js.map +1 -1
  270. package/dist/store/umbrella-data-accessor.d.ts +1 -0
  271. package/dist/store/umbrella-data-accessor.d.ts.map +1 -1
  272. package/dist/store/umbrella-data-accessor.js +5 -0
  273. package/dist/store/umbrella-data-accessor.js.map +1 -1
  274. package/dist/store/validation-schemas.d.ts +32 -0
  275. package/dist/store/validation-schemas.d.ts.map +1 -1
  276. package/dist/store/writer-lease-schema.d.ts +392 -0
  277. package/dist/store/writer-lease-schema.d.ts.map +1 -0
  278. package/dist/store/writer-lease-schema.js +142 -0
  279. package/dist/store/writer-lease-schema.js.map +1 -0
  280. package/dist/store/writer-lease.d.ts +368 -0
  281. package/dist/store/writer-lease.d.ts.map +1 -0
  282. package/dist/store/writer-lease.js +1002 -0
  283. package/dist/store/writer-lease.js.map +1 -0
  284. package/dist/tasks/backfill-child-projections.d.ts.map +1 -1
  285. package/dist/tasks/backfill-child-projections.js +14 -9
  286. package/dist/tasks/backfill-child-projections.js.map +1 -1
  287. package/dist/tasks/complete.d.ts.map +1 -1
  288. package/dist/tasks/complete.js +7 -10
  289. package/dist/tasks/complete.js.map +1 -1
  290. package/dist/tasks/duplicate-detector.d.ts.map +1 -1
  291. package/dist/tasks/duplicate-detector.js +14 -7
  292. package/dist/tasks/duplicate-detector.js.map +1 -1
  293. package/dist/telemetry/index.d.ts.map +1 -1
  294. package/dist/telemetry/index.js +10 -4
  295. package/dist/telemetry/index.js.map +1 -1
  296. package/dist/tools/agent-registry.d.ts +250 -0
  297. package/dist/tools/agent-registry.d.ts.map +1 -0
  298. package/dist/tools/agent-registry.js +292 -0
  299. package/dist/tools/agent-registry.js.map +1 -0
  300. package/dist/tools/agent-tool-families.d.ts +107 -0
  301. package/dist/tools/agent-tool-families.d.ts.map +1 -0
  302. package/dist/tools/agent-tool-families.js +527 -0
  303. package/dist/tools/agent-tool-families.js.map +1 -0
  304. package/dist/tools/browser-driver.d.ts +183 -0
  305. package/dist/tools/browser-driver.d.ts.map +1 -0
  306. package/dist/tools/browser-driver.js +242 -0
  307. package/dist/tools/browser-driver.js.map +1 -0
  308. package/dist/tools/builtin-agent-tools.d.ts +36 -0
  309. package/dist/tools/builtin-agent-tools.d.ts.map +1 -0
  310. package/dist/tools/builtin-agent-tools.js +150 -0
  311. package/dist/tools/builtin-agent-tools.js.map +1 -0
  312. package/dist/tools/dispatch.d.ts +370 -0
  313. package/dist/tools/dispatch.d.ts.map +1 -0
  314. package/dist/tools/dispatch.js +505 -0
  315. package/dist/tools/dispatch.js.map +1 -0
  316. package/dist/tools/env-scrub.d.ts +93 -0
  317. package/dist/tools/env-scrub.d.ts.map +1 -0
  318. package/dist/tools/env-scrub.js +176 -0
  319. package/dist/tools/env-scrub.js.map +1 -0
  320. package/dist/tools/fs.d.ts +30 -0
  321. package/dist/tools/fs.d.ts.map +1 -1
  322. package/dist/tools/fs.js +55 -2
  323. package/dist/tools/fs.js.map +1 -1
  324. package/dist/tools/guard.d.ts +15 -0
  325. package/dist/tools/guard.d.ts.map +1 -1
  326. package/dist/tools/guard.js +49 -12
  327. package/dist/tools/guard.js.map +1 -1
  328. package/dist/tools/index.d.ts +10 -0
  329. package/dist/tools/index.d.ts.map +1 -1
  330. package/dist/tools/index.js +37 -0
  331. package/dist/tools/index.js.map +1 -1
  332. package/dist/tools/pty.d.ts +45 -0
  333. package/dist/tools/pty.d.ts.map +1 -0
  334. package/dist/tools/pty.js +166 -0
  335. package/dist/tools/pty.js.map +1 -0
  336. package/dist/tools/schema-gen.d.ts +57 -0
  337. package/dist/tools/schema-gen.d.ts.map +1 -0
  338. package/dist/tools/schema-gen.js +52 -0
  339. package/dist/tools/schema-gen.js.map +1 -0
  340. package/dist/tools/shell.d.ts +12 -0
  341. package/dist/tools/shell.d.ts.map +1 -1
  342. package/dist/tools/shell.js +14 -1
  343. package/dist/tools/shell.js.map +1 -1
  344. package/dist/tools/web-agent-tools.d.ts +72 -0
  345. package/dist/tools/web-agent-tools.d.ts.map +1 -0
  346. package/dist/tools/web-agent-tools.js +393 -0
  347. package/dist/tools/web-agent-tools.js.map +1 -0
  348. package/dist/tools/web-search-backends.d.ts +156 -0
  349. package/dist/tools/web-search-backends.d.ts.map +1 -0
  350. package/dist/tools/web-search-backends.js +290 -0
  351. package/dist/tools/web-search-backends.js.map +1 -0
  352. package/dist/validation/ops.d.ts +1 -15
  353. package/dist/validation/ops.d.ts.map +1 -1
  354. package/dist/validation/ops.js +0 -20
  355. package/dist/validation/ops.js.map +1 -1
  356. package/migrations/drizzle-cleo-global/20260607000000_t11891-writer-leases/migration.sql +55 -0
  357. package/migrations/drizzle-cleo-global/20260607010000_t11639-session-manifest/migration.sql +43 -0
  358. package/migrations/drizzle-cleo-global/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
  359. package/migrations/drizzle-cleo-global/20260608010000_t11709-accounts-credential-pool/migration.sql +72 -0
  360. package/migrations/drizzle-cleo-global/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
  361. package/migrations/drizzle-cleo-project/20260607000000_t11891-writer-leases/migration.sql +55 -0
  362. package/migrations/drizzle-cleo-project/20260607010000_t11639-session-parent/migration.sql +22 -0
  363. package/migrations/drizzle-cleo-project/20260608000000_t11899-pi-session-tree/migration.sql +52 -0
  364. package/migrations/drizzle-cleo-project/20260608020000_t11889-selfimprove-dhq/migration.sql +64 -0
  365. package/package.json +15 -13
  366. package/dist/lifecycle/chain-composition.d.ts +0 -30
  367. package/dist/lifecycle/chain-composition.d.ts.map +0 -1
  368. package/dist/lifecycle/chain-composition.js +0 -152
  369. package/dist/lifecycle/chain-composition.js.map +0 -1
  370. package/dist/lifecycle/chain-store.d.ts +0 -70
  371. package/dist/lifecycle/chain-store.d.ts.map +0 -1
  372. package/dist/lifecycle/chain-store.js +0 -246
  373. package/dist/lifecycle/chain-store.js.map +0 -1
  374. package/dist/lifecycle/default-chain.d.ts +0 -39
  375. package/dist/lifecycle/default-chain.d.ts.map +0 -1
  376. package/dist/lifecycle/default-chain.js +0 -176
  377. package/dist/lifecycle/default-chain.js.map +0 -1
  378. package/dist/lifecycle/tessera-engine.d.ts +0 -48
  379. package/dist/lifecycle/tessera-engine.d.ts.map +0 -1
  380. package/dist/lifecycle/tessera-engine.js +0 -249
  381. package/dist/lifecycle/tessera-engine.js.map +0 -1
  382. package/dist/validation/chain-validation.d.ts +0 -43
  383. package/dist/validation/chain-validation.d.ts.map +0 -1
  384. package/dist/validation/chain-validation.js +0 -146
  385. package/dist/validation/chain-validation.js.map +0 -1
@@ -0,0 +1,406 @@
1
+ /**
2
+ * Guarded Pi `ExecutionEnv` (T11761 · S1 · T11897).
3
+ *
4
+ * Pi's agent loop performs ALL filesystem + shell work through a single
5
+ * pluggable seam: `ExecutionEnv extends FileSystem, Shell`. This module supplies
6
+ * Cleo's implementation of that seam — {@link GuardedExecutionEnv} — which routes
7
+ * every operation through the deny-first {@link ToolGuard} chokepoint and an
8
+ * injected **workspace boundary**, so Pi can touch nothing outside the
9
+ * allowlisted roots and runs no command on the denylist.
10
+ *
11
+ * Two layers of confinement (deny-first):
12
+ * 1. **Workspace boundary** — every fs path is canonicalized with SYMLINK
13
+ * RESOLUTION (`fs.realpath` on the nearest existing ancestor) and the REAL
14
+ * target MUST fall under the injected `workspaceRoot`; a `../` escape, an
15
+ * out-of-root absolute path, OR a symlink (file or parent dir) whose real
16
+ * target leaves the root is rejected as a Pi `Result.err(FileError)` BEFORE
17
+ * the guard is consulted. A purely lexical check is symlink-blind, so the
18
+ * boundary resolves symlinks first. (The guard's own `allowedRoots` is a
19
+ * second, ALSO-symlink-resolving net.)
20
+ * 2. **ToolGuard** — the allowed operations delegate to the `ToolGuard` surface
21
+ * (`readFileText`/`writeFileAtomic`/`pathExists`/`executeShell`/`runGit`),
22
+ * which applies the project's symlink-resolved path allowlist + shell
23
+ * denylist + subprocess-env scrub. A `GuardDeniedError` from enforce-mode is
24
+ * CAUGHT and converted to a Pi `Result.err` — Pi's `FileSystem`/`Shell` ops
25
+ * must NEVER throw. The guard MUST be constructed in `enforce` mode (the
26
+ * factory asserts it) — in `warn` mode its allowlist/denylist are advisory
27
+ * and confinement would collapse to the workspace boundary alone.
28
+ *
29
+ * Every other capability (binary reads, raw temp/dir mutation, listing, …) for
30
+ * which there is no atomic primitive in v0 is DENIED with a typed error rather
31
+ * than reaching the real filesystem. The structural Pi interfaces are declared
32
+ * locally here (the `@earendil-works/pi-agent-core` package is not yet a
33
+ * dependency); S2 replaces these with the real type-only imports — the shapes
34
+ * match `@earendil-works/pi-agent-core@0.78.1` `harness/types.ts:268-332`.
35
+ *
36
+ * Scope discipline (S1): NO `pi-ai`/`pi-agent-core` imports, NO DB access, NO
37
+ * LLM calls. Import-time side-effect free.
38
+ *
39
+ * @epic T10403
40
+ * @task T11761
41
+ * @task T11897
42
+ */
43
+ import { isAbsolute, relative, resolve as resolvePath } from 'node:path';
44
+ import { scrubSubprocessEnv } from '../../tools/env-scrub.js';
45
+ import { canonicalizePath } from '../../tools/fs.js';
46
+ import { GuardDeniedError } from '../../tools/guard.js';
47
+ // ---------------------------------------------------------------------------
48
+ // Result constructors
49
+ // ---------------------------------------------------------------------------
50
+ /** Build a successful {@link PiResult}. */
51
+ function ok(value) {
52
+ return { ok: true, value };
53
+ }
54
+ /** Build a failed {@link PiResult} with a {@link PiFileError}. */
55
+ function fsErr(code, message, path) {
56
+ return { ok: false, error: { code, message, ...(path !== undefined ? { path } : {}) } };
57
+ }
58
+ /** Build a failed {@link PiResult} with a {@link PiExecutionError}. */
59
+ function execErr(code, message) {
60
+ return { ok: false, error: { code, message } };
61
+ }
62
+ /**
63
+ * Whether `err` is a "file does not exist" failure (`ENOENT`). Used by
64
+ * {@link GuardedExecutionEnv.appendFile} to treat append-to-missing as
65
+ * append-creates (empty prefix) while still propagating every OTHER failure
66
+ * (guard denial, permission, …).
67
+ */
68
+ function isMissingFileError(err) {
69
+ return (typeof err === 'object' &&
70
+ err !== null &&
71
+ 'code' in err &&
72
+ err.code === 'ENOENT');
73
+ }
74
+ /**
75
+ * Deny-first {@link PiExecutionEnv} backed by the Cleo {@link ToolGuard} surface
76
+ * and a workspace boundary.
77
+ *
78
+ * - File reads/writes/existence checks route through the guard's atomic
79
+ * primitives, confined to `workspaceRoot`.
80
+ * - `exec` routes through the guard's `executeShell` (shell denylist applies).
81
+ * - Capabilities with no atomic primitive in v0 (binary read, `listDir`,
82
+ * `createDir`, `remove`, temp dir/file) are DENIED with a typed
83
+ * `Result.err` — they never reach the real filesystem.
84
+ * - Pure path arithmetic (`cwd`/`absolutePath`/`joinPath`) is computed locally
85
+ * (no fs access), anchored to `workspaceRoot`.
86
+ *
87
+ * Every method honours the Pi contract: it returns a {@link PiResult} and never
88
+ * throws — a {@link GuardDeniedError} from the guard is caught and converted.
89
+ */
90
+ export class GuardedExecutionEnv {
91
+ #guard;
92
+ #root;
93
+ /**
94
+ * @param deps - The guard surface + the workspace root to confine to.
95
+ */
96
+ constructor(deps) {
97
+ this.#guard = deps.guard;
98
+ this.#root = resolvePath(deps.workspaceRoot);
99
+ }
100
+ /**
101
+ * Lexically resolve a (possibly relative) path against the workspace root and
102
+ * assert it does not climb out. This is the fast FIRST gate only — it is
103
+ * symlink-blind, so {@link #confine} additionally re-checks the REAL target.
104
+ *
105
+ * @returns the lexically-resolved absolute path, or `null` on a `../`/absolute
106
+ * escape.
107
+ */
108
+ #lexicalConfine(path) {
109
+ const abs = isAbsolute(path) ? resolvePath(path) : resolvePath(this.#root, path);
110
+ const rel = relative(this.#root, abs);
111
+ if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel)))
112
+ return abs;
113
+ return null;
114
+ }
115
+ /**
116
+ * Resolve a (possibly relative) path against the workspace root and assert its
117
+ * REAL filesystem target stays inside the boundary. Two gates:
118
+ * 1. lexical (`#lexicalConfine`) — rejects `../` / out-of-root absolute paths;
119
+ * 2. SYMLINK resolution (`canonicalizePath`) — follows every symlink component
120
+ * (incl. a symlinked parent of a fresh write target) and re-checks
121
+ * containment against the REAL path, defeating the classic symlink/TOCTOU
122
+ * escape that a purely lexical check is blind to.
123
+ *
124
+ * @returns the symlink-resolved absolute path, or `null` when it escapes.
125
+ */
126
+ async #confine(path) {
127
+ const lexical = this.#lexicalConfine(path);
128
+ if (lexical === null)
129
+ return null;
130
+ const real = await canonicalizePath(lexical);
131
+ // Compare against the REAL root too, so a workspace whose own path traverses
132
+ // a symlink does not spuriously reject its own contained files.
133
+ const realRoot = await canonicalizePath(this.#root);
134
+ const rel = relative(realRoot, real);
135
+ // The REAL target must not climb out of the (also-real) root.
136
+ if (rel === '' || (!rel.startsWith('..') && !isAbsolute(rel)))
137
+ return real;
138
+ return null;
139
+ }
140
+ // --- pure path arithmetic (no fs access) ---------------------------------
141
+ /** The workspace root (the in-process Pi run's working directory). */
142
+ cwd() {
143
+ return this.#root;
144
+ }
145
+ /** Resolve `path` to an absolute path anchored at the workspace root. */
146
+ absolutePath(path) {
147
+ return isAbsolute(path) ? resolvePath(path) : resolvePath(this.#root, path);
148
+ }
149
+ /** Join path segments (pure). */
150
+ joinPath(...segments) {
151
+ return resolvePath(this.#root, ...segments);
152
+ }
153
+ // --- file reads ----------------------------------------------------------
154
+ /** Read a file's text, confined to the workspace + guarded. */
155
+ async readTextFile(path) {
156
+ const abs = await this.#confine(path);
157
+ if (abs === null)
158
+ return fsErr('E_PI_FS_DENIED', 'path escapes workspace boundary', path);
159
+ try {
160
+ const res = await this.#guard.readFileText({ path: abs });
161
+ return ok(res.content);
162
+ }
163
+ catch (err) {
164
+ return this.#toFsErr(err, abs);
165
+ }
166
+ }
167
+ /** Read a file's text as an array of lines. */
168
+ async readTextLines(path) {
169
+ const res = await this.readTextFile(path);
170
+ return res.ok ? ok(res.value.split(/\r?\n/)) : res;
171
+ }
172
+ /**
173
+ * Binary read — DENIED in v0. The atomic `readFileText` primitive is
174
+ * text-only (`ReadFileInput.encoding` has no binary variant); a binary
175
+ * primitive must be added under `core/src/tools` (Gate 11) before this is
176
+ * supported. Deny-first: never reaches the filesystem.
177
+ */
178
+ async readBinaryFile(path) {
179
+ return fsErr('E_PI_FS_UNSUPPORTED', 'binary read is not supported in v0', path);
180
+ }
181
+ // --- file writes ---------------------------------------------------------
182
+ /** Atomically write a file, confined to the workspace + guarded. */
183
+ async writeFile(path, content) {
184
+ const abs = await this.#confine(path);
185
+ if (abs === null)
186
+ return fsErr('E_PI_FS_DENIED', 'path escapes workspace boundary', path);
187
+ try {
188
+ await this.#guard.writeFileAtomic({ path: abs, content });
189
+ return ok(undefined);
190
+ }
191
+ catch (err) {
192
+ return this.#toFsErr(err, abs);
193
+ }
194
+ }
195
+ /**
196
+ * Append to a file. The atomic surface offers only whole-file atomic writes,
197
+ * so this reads-then-writes the concatenation (still confined + guarded). A
198
+ * missing file is treated as empty.
199
+ *
200
+ * Confinement happens EXACTLY ONCE here, then the read + write delegate
201
+ * straight to the guard with the already-resolved `abs`. Re-entering the
202
+ * public `readTextFile`/`writeFile` would re-`#confine` the value `#confine`
203
+ * just returned — and because `#confine` yields the SYMLINK-RESOLVED real path
204
+ * (e.g. macOS `/tmp`→`/private/tmp`, or a symlinked workspace root), that real
205
+ * path is `../`-outside the lexical `workspaceRoot`, so the second lexical
206
+ * gate would spuriously reject it (`E_PI_FS_DENIED`). Reading once through the
207
+ * guard — whose own allowlist canonicalizes both sides — avoids the
208
+ * double-confine while keeping the symlink-escape denial intact.
209
+ */
210
+ async appendFile(path, content) {
211
+ const abs = await this.#confine(path);
212
+ if (abs === null)
213
+ return fsErr('E_PI_FS_DENIED', 'path escapes workspace boundary', path);
214
+ // Read existing content directly via the guard (a missing file → ENOENT,
215
+ // treated as empty). Do NOT route through readTextFile: that would re-confine
216
+ // the resolved real path against the lexical root and falsely reject it.
217
+ let prefix = '';
218
+ try {
219
+ const res = await this.#guard.readFileText({ path: abs });
220
+ prefix = res.content;
221
+ }
222
+ catch (err) {
223
+ // A missing file is the only non-fatal case (append-creates). Any other
224
+ // failure (guard denial, permission, …) propagates as the Pi error.
225
+ if (!isMissingFileError(err))
226
+ return this.#toFsErr(err, abs);
227
+ }
228
+ try {
229
+ await this.#guard.writeFileAtomic({ path: abs, content: prefix + content });
230
+ return ok(undefined);
231
+ }
232
+ catch (err) {
233
+ return this.#toFsErr(err, abs);
234
+ }
235
+ }
236
+ // --- metadata ------------------------------------------------------------
237
+ /** Report whether a path is a file or directory, confined + guarded. */
238
+ async fileInfo(path) {
239
+ const abs = await this.#confine(path);
240
+ if (abs === null)
241
+ return fsErr('E_PI_FS_DENIED', 'path escapes workspace boundary', path);
242
+ try {
243
+ const res = await this.#guard.pathExists({ path: abs });
244
+ if (!res.exists)
245
+ return fsErr('E_PI_FS_NOT_FOUND', 'path does not exist', abs);
246
+ return ok({ isFile: res.kind === 'file', isDirectory: res.kind === 'directory' });
247
+ }
248
+ catch (err) {
249
+ return this.#toFsErr(err, abs);
250
+ }
251
+ }
252
+ /** Whether a path exists, confined + guarded. */
253
+ async exists(path) {
254
+ const abs = await this.#confine(path);
255
+ if (abs === null)
256
+ return fsErr('E_PI_FS_DENIED', 'path escapes workspace boundary', path);
257
+ try {
258
+ const res = await this.#guard.pathExists({ path: abs });
259
+ return ok(res.exists);
260
+ }
261
+ catch (err) {
262
+ return this.#toFsErr(err, abs);
263
+ }
264
+ }
265
+ /**
266
+ * Canonicalize a path inside the workspace. SYMLINK-RESOLVING: `#confine`
267
+ * follows every symlink component via `fs.realpath`, so the returned value is
268
+ * the REAL on-disk location (matching Pi's `NodeExecutionEnv.canonicalPath`
269
+ * contract), and a path whose real target escapes the workspace is denied.
270
+ */
271
+ async canonicalPath(path) {
272
+ const abs = await this.#confine(path);
273
+ if (abs === null)
274
+ return fsErr('E_PI_FS_DENIED', 'path escapes workspace boundary', path);
275
+ return ok(abs);
276
+ }
277
+ // --- denied fs-mutating / listing ops (no atomic primitive in v0) --------
278
+ /** DENIED in v0 — no `listDir` atomic primitive. */
279
+ async listDir(path) {
280
+ return fsErr('E_PI_FS_UNSUPPORTED', 'directory listing is not supported in v0', path);
281
+ }
282
+ /** DENIED in v0 — no `createDir` atomic primitive. */
283
+ async createDir(path) {
284
+ return fsErr('E_PI_FS_UNSUPPORTED', 'directory creation is not supported in v0', path);
285
+ }
286
+ /** DENIED in v0 — no `remove` atomic primitive. */
287
+ async remove(path) {
288
+ return fsErr('E_PI_FS_UNSUPPORTED', 'remove is not supported in v0', path);
289
+ }
290
+ /** DENIED in v0 — no temp-dir atomic primitive. */
291
+ async createTempDir() {
292
+ return fsErr('E_PI_FS_UNSUPPORTED', 'temp dir creation is not supported in v0');
293
+ }
294
+ /** DENIED in v0 — no temp-file atomic primitive. */
295
+ async createTempFile() {
296
+ return fsErr('E_PI_FS_UNSUPPORTED', 'temp file creation is not supported in v0');
297
+ }
298
+ // --- shell ---------------------------------------------------------------
299
+ /**
300
+ * Execute a command through the guard's shell surface (denylist applies). The
301
+ * Pi `command` string is a bare executable name (args are passed by Pi via the
302
+ * loop, but the v0 seam takes only `command`); we forward it as the guard's
303
+ * `command` with empty args. `cwd` is symlink-confined to the workspace.
304
+ *
305
+ * ## Env is SCRUBBED before it leaves this seam (T11897 · security)
306
+ *
307
+ * Pi's `options.env` is UNTRUSTED model-driven input. Forwarding it verbatim
308
+ * would let Pi set `LD_PRELOAD`/`NODE_OPTIONS`/`GIT_SSH_COMMAND` (arbitrary
309
+ * native code execution outside any allowlist) or hijack `PATH` to make a
310
+ * workspace-resident impostor satisfy an allowed command basename. So the env
311
+ * is run through {@link scrubSubprocessEnv} HERE — forbidden keys (loader
312
+ * hooks, `PATH`, secrets) are dropped and `PATH` is pinned to a trusted value
313
+ * — before it reaches the guard (which scrubs again as a redundant net, as
314
+ * does `defaultShellExecutor`). This also prevents the daemon's own secrets
315
+ * from leaking into the child (the scrubbed env never inherits `process.env`).
316
+ */
317
+ async exec(command, options) {
318
+ const cwd = options?.cwd ? await this.#confine(options.cwd) : this.#root;
319
+ if (cwd === null) {
320
+ return execErr('E_PI_EXEC_DENIED', 'cwd escapes workspace boundary');
321
+ }
322
+ // Scrub Pi-supplied env to a minimal allowlist at the seam (defense in depth
323
+ // — the guard + executor scrub again). Pi can NOT inject a loader hook,
324
+ // hijack PATH, or read inherited daemon secrets through this channel.
325
+ const env = scrubSubprocessEnv({ extra: options?.env });
326
+ try {
327
+ const res = await this.#guard.executeShell({
328
+ command,
329
+ cwd,
330
+ env,
331
+ ...(options?.timeout !== undefined ? { timeoutMs: options.timeout } : {}),
332
+ });
333
+ return ok({ stdout: res.stdout, stderr: res.stderr, exitCode: res.code });
334
+ }
335
+ catch (err) {
336
+ if (err instanceof GuardDeniedError) {
337
+ return execErr('E_PI_EXEC_DENIED', err.message);
338
+ }
339
+ const message = err instanceof Error ? err.message : String(err);
340
+ return execErr('E_PI_EXEC_FAILED', message);
341
+ }
342
+ }
343
+ // --- cleanup (best-effort, must not throw) -------------------------------
344
+ /** Best-effort cleanup; the guarded surface owns no resources, so a no-op. */
345
+ async cleanup() {
346
+ // no-op — required on both FileSystem + Shell; owns nothing to release.
347
+ }
348
+ // --- error mapping -------------------------------------------------------
349
+ /** Convert a thrown error from the guarded surface into a Pi `Result.err`. */
350
+ #toFsErr(err, path) {
351
+ if (err instanceof GuardDeniedError) {
352
+ return fsErr('E_PI_FS_DENIED', err.message, path);
353
+ }
354
+ const code = typeof err === 'object' && err !== null && 'code' in err
355
+ ? String(err.code)
356
+ : 'E_PI_FS_FAILED';
357
+ const message = err instanceof Error ? err.message : String(err);
358
+ return fsErr(code, message, path);
359
+ }
360
+ }
361
+ /**
362
+ * Thrown by {@link createGuardedExecutionEnv} when the injected guard is NOT in
363
+ * `enforce` mode. In `warn` mode the guard's path allowlist + command denylist
364
+ * are advisory (log-and-proceed), so the second confinement net does not exist
365
+ * and the boundary would collapse to the workspace check alone. The Pi adapter
366
+ * therefore REFUSES a non-enforce guard rather than running untrusted Pi work
367
+ * behind an advisory boundary.
368
+ */
369
+ export class PiGuardModeError extends Error {
370
+ /** Machine-readable code. */
371
+ code = 'E_PI_GUARD_NOT_ENFORCING';
372
+ /**
373
+ * @param mode - The (non-enforce) mode the guard was constructed with.
374
+ */
375
+ constructor(mode) {
376
+ super(`Pi ExecutionEnv requires an enforce-mode ToolGuard; got "${mode}". ` +
377
+ 'In warn mode the path allowlist + command denylist are advisory and provide no boundary.');
378
+ this.name = 'PiGuardModeError';
379
+ }
380
+ }
381
+ /**
382
+ * Construct a deny-first {@link GuardedExecutionEnv}.
383
+ *
384
+ * REQUIRES an `enforce`-mode guard: a `warn`-mode guard's allowlist/denylist are
385
+ * advisory, so handing untrusted Pi work behind one would leave confinement to
386
+ * the workspace boundary alone. The factory ASSERTS the mode and throws
387
+ * {@link PiGuardModeError} otherwise — the Pi adapter never silently degrades to
388
+ * an advisory boundary.
389
+ *
390
+ * @param deps - The guard surface + the workspace root to confine to.
391
+ * @returns A {@link PiExecutionEnv} safe to hand to Pi's agent loop.
392
+ * @throws {PiGuardModeError} When `deps.guard.mode !== 'enforce'`.
393
+ *
394
+ * @example
395
+ * ```ts
396
+ * const guard = createToolGuard({ allowedRoots: [projectRoot], mode: 'enforce' });
397
+ * const env = createGuardedExecutionEnv({ guard, workspaceRoot: projectRoot });
398
+ * ```
399
+ */
400
+ export function createGuardedExecutionEnv(deps) {
401
+ if (deps.guard.mode !== 'enforce') {
402
+ throw new PiGuardModeError(deps.guard.mode);
403
+ }
404
+ return new GuardedExecutionEnv(deps);
405
+ }
406
+ //# sourceMappingURL=pi-execution-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-execution-env.js","sourceRoot":"","sources":["../../../src/llm/pi/pi-execution-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAkC,MAAM,sBAAsB,CAAC;AAyGxF,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,2CAA2C;AAC3C,SAAS,EAAE,CAAI,KAAQ;IACrB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,kEAAkE;AAClE,SAAS,KAAK,CAAC,IAAY,EAAE,OAAe,EAAE,IAAa;IACzD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;AAC1F,CAAC;AAED,uEAAuE;AACvE,SAAS,OAAO,CAAC,IAAY,EAAE,OAAe;IAC5C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;AACjD,CAAC;AAED;;;;;GAKG;AACH,SAAS,kBAAkB,CAAC,GAAY;IACtC,OAAO,CACL,OAAO,GAAG,KAAK,QAAQ;QACvB,GAAG,KAAK,IAAI;QACZ,MAAM,IAAI,GAAG;QACZ,GAA0B,CAAC,IAAI,KAAK,QAAQ,CAC9C,CAAC;AACJ,CAAC;AAqBD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,mBAAmB;IACrB,MAAM,CAAY;IAClB,KAAK,CAAS;IAEvB;;OAEG;IACH,YAAY,IAA6B;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/C,CAAC;IAED;;;;;;;OAOG;IACH,eAAe,CAAC,IAAY;QAC1B,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACjF,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC7C,6EAA6E;QAC7E,gEAAgE;QAChE,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrC,8DAA8D;QAC9D,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC3E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAE5E,sEAAsE;IACtE,GAAG;QACD,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,yEAAyE;IACzE,YAAY,CAAC,IAAY;QACvB,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9E,CAAC;IAED,iCAAiC;IACjC,QAAQ,CAAC,GAAG,QAAkB;QAC5B,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,4EAA4E;IAE5E,+DAA+D;IAC/D,KAAK,CAAC,YAAY,CAAC,IAAY;QAC7B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,gBAAgB,EAAE,iCAAiC,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1D,OAAO,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACrD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,cAAc,CAAC,IAAY;QAC/B,OAAO,KAAK,CAAC,qBAAqB,EAAE,oCAAoC,EAAE,IAAI,CAAC,CAAC;IAClF,CAAC;IAED,4EAA4E;IAE5E,oEAAoE;IACpE,KAAK,CAAC,SAAS,CAAC,IAAY,EAAE,OAAe;QAC3C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,gBAAgB,EAAE,iCAAiC,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;YAC1D,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,OAAe;QAC5C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,gBAAgB,EAAE,iCAAiC,EAAE,IAAI,CAAC,CAAC;QAC1F,yEAAyE;QACzE,8EAA8E;QAC9E,yEAAyE;QACzE,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YAC1D,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wEAAwE;YACxE,oEAAoE;YACpE,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC;gBAAE,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC,CAAC;YAC5E,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,4EAA4E;IAE5E,wEAAwE;IACxE,KAAK,CAAC,QAAQ,CAAC,IAAY;QACzB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,gBAAgB,EAAE,iCAAiC,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,GAAG,CAAC,MAAM;gBAAE,OAAO,KAAK,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,GAAG,CAAC,CAAC;YAC/E,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC,CAAC;QACpF,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,gBAAgB,EAAE,iCAAiC,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;YACxD,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,aAAa,CAAC,IAAY;QAC9B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,GAAG,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC,gBAAgB,EAAE,iCAAiC,EAAE,IAAI,CAAC,CAAC;QAC1F,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,4EAA4E;IAE5E,oDAAoD;IACpD,KAAK,CAAC,OAAO,CAAC,IAAY;QACxB,OAAO,KAAK,CAAC,qBAAqB,EAAE,0CAA0C,EAAE,IAAI,CAAC,CAAC;IACxF,CAAC;IAED,sDAAsD;IACtD,KAAK,CAAC,SAAS,CAAC,IAAY;QAC1B,OAAO,KAAK,CAAC,qBAAqB,EAAE,2CAA2C,EAAE,IAAI,CAAC,CAAC;IACzF,CAAC;IAED,mDAAmD;IACnD,KAAK,CAAC,MAAM,CAAC,IAAY;QACvB,OAAO,KAAK,CAAC,qBAAqB,EAAE,+BAA+B,EAAE,IAAI,CAAC,CAAC;IAC7E,CAAC;IAED,mDAAmD;IACnD,KAAK,CAAC,aAAa;QACjB,OAAO,KAAK,CAAC,qBAAqB,EAAE,0CAA0C,CAAC,CAAC;IAClF,CAAC;IAED,oDAAoD;IACpD,KAAK,CAAC,cAAc;QAClB,OAAO,KAAK,CAAC,qBAAqB,EAAE,2CAA2C,CAAC,CAAC;IACnF,CAAC;IAED,4EAA4E;IAE5E;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAC,IAAI,CACR,OAAe,EACf,OAAuB;QAEvB,MAAM,GAAG,GAAG,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QACzE,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,OAAO,CAAC,kBAAkB,EAAE,gCAAgC,CAAC,CAAC;QACvE,CAAC;QACD,6EAA6E;QAC7E,wEAAwE;QACxE,sEAAsE;QACtE,MAAM,GAAG,GAAG,kBAAkB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;gBACzC,OAAO;gBACP,GAAG;gBACH,GAAG;gBACH,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1E,CAAC,CAAC;YACH,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;gBACpC,OAAO,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;YAClD,CAAC;YACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,4EAA4E;IAE5E,8EAA8E;IAC9E,KAAK,CAAC,OAAO;QACX,wEAAwE;IAC1E,CAAC;IAED,4EAA4E;IAE5E,8EAA8E;IAC9E,QAAQ,CAAC,GAAY,EAAE,IAAY;QACjC,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;YACpC,OAAO,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACpD,CAAC;QACD,MAAM,IAAI,GACR,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG;YACtD,CAAC,CAAC,MAAM,CAAE,GAA0B,CAAC,IAAI,CAAC;YAC1C,CAAC,CAAC,gBAAgB,CAAC;QACvB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACzC,6BAA6B;IACpB,IAAI,GAAG,0BAA0B,CAAC;IAC3C;;OAEG;IACH,YAAY,IAAe;QACzB,KAAK,CACH,4DAA4D,IAAI,KAAK;YACnE,0FAA0F,CAC7F,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAA6B;IACrE,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Gondolin micro-VM Pi `ExecutionEnv` — the SECOND backend of the
3
+ * {@link PiExecutionEnv} seam (T11909 · T11888-B · P5 Gondolin · epic T11599).
4
+ *
5
+ * Where the in-process {@link import('./pi-execution-env.js').GuardedExecutionEnv}
6
+ * (S1 · T11761 · T11897) confines Pi with a deny-first `ToolGuard` + workspace
7
+ * boundary INSIDE the host process, this backend's confinement is the
8
+ * **micro-VM boundary itself**. Guest code runs with:
9
+ *
10
+ * - **ZERO host authority** — no `cleo.db` handle, no writer-lease IPC socket, no
11
+ * host `process.env` secrets, no host filesystem outside the single RW
12
+ * `/workspace` mount. The guest is a different kernel; it cannot reach the
13
+ * daemon, the lease arbiter, or BRAIN even if Pi-driven code tries.
14
+ * - **Egress only via the credential-injection proxy** — `createHttpHooks` is
15
+ * constructed with `allowedHosts: []` (present-and-empty = DENY ALL per the
16
+ * gondolin docs; OMITTING it = allow-all — the egress footgun this guards) and
17
+ * host-side secret PLACEHOLDERS, so the guest only ever sees the `placeholder`
18
+ * bytes, never the real token. The loop appends specific hosts per run.
19
+ * - **Live DBs NEVER mounted** — `.cleo/tasks.db` / `.cleo/brain.db` are NOT in
20
+ * the VFS mount set. A replay operates on a DISPOSABLE seeded copy
21
+ * (`VACUUM INTO` snapshot), so the T5158 data-loss vector (git overwrites the
22
+ * live WAL-backed DB) is structurally impossible: there is no live handle
23
+ * inside the VM to corrupt.
24
+ *
25
+ * This is strictly stronger than S1's env-scrub: S1 protects against an in-process
26
+ * Pi escape via the guard allowlist; Gondolin protects via kernel + VFS + network
27
+ * namespace separation. A thin in-guest deny layer (lexical `/workspace`
28
+ * confinement + a command denylist for real egress verbs) is kept as DEFENSE IN
29
+ * DEPTH — the boundary is the VM, but a Pi escape that runs a binary still cannot
30
+ * do damage that survives the run.
31
+ *
32
+ * Optional-dep discipline (D11142): `@earendil-works/gondolin` is loaded ONLY via
33
+ * the {@link import('./gondolin-loader.js').loadGondolin} dynamic import — it is
34
+ * in NEITHER `dependencies` NOR `optionalDependencies`, and this module declares
35
+ * NO `import type` from the package (the consumed structural shapes come from the
36
+ * loader's LOCAL types). `core` builds + all non-gondolin tests pass with gondolin
37
+ * ABSENT, and this module is import-time side-effect-free (no top-level VM boot).
38
+ *
39
+ * Never-throw discipline: every `vm.fs.*` / `vm.exec` call is wrapped exactly as
40
+ * S1's `#toFsErr` / `execErr` — a thrown gondolin/guest error becomes a
41
+ * {@link PiResult} `err` with `E_PI_FS_*` / `E_PI_EXEC_*` codes. The
42
+ * `PiResult<T, E>` contract is byte-for-byte identical to S1, so the Pi loop
43
+ * cannot tell the two backends apart.
44
+ *
45
+ * @epic T11599
46
+ * @task T11909
47
+ * @see ./pi-execution-env.js — the S1 `GuardedExecutionEnv` this mirrors over a VM
48
+ * @see ./gondolin-loader.js — the optional-dep loader supplying the structural types
49
+ */
50
+ import { type GondolinModule, type SecretDefinition, type VM } from './gondolin-loader.js';
51
+ import type { PiExecOptions, PiExecResult, PiExecutionEnv, PiExecutionError, PiFileError, PiFileInfo, PiResult } from './pi-execution-env.js';
52
+ /** The single RW mount point inside the guest — the ONLY writable location. */
53
+ export declare const GONDOLIN_WORKSPACE_ROOT: "/workspace";
54
+ /**
55
+ * The injectable factory the {@link createGondolinExecutionEnv} uses to obtain
56
+ * the gondolin module. Defaults to the real lazy {@link loadGondolin}; unit
57
+ * tests inject a fake that returns a MOCK module so NO real QEMU VM is launched.
58
+ */
59
+ export type GondolinLoader = () => Promise<GondolinModule | null>;
60
+ /** Construction options for {@link createGondolinExecutionEnv}. */
61
+ export interface CreateGondolinExecutionEnvOptions {
62
+ /**
63
+ * The host directory mounted RW at `/workspace` inside the guest. This MUST be
64
+ * a DISPOSABLE seeded copy (e.g. a `VACUUM INTO` snapshot dir) — NEVER a path
65
+ * containing the live `.cleo/tasks.db` / `.cleo/brain.db`. The factory mounts
66
+ * ONLY this directory; live DBs are structurally absent from the guest VFS.
67
+ */
68
+ readonly seededCopyDir: string;
69
+ /**
70
+ * Outbound host allowlist. Defaults to `[]` (DENY ALL) when omitted — the
71
+ * egress footgun guard. The loop appends ONLY the specific hosts it needs
72
+ * (e.g. the model endpoint via the Vault proxy) per run.
73
+ */
74
+ readonly allowedHosts?: readonly string[];
75
+ /**
76
+ * Host-side secret injections. The guest only ever sees each entry's
77
+ * `placeholder`; the real `value` bytes never enter the VM.
78
+ */
79
+ readonly vaultSecrets?: Readonly<Record<string, SecretDefinition>>;
80
+ /** Guest memory bound (e.g. `"1G"`). Defaults to {@link DEFAULT_GUEST_MEMORY}. */
81
+ readonly memory?: string;
82
+ /**
83
+ * Guest environment — the ONLY env the guest sees (host `process.env` is NEVER
84
+ * inherited; that isolation is structural). Defaults to an empty map.
85
+ */
86
+ readonly env?: Readonly<Record<string, string>>;
87
+ /**
88
+ * Optional loader override (tests inject a fake → a MOCK VM, no QEMU). Defaults
89
+ * to the real {@link loadGondolin}.
90
+ */
91
+ readonly load?: GondolinLoader;
92
+ }
93
+ /**
94
+ * A {@link PiExecutionEnv} whose confinement is a gondolin micro-VM. Owns exactly
95
+ * ONE {@link VM} and releases it in {@link cleanup} via `vm.close()`.
96
+ *
97
+ * Every fs op maps to `vm.fs.*`; `exec` maps to `vm.exec`. Each call is wrapped
98
+ * try/catch → {@link PiResult} `err`, so no method ever throws. A thin in-guest
99
+ * deny layer (lexical `/workspace` confinement + the {@link DENIED_EXEC_PREFIXES}
100
+ * command denylist) is the defense-in-depth net BEHIND the VM boundary.
101
+ *
102
+ * Unlike the stateless {@link import('./pi-execution-env.js').GuardedExecutionEnv}
103
+ * (whose `cleanup()` is a no-op), this env OWNS the VM and MUST release it.
104
+ * `cleanup()` is idempotent (guarded by a `#closed` flag).
105
+ */
106
+ export declare class GondolinExecutionEnv implements PiExecutionEnv {
107
+ #private;
108
+ /**
109
+ * @param vm - The booted gondolin VM this env owns. Construct via
110
+ * {@link createGondolinExecutionEnv}, not directly — the factory wires the
111
+ * deny-by-default egress hooks + seeded-copy-only mount set.
112
+ */
113
+ constructor(vm: VM);
114
+ /** The guest workspace root — the in-VM Pi run's working directory. */
115
+ cwd(): string;
116
+ /** Resolve `path` to a guest-absolute path anchored at `/workspace`. */
117
+ absolutePath(path: string): string;
118
+ /** Join path segments (pure POSIX) anchored at the guest workspace root. */
119
+ joinPath(...segments: string[]): string;
120
+ /** Read a file's text from the guest workspace. */
121
+ readTextFile(path: string): Promise<PiResult<string, PiFileError>>;
122
+ /** Read a file's text as an array of lines. */
123
+ readTextLines(path: string): Promise<PiResult<string[], PiFileError>>;
124
+ /**
125
+ * Binary read — FILLS S1's v0 denial. The guest VFS supports binary reads
126
+ * directly via `vm.fs.readFile(p)` (returns a `Uint8Array`).
127
+ */
128
+ readBinaryFile(path: string): Promise<PiResult<Uint8Array, PiFileError>>;
129
+ /** Write a file to the guest workspace. */
130
+ writeFile(path: string, content: string): Promise<PiResult<void, PiFileError>>;
131
+ /**
132
+ * Append to a file. The guest fs surface offers only whole-file writes, so this
133
+ * reads-then-writes the concatenation (still confined). A missing file is
134
+ * treated as empty (append-creates).
135
+ */
136
+ appendFile(path: string, content: string): Promise<PiResult<void, PiFileError>>;
137
+ /** Report whether a guest path is a file or directory. */
138
+ fileInfo(path: string): Promise<PiResult<PiFileInfo, PiFileError>>;
139
+ /** Whether a guest path exists. */
140
+ exists(path: string): Promise<PiResult<boolean, PiFileError>>;
141
+ /**
142
+ * Canonicalize a guest path via `realpath` inside the guest. Runs the binary in
143
+ * ARRAY form (no `$PATH` / shell expansion) so the path argument cannot be
144
+ * reinterpreted as shell.
145
+ */
146
+ canonicalPath(path: string): Promise<PiResult<string, PiFileError>>;
147
+ /** List a guest directory — FILLS S1's v0 denial. */
148
+ listDir(path: string): Promise<PiResult<string[], PiFileError>>;
149
+ /** Create a guest directory (recursive) — FILLS S1's v0 denial. */
150
+ createDir(path: string): Promise<PiResult<void, PiFileError>>;
151
+ /** Remove a guest path (recursive, force) — FILLS S1's v0 denial. */
152
+ remove(path: string): Promise<PiResult<void, PiFileError>>;
153
+ /**
154
+ * Create a temp directory under `/workspace/.tmp` — FILLS S1's v0 denial. Runs
155
+ * `mktemp -d` in ARRAY form (no `$PATH` / shell expansion).
156
+ */
157
+ createTempDir(prefix?: string): Promise<PiResult<string, PiFileError>>;
158
+ /**
159
+ * Create a temp file under `/workspace/.tmp` — FILLS S1's v0 denial. Runs
160
+ * `mktemp` in ARRAY form (no `$PATH` / shell expansion).
161
+ */
162
+ createTempFile(prefix?: string): Promise<PiResult<string, PiFileError>>;
163
+ /**
164
+ * Execute a command in the guest via `vm.exec`. Deny-first: a real-egress verb
165
+ * ({@link DENIED_EXEC_PREFIXES} — `gh` / `git push` / `npm publish` / `cleo` /
166
+ * `git remote`) is rejected BEFORE reaching the VM, even though the VM itself
167
+ * has no egress (the network namespace is deny-by-default). `cwd` is confined
168
+ * to the workspace; the host `AbortSignal` is forwarded only when supplied.
169
+ *
170
+ * ## exitCode mapping
171
+ *
172
+ * gondolin's `ExecResult.exitCode` is `number` (NON-nullable) with a SEPARATE
173
+ * optional `signal` field; Pi's `PiExecResult.exitCode` is `number | null`
174
+ * ("null when killed by signal"). So a signal-kill is mapped to `null`, NOT
175
+ * the raw `exitCode`.
176
+ */
177
+ exec(command: string, options?: PiExecOptions): Promise<PiResult<PiExecResult, PiExecutionError>>;
178
+ /**
179
+ * Tear down the owned VM (`vm.close()`). Idempotent: a second call is a no-op.
180
+ * Best-effort and never throws (a close failure is logged, not propagated) so
181
+ * the Pi contract — `cleanup()` must not throw — holds.
182
+ */
183
+ cleanup(): Promise<void>;
184
+ }
185
+ /**
186
+ * Thrown by {@link createGondolinExecutionEnv} when the optional
187
+ * `@earendil-works/gondolin` package (or its QEMU/KVM host infra) is not
188
+ * available, so a VM cannot be booted. Callers that want graceful degradation
189
+ * should check `isGondolinAvailable()` first (the selector
190
+ * {@link import('./resolve-execution-env.js')} does this) and fall back to the
191
+ * in-process {@link import('./pi-execution-env.js').GuardedExecutionEnv}.
192
+ */
193
+ export declare class GondolinUnavailableError extends Error {
194
+ /** Machine-readable code. */
195
+ readonly code = "E_GONDOLIN_UNAVAILABLE";
196
+ constructor(message: string);
197
+ }
198
+ /**
199
+ * Boot a gondolin micro-VM and wrap it in a {@link GondolinExecutionEnv}.
200
+ *
201
+ * The VM is configured for ZERO host authority:
202
+ * - **mount set** = ONLY `{ '/workspace': new RealFSProvider(seededCopyDir) }`.
203
+ * The disposable seeded copy is the single RW mount; live `tasks.db`/`brain.db`
204
+ * are structurally absent from the guest VFS (T5158 impossible in-VM).
205
+ * - **egress** = `createHttpHooks({ allowedHosts, secrets })` with `allowedHosts`
206
+ * defaulting to `[]` (DENY ALL — the footgun guard) and host-side secret
207
+ * PLACEHOLDERS (the guest never sees real token bytes).
208
+ * - **env** = ONLY `opts.env` (host `process.env` is NEVER inherited).
209
+ * - **memory** = `opts.memory` (default `"1G"`), set EXPLICITLY.
210
+ *
211
+ * Import-time side-effect-free: the gondolin module is loaded lazily HERE (not at
212
+ * module top-level) via the injectable {@link GondolinLoader} (tests pass a fake
213
+ * → a MOCK VM, so NO real QEMU boots).
214
+ *
215
+ * @param opts - The seeded-copy mount dir + egress allowlist/secrets + guest env.
216
+ * @returns A {@link PiExecutionEnv} backed by the booted VM.
217
+ * @throws {GondolinUnavailableError} When the optional package cannot be loaded.
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * const env = await createGondolinExecutionEnv({ seededCopyDir: snapshotDir });
222
+ * // ... drive Pi's loop over `env` ...
223
+ * await env.cleanup(); // releases the VM
224
+ * ```
225
+ */
226
+ export declare function createGondolinExecutionEnv(opts: CreateGondolinExecutionEnvOptions): Promise<PiExecutionEnv>;
227
+ //# sourceMappingURL=pi-gondolin-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-gondolin-env.d.ts","sourceRoot":"","sources":["../../../src/llm/pi/pi-gondolin-env.ts"],"names":[],"mappings":"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"}