looply-cli 0.0.0-stage → 0.3.0

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 (793) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +137 -3
  3. package/dist/.src-hash +1 -0
  4. package/dist/acceptance-observe.d.ts +108 -0
  5. package/dist/acceptance-observe.d.ts.map +1 -0
  6. package/dist/acceptance-observe.js +152 -0
  7. package/dist/acceptance-observe.js.map +1 -0
  8. package/dist/agent-cmd.d.ts +131 -0
  9. package/dist/agent-cmd.d.ts.map +1 -0
  10. package/dist/agent-cmd.js +154 -0
  11. package/dist/agent-cmd.js.map +1 -0
  12. package/dist/agent-contained.d.ts +114 -0
  13. package/dist/agent-contained.d.ts.map +1 -0
  14. package/dist/agent-contained.js +292 -0
  15. package/dist/agent-contained.js.map +1 -0
  16. package/dist/agent-driver.d.ts +130 -0
  17. package/dist/agent-driver.d.ts.map +1 -0
  18. package/dist/agent-driver.js +170 -0
  19. package/dist/agent-driver.js.map +1 -0
  20. package/dist/agent-envelope.d.ts +94 -0
  21. package/dist/agent-envelope.d.ts.map +1 -0
  22. package/dist/agent-envelope.js +214 -0
  23. package/dist/agent-envelope.js.map +1 -0
  24. package/dist/agent-exec.d.ts +182 -0
  25. package/dist/agent-exec.d.ts.map +1 -0
  26. package/dist/agent-exec.js +125 -0
  27. package/dist/agent-exec.js.map +1 -0
  28. package/dist/agent-runtime.d.ts +23 -0
  29. package/dist/agent-runtime.d.ts.map +1 -0
  30. package/dist/agent-runtime.js +143 -0
  31. package/dist/agent-runtime.js.map +1 -0
  32. package/dist/approval-gate-read.d.ts +66 -0
  33. package/dist/approval-gate-read.d.ts.map +1 -0
  34. package/dist/approval-gate-read.js +138 -0
  35. package/dist/approval-gate-read.js.map +1 -0
  36. package/dist/approval-resolution.d.ts +87 -0
  37. package/dist/approval-resolution.d.ts.map +1 -0
  38. package/dist/approval-resolution.js +100 -0
  39. package/dist/approval-resolution.js.map +1 -0
  40. package/dist/approval-resumes.d.ts +102 -0
  41. package/dist/approval-resumes.d.ts.map +1 -0
  42. package/dist/approval-resumes.js +167 -0
  43. package/dist/approval-resumes.js.map +1 -0
  44. package/dist/ask-brain.d.ts +167 -0
  45. package/dist/ask-brain.d.ts.map +1 -0
  46. package/dist/ask-brain.js +355 -0
  47. package/dist/ask-brain.js.map +1 -0
  48. package/dist/autonomy-authority.d.ts +80 -0
  49. package/dist/autonomy-authority.d.ts.map +1 -0
  50. package/dist/autonomy-authority.js +82 -0
  51. package/dist/autonomy-authority.js.map +1 -0
  52. package/dist/autonomy-controller.d.ts +321 -0
  53. package/dist/autonomy-controller.d.ts.map +1 -0
  54. package/dist/autonomy-controller.js +517 -0
  55. package/dist/autonomy-controller.js.map +1 -0
  56. package/dist/autonomy-store.d.ts +327 -0
  57. package/dist/autonomy-store.d.ts.map +1 -0
  58. package/dist/autonomy-store.js +581 -0
  59. package/dist/autonomy-store.js.map +1 -0
  60. package/dist/autonomy-tick.d.ts +257 -0
  61. package/dist/autonomy-tick.d.ts.map +1 -0
  62. package/dist/autonomy-tick.js +616 -0
  63. package/dist/autonomy-tick.js.map +1 -0
  64. package/dist/bin.d.ts +3 -0
  65. package/dist/bin.d.ts.map +1 -0
  66. package/dist/bin.js +2727 -0
  67. package/dist/bin.js.map +1 -0
  68. package/dist/brain-advice.d.ts +21 -0
  69. package/dist/brain-advice.d.ts.map +1 -0
  70. package/dist/brain-advice.js +51 -0
  71. package/dist/brain-advice.js.map +1 -0
  72. package/dist/candidate-replay-runtime.d.ts +125 -0
  73. package/dist/candidate-replay-runtime.d.ts.map +1 -0
  74. package/dist/candidate-replay-runtime.js +188 -0
  75. package/dist/candidate-replay-runtime.js.map +1 -0
  76. package/dist/checkout-carry.d.ts +76 -0
  77. package/dist/checkout-carry.d.ts.map +1 -0
  78. package/dist/checkout-carry.js +125 -0
  79. package/dist/checkout-carry.js.map +1 -0
  80. package/dist/citation-readers.d.ts +26 -0
  81. package/dist/citation-readers.d.ts.map +1 -0
  82. package/dist/citation-readers.js +102 -0
  83. package/dist/citation-readers.js.map +1 -0
  84. package/dist/command-receipts.d.ts +79 -0
  85. package/dist/command-receipts.d.ts.map +1 -0
  86. package/dist/command-receipts.js +143 -0
  87. package/dist/command-receipts.js.map +1 -0
  88. package/dist/command-runner.d.ts +32 -0
  89. package/dist/command-runner.d.ts.map +1 -0
  90. package/dist/command-runner.js +108 -0
  91. package/dist/command-runner.js.map +1 -0
  92. package/dist/compatible-sets.d.ts +67 -0
  93. package/dist/compatible-sets.d.ts.map +1 -0
  94. package/dist/compatible-sets.js +81 -0
  95. package/dist/compatible-sets.js.map +1 -0
  96. package/dist/compile-check.d.ts +31 -0
  97. package/dist/compile-check.d.ts.map +1 -0
  98. package/dist/compile-check.js +34 -0
  99. package/dist/compile-check.js.map +1 -0
  100. package/dist/compile-store.d.ts +16 -0
  101. package/dist/compile-store.d.ts.map +1 -0
  102. package/dist/compile-store.js +21 -0
  103. package/dist/compile-store.js.map +1 -0
  104. package/dist/completion.d.ts +106 -0
  105. package/dist/completion.d.ts.map +1 -0
  106. package/dist/completion.js +131 -0
  107. package/dist/completion.js.map +1 -0
  108. package/dist/config.d.ts +549 -0
  109. package/dist/config.d.ts.map +1 -0
  110. package/dist/config.js +763 -0
  111. package/dist/config.js.map +1 -0
  112. package/dist/control-file.d.ts +142 -0
  113. package/dist/control-file.d.ts.map +1 -0
  114. package/dist/control-file.js +144 -0
  115. package/dist/control-file.js.map +1 -0
  116. package/dist/coordinator-state.d.ts +131 -0
  117. package/dist/coordinator-state.d.ts.map +1 -0
  118. package/dist/coordinator-state.js +380 -0
  119. package/dist/coordinator-state.js.map +1 -0
  120. package/dist/coordinator.d.ts +95 -0
  121. package/dist/coordinator.d.ts.map +1 -0
  122. package/dist/coordinator.js +97 -0
  123. package/dist/coordinator.js.map +1 -0
  124. package/dist/cursor-store.d.ts +53 -0
  125. package/dist/cursor-store.d.ts.map +1 -0
  126. package/dist/cursor-store.js +98 -0
  127. package/dist/cursor-store.js.map +1 -0
  128. package/dist/daemon-cmd.d.ts +239 -0
  129. package/dist/daemon-cmd.d.ts.map +1 -0
  130. package/dist/daemon-cmd.js +1751 -0
  131. package/dist/daemon-cmd.js.map +1 -0
  132. package/dist/daemon-lock.d.ts +140 -0
  133. package/dist/daemon-lock.d.ts.map +1 -0
  134. package/dist/daemon-lock.js +352 -0
  135. package/dist/daemon-lock.js.map +1 -0
  136. package/dist/daemon-recovery.d.ts +78 -0
  137. package/dist/daemon-recovery.d.ts.map +1 -0
  138. package/dist/daemon-recovery.js +161 -0
  139. package/dist/daemon-recovery.js.map +1 -0
  140. package/dist/daemon.d.ts +368 -0
  141. package/dist/daemon.d.ts.map +1 -0
  142. package/dist/daemon.js +601 -0
  143. package/dist/daemon.js.map +1 -0
  144. package/dist/declared-response-shape.d.ts +93 -0
  145. package/dist/declared-response-shape.d.ts.map +1 -0
  146. package/dist/declared-response-shape.js +200 -0
  147. package/dist/declared-response-shape.js.map +1 -0
  148. package/dist/declared-surfaces.d.ts +16 -0
  149. package/dist/declared-surfaces.d.ts.map +1 -0
  150. package/dist/declared-surfaces.js +19 -0
  151. package/dist/declared-surfaces.js.map +1 -0
  152. package/dist/depends-review.d.ts +113 -0
  153. package/dist/depends-review.d.ts.map +1 -0
  154. package/dist/depends-review.js +110 -0
  155. package/dist/depends-review.js.map +1 -0
  156. package/dist/doctor.d.ts +91 -0
  157. package/dist/doctor.d.ts.map +1 -0
  158. package/dist/doctor.js +71 -0
  159. package/dist/doctor.js.map +1 -0
  160. package/dist/edge-approval.d.ts +105 -0
  161. package/dist/edge-approval.d.ts.map +1 -0
  162. package/dist/edge-approval.js +100 -0
  163. package/dist/edge-approval.js.map +1 -0
  164. package/dist/evidence-cache.d.ts +45 -0
  165. package/dist/evidence-cache.d.ts.map +1 -0
  166. package/dist/evidence-cache.js +90 -0
  167. package/dist/evidence-cache.js.map +1 -0
  168. package/dist/evidence-cmd.d.ts +133 -0
  169. package/dist/evidence-cmd.d.ts.map +1 -0
  170. package/dist/evidence-cmd.js +347 -0
  171. package/dist/evidence-cmd.js.map +1 -0
  172. package/dist/evidence-facts.d.ts +40 -0
  173. package/dist/evidence-facts.d.ts.map +1 -0
  174. package/dist/evidence-facts.js +114 -0
  175. package/dist/evidence-facts.js.map +1 -0
  176. package/dist/exclusive-lock.d.ts +52 -0
  177. package/dist/exclusive-lock.d.ts.map +1 -0
  178. package/dist/exclusive-lock.js +150 -0
  179. package/dist/exclusive-lock.js.map +1 -0
  180. package/dist/exec-domains.d.ts +140 -0
  181. package/dist/exec-domains.d.ts.map +1 -0
  182. package/dist/exec-domains.js +287 -0
  183. package/dist/exec-domains.js.map +1 -0
  184. package/dist/exemption-store.d.ts +197 -0
  185. package/dist/exemption-store.d.ts.map +1 -0
  186. package/dist/exemption-store.js +266 -0
  187. package/dist/exemption-store.js.map +1 -0
  188. package/dist/explicit-start-gate.d.ts +96 -0
  189. package/dist/explicit-start-gate.d.ts.map +1 -0
  190. package/dist/explicit-start-gate.js +103 -0
  191. package/dist/explicit-start-gate.js.map +1 -0
  192. package/dist/fs-trouble.d.ts +70 -0
  193. package/dist/fs-trouble.d.ts.map +1 -0
  194. package/dist/fs-trouble.js +98 -0
  195. package/dist/fs-trouble.js.map +1 -0
  196. package/dist/gate.d.ts +278 -0
  197. package/dist/gate.d.ts.map +1 -0
  198. package/dist/gate.js +278 -0
  199. package/dist/gate.js.map +1 -0
  200. package/dist/git-driver.d.ts +519 -0
  201. package/dist/git-driver.d.ts.map +1 -0
  202. package/dist/git-driver.js +900 -0
  203. package/dist/git-driver.js.map +1 -0
  204. package/dist/git-push-executor.d.ts +41 -0
  205. package/dist/git-push-executor.d.ts.map +1 -0
  206. package/dist/git-push-executor.js +142 -0
  207. package/dist/git-push-executor.js.map +1 -0
  208. package/dist/glob.d.ts +26 -0
  209. package/dist/glob.d.ts.map +1 -0
  210. package/dist/glob.js +93 -0
  211. package/dist/glob.js.map +1 -0
  212. package/dist/goal-adaptive.d.ts +295 -0
  213. package/dist/goal-adaptive.d.ts.map +1 -0
  214. package/dist/goal-adaptive.js +393 -0
  215. package/dist/goal-adaptive.js.map +1 -0
  216. package/dist/goal-compile.d.ts +342 -0
  217. package/dist/goal-compile.d.ts.map +1 -0
  218. package/dist/goal-compile.js +444 -0
  219. package/dist/goal-compile.js.map +1 -0
  220. package/dist/goal-depends-executor.d.ts +55 -0
  221. package/dist/goal-depends-executor.d.ts.map +1 -0
  222. package/dist/goal-depends-executor.js +202 -0
  223. package/dist/goal-depends-executor.js.map +1 -0
  224. package/dist/goal-execution-evidence.d.ts +135 -0
  225. package/dist/goal-execution-evidence.d.ts.map +1 -0
  226. package/dist/goal-execution-evidence.js +159 -0
  227. package/dist/goal-execution-evidence.js.map +1 -0
  228. package/dist/goal-gap.d.ts +140 -0
  229. package/dist/goal-gap.d.ts.map +1 -0
  230. package/dist/goal-gap.js +197 -0
  231. package/dist/goal-gap.js.map +1 -0
  232. package/dist/goal-met-target.d.ts +98 -0
  233. package/dist/goal-met-target.d.ts.map +1 -0
  234. package/dist/goal-met-target.js +92 -0
  235. package/dist/goal-met-target.js.map +1 -0
  236. package/dist/goal-ownership.d.ts +416 -0
  237. package/dist/goal-ownership.d.ts.map +1 -0
  238. package/dist/goal-ownership.js +576 -0
  239. package/dist/goal-ownership.js.map +1 -0
  240. package/dist/goal-runs.d.ts +82 -0
  241. package/dist/goal-runs.d.ts.map +1 -0
  242. package/dist/goal-runs.js +120 -0
  243. package/dist/goal-runs.js.map +1 -0
  244. package/dist/goal-store.d.ts +146 -0
  245. package/dist/goal-store.d.ts.map +1 -0
  246. package/dist/goal-store.js +294 -0
  247. package/dist/goal-store.js.map +1 -0
  248. package/dist/goal-view.d.ts +156 -0
  249. package/dist/goal-view.d.ts.map +1 -0
  250. package/dist/goal-view.js +499 -0
  251. package/dist/goal-view.js.map +1 -0
  252. package/dist/governed-approvals.d.ts +152 -0
  253. package/dist/governed-approvals.d.ts.map +1 -0
  254. package/dist/governed-approvals.js +246 -0
  255. package/dist/governed-approvals.js.map +1 -0
  256. package/dist/governed-broker.d.ts +169 -0
  257. package/dist/governed-broker.d.ts.map +1 -0
  258. package/dist/governed-broker.js +196 -0
  259. package/dist/governed-broker.js.map +1 -0
  260. package/dist/governed-run.d.ts +220 -0
  261. package/dist/governed-run.d.ts.map +1 -0
  262. package/dist/governed-run.js +406 -0
  263. package/dist/governed-run.js.map +1 -0
  264. package/dist/grant-reconcile.d.ts +63 -0
  265. package/dist/grant-reconcile.d.ts.map +1 -0
  266. package/dist/grant-reconcile.js +121 -0
  267. package/dist/grant-reconcile.js.map +1 -0
  268. package/dist/index-for-head.d.ts +56 -0
  269. package/dist/index-for-head.d.ts.map +1 -0
  270. package/dist/index-for-head.js +103 -0
  271. package/dist/index-for-head.js.map +1 -0
  272. package/dist/index.d.ts +39 -0
  273. package/dist/index.d.ts.map +1 -0
  274. package/dist/index.js +55 -0
  275. package/dist/index.js.map +1 -0
  276. package/dist/init-detect.d.ts +39 -0
  277. package/dist/init-detect.d.ts.map +1 -0
  278. package/dist/init-detect.js +188 -0
  279. package/dist/init-detect.js.map +1 -0
  280. package/dist/integration-deps.d.ts +62 -0
  281. package/dist/integration-deps.d.ts.map +1 -0
  282. package/dist/integration-deps.js +251 -0
  283. package/dist/integration-deps.js.map +1 -0
  284. package/dist/integration-runtime.d.ts +458 -0
  285. package/dist/integration-runtime.d.ts.map +1 -0
  286. package/dist/integration-runtime.js +681 -0
  287. package/dist/integration-runtime.js.map +1 -0
  288. package/dist/integration.d.ts +45 -0
  289. package/dist/integration.d.ts.map +1 -0
  290. package/dist/integration.js +87 -0
  291. package/dist/integration.js.map +1 -0
  292. package/dist/integrator.d.ts +84 -0
  293. package/dist/integrator.d.ts.map +1 -0
  294. package/dist/integrator.js +193 -0
  295. package/dist/integrator.js.map +1 -0
  296. package/dist/lane-claims.d.ts +174 -0
  297. package/dist/lane-claims.d.ts.map +1 -0
  298. package/dist/lane-claims.js +218 -0
  299. package/dist/lane-claims.js.map +1 -0
  300. package/dist/lane-coverage.d.ts +87 -0
  301. package/dist/lane-coverage.d.ts.map +1 -0
  302. package/dist/lane-coverage.js +129 -0
  303. package/dist/lane-coverage.js.map +1 -0
  304. package/dist/ledger-replay.d.ts +115 -0
  305. package/dist/ledger-replay.d.ts.map +1 -0
  306. package/dist/ledger-replay.js +155 -0
  307. package/dist/ledger-replay.js.map +1 -0
  308. package/dist/ledger-store.d.ts +68 -0
  309. package/dist/ledger-store.d.ts.map +1 -0
  310. package/dist/ledger-store.js +111 -0
  311. package/dist/ledger-store.js.map +1 -0
  312. package/dist/loop-safety-observer.d.ts +132 -0
  313. package/dist/loop-safety-observer.d.ts.map +1 -0
  314. package/dist/loop-safety-observer.js +76 -0
  315. package/dist/loop-safety-observer.js.map +1 -0
  316. package/dist/loop-safety-store.d.ts +339 -0
  317. package/dist/loop-safety-store.d.ts.map +1 -0
  318. package/dist/loop-safety-store.js +800 -0
  319. package/dist/loop-safety-store.js.map +1 -0
  320. package/dist/machine-store.d.ts +54 -0
  321. package/dist/machine-store.d.ts.map +1 -0
  322. package/dist/machine-store.js +149 -0
  323. package/dist/machine-store.js.map +1 -0
  324. package/dist/mcp-main.d.ts +2 -0
  325. package/dist/mcp-main.d.ts.map +1 -0
  326. package/dist/mcp-main.js +116 -0
  327. package/dist/mcp-main.js.map +1 -0
  328. package/dist/mcp-server.d.ts +72 -0
  329. package/dist/mcp-server.d.ts.map +1 -0
  330. package/dist/mcp-server.js +259 -0
  331. package/dist/mcp-server.js.map +1 -0
  332. package/dist/model-routing.d.ts +75 -0
  333. package/dist/model-routing.d.ts.map +1 -0
  334. package/dist/model-routing.js +108 -0
  335. package/dist/model-routing.js.map +1 -0
  336. package/dist/model-transport.d.ts +188 -0
  337. package/dist/model-transport.d.ts.map +1 -0
  338. package/dist/model-transport.js +625 -0
  339. package/dist/model-transport.js.map +1 -0
  340. package/dist/notify-cadence.d.ts +55 -0
  341. package/dist/notify-cadence.d.ts.map +1 -0
  342. package/dist/notify-cadence.js +68 -0
  343. package/dist/notify-cadence.js.map +1 -0
  344. package/dist/notify-channel.d.ts +69 -0
  345. package/dist/notify-channel.d.ts.map +1 -0
  346. package/dist/notify-channel.js +151 -0
  347. package/dist/notify-channel.js.map +1 -0
  348. package/dist/notify.d.ts +71 -0
  349. package/dist/notify.d.ts.map +1 -0
  350. package/dist/notify.js +125 -0
  351. package/dist/notify.js.map +1 -0
  352. package/dist/observation-inventory.d.ts +65 -0
  353. package/dist/observation-inventory.d.ts.map +1 -0
  354. package/dist/observation-inventory.js +139 -0
  355. package/dist/observation-inventory.js.map +1 -0
  356. package/dist/owned-children.d.ts +45 -0
  357. package/dist/owned-children.d.ts.map +1 -0
  358. package/dist/owned-children.js +64 -0
  359. package/dist/owned-children.js.map +1 -0
  360. package/dist/packet-for-goal.d.ts +19 -0
  361. package/dist/packet-for-goal.d.ts.map +1 -0
  362. package/dist/packet-for-goal.js +32 -0
  363. package/dist/packet-for-goal.js.map +1 -0
  364. package/dist/pair-cmd.d.ts +85 -0
  365. package/dist/pair-cmd.d.ts.map +1 -0
  366. package/dist/pair-cmd.js +205 -0
  367. package/dist/pair-cmd.js.map +1 -0
  368. package/dist/partial-asker.d.ts +96 -0
  369. package/dist/partial-asker.d.ts.map +1 -0
  370. package/dist/partial-asker.js +117 -0
  371. package/dist/partial-asker.js.map +1 -0
  372. package/dist/pdf-text-lines.d.ts +17 -0
  373. package/dist/pdf-text-lines.d.ts.map +1 -0
  374. package/dist/pdf-text-lines.js +70 -0
  375. package/dist/pdf-text-lines.js.map +1 -0
  376. package/dist/pdf-text-worker.d.ts +2 -0
  377. package/dist/pdf-text-worker.d.ts.map +1 -0
  378. package/dist/pdf-text-worker.js +81 -0
  379. package/dist/pdf-text-worker.js.map +1 -0
  380. package/dist/pdf-text.d.ts +56 -0
  381. package/dist/pdf-text.d.ts.map +1 -0
  382. package/dist/pdf-text.js +64 -0
  383. package/dist/pdf-text.js.map +1 -0
  384. package/dist/pending-action.d.ts +154 -0
  385. package/dist/pending-action.d.ts.map +1 -0
  386. package/dist/pending-action.js +148 -0
  387. package/dist/pending-action.js.map +1 -0
  388. package/dist/preemptor.d.ts +40 -0
  389. package/dist/preemptor.d.ts.map +1 -0
  390. package/dist/preemptor.js +49 -0
  391. package/dist/preemptor.js.map +1 -0
  392. package/dist/programme-mode.d.ts +29 -0
  393. package/dist/programme-mode.d.ts.map +1 -0
  394. package/dist/programme-mode.js +50 -0
  395. package/dist/programme-mode.js.map +1 -0
  396. package/dist/progress-view.d.ts +14 -0
  397. package/dist/progress-view.d.ts.map +1 -0
  398. package/dist/progress-view.js +114 -0
  399. package/dist/progress-view.js.map +1 -0
  400. package/dist/project-graph-builder.d.ts +81 -0
  401. package/dist/project-graph-builder.d.ts.map +1 -0
  402. package/dist/project-graph-builder.js +246 -0
  403. package/dist/project-graph-builder.js.map +1 -0
  404. package/dist/project-graph-runtime.d.ts +86 -0
  405. package/dist/project-graph-runtime.d.ts.map +1 -0
  406. package/dist/project-graph-runtime.js +112 -0
  407. package/dist/project-graph-runtime.js.map +1 -0
  408. package/dist/project-index-builder.d.ts +96 -0
  409. package/dist/project-index-builder.d.ts.map +1 -0
  410. package/dist/project-index-builder.js +298 -0
  411. package/dist/project-index-builder.js.map +1 -0
  412. package/dist/project-index-facts.d.ts +51 -0
  413. package/dist/project-index-facts.d.ts.map +1 -0
  414. package/dist/project-index-facts.js +117 -0
  415. package/dist/project-index-facts.js.map +1 -0
  416. package/dist/project-index-store.d.ts +97 -0
  417. package/dist/project-index-store.d.ts.map +1 -0
  418. package/dist/project-index-store.js +140 -0
  419. package/dist/project-index-store.js.map +1 -0
  420. package/dist/project-memory-store.d.ts +127 -0
  421. package/dist/project-memory-store.d.ts.map +1 -0
  422. package/dist/project-memory-store.js +302 -0
  423. package/dist/project-memory-store.js.map +1 -0
  424. package/dist/proposal-store.d.ts +14 -0
  425. package/dist/proposal-store.d.ts.map +1 -0
  426. package/dist/proposal-store.js +19 -0
  427. package/dist/proposal-store.js.map +1 -0
  428. package/dist/prover.d.ts +80 -0
  429. package/dist/prover.d.ts.map +1 -0
  430. package/dist/prover.js +137 -0
  431. package/dist/prover.js.map +1 -0
  432. package/dist/provider-identity-store.d.ts +34 -0
  433. package/dist/provider-identity-store.d.ts.map +1 -0
  434. package/dist/provider-identity-store.js +72 -0
  435. package/dist/provider-identity-store.js.map +1 -0
  436. package/dist/provider-identity.d.ts +104 -0
  437. package/dist/provider-identity.d.ts.map +1 -0
  438. package/dist/provider-identity.js +167 -0
  439. package/dist/provider-identity.js.map +1 -0
  440. package/dist/provider-limit.d.ts +79 -0
  441. package/dist/provider-limit.d.ts.map +1 -0
  442. package/dist/provider-limit.js +148 -0
  443. package/dist/provider-limit.js.map +1 -0
  444. package/dist/provider-preflight.d.ts +171 -0
  445. package/dist/provider-preflight.d.ts.map +1 -0
  446. package/dist/provider-preflight.js +395 -0
  447. package/dist/provider-preflight.js.map +1 -0
  448. package/dist/provider-state.d.ts +120 -0
  449. package/dist/provider-state.d.ts.map +1 -0
  450. package/dist/provider-state.js +182 -0
  451. package/dist/provider-state.js.map +1 -0
  452. package/dist/providers.d.ts +132 -0
  453. package/dist/providers.d.ts.map +1 -0
  454. package/dist/providers.js +161 -0
  455. package/dist/providers.js.map +1 -0
  456. package/dist/publication-recorder.d.ts +117 -0
  457. package/dist/publication-recorder.d.ts.map +1 -0
  458. package/dist/publication-recorder.js +124 -0
  459. package/dist/publication-recorder.js.map +1 -0
  460. package/dist/pursuit-delivery.d.ts +24 -0
  461. package/dist/pursuit-delivery.d.ts.map +1 -0
  462. package/dist/pursuit-delivery.js +38 -0
  463. package/dist/pursuit-delivery.js.map +1 -0
  464. package/dist/queue-store.d.ts +132 -0
  465. package/dist/queue-store.d.ts.map +1 -0
  466. package/dist/queue-store.js +185 -0
  467. package/dist/queue-store.js.map +1 -0
  468. package/dist/queue-summary.d.ts +14 -0
  469. package/dist/queue-summary.d.ts.map +1 -0
  470. package/dist/queue-summary.js +82 -0
  471. package/dist/queue-summary.js.map +1 -0
  472. package/dist/queue-view.d.ts +20 -0
  473. package/dist/queue-view.d.ts.map +1 -0
  474. package/dist/queue-view.js +163 -0
  475. package/dist/queue-view.js.map +1 -0
  476. package/dist/queue-write-lease.d.ts +106 -0
  477. package/dist/queue-write-lease.d.ts.map +1 -0
  478. package/dist/queue-write-lease.js +282 -0
  479. package/dist/queue-write-lease.js.map +1 -0
  480. package/dist/rails-home.d.ts +162 -0
  481. package/dist/rails-home.d.ts.map +1 -0
  482. package/dist/rails-home.js +452 -0
  483. package/dist/rails-home.js.map +1 -0
  484. package/dist/rails-migrations.d.ts +75 -0
  485. package/dist/rails-migrations.d.ts.map +1 -0
  486. package/dist/rails-migrations.js +199 -0
  487. package/dist/rails-migrations.js.map +1 -0
  488. package/dist/rails-stores.d.ts +49 -0
  489. package/dist/rails-stores.d.ts.map +1 -0
  490. package/dist/rails-stores.js +100 -0
  491. package/dist/rails-stores.js.map +1 -0
  492. package/dist/reaper.d.ts +69 -0
  493. package/dist/reaper.d.ts.map +1 -0
  494. package/dist/reaper.js +152 -0
  495. package/dist/reaper.js.map +1 -0
  496. package/dist/record-store.d.ts +36 -0
  497. package/dist/record-store.d.ts.map +1 -0
  498. package/dist/record-store.js +78 -0
  499. package/dist/record-store.js.map +1 -0
  500. package/dist/recovery-io.d.ts +50 -0
  501. package/dist/recovery-io.d.ts.map +1 -0
  502. package/dist/recovery-io.js +122 -0
  503. package/dist/recovery-io.js.map +1 -0
  504. package/dist/recovery.d.ts +146 -0
  505. package/dist/recovery.d.ts.map +1 -0
  506. package/dist/recovery.js +110 -0
  507. package/dist/recovery.js.map +1 -0
  508. package/dist/redraw.d.ts +34 -0
  509. package/dist/redraw.d.ts.map +1 -0
  510. package/dist/redraw.js +62 -0
  511. package/dist/redraw.js.map +1 -0
  512. package/dist/rejected-evidence.d.ts +255 -0
  513. package/dist/rejected-evidence.d.ts.map +1 -0
  514. package/dist/rejected-evidence.js +324 -0
  515. package/dist/rejected-evidence.js.map +1 -0
  516. package/dist/report-cmd.d.ts +32 -0
  517. package/dist/report-cmd.d.ts.map +1 -0
  518. package/dist/report-cmd.js +201 -0
  519. package/dist/report-cmd.js.map +1 -0
  520. package/dist/repos-cmd.d.ts +80 -0
  521. package/dist/repos-cmd.d.ts.map +1 -0
  522. package/dist/repos-cmd.js +240 -0
  523. package/dist/repos-cmd.js.map +1 -0
  524. package/dist/request-body-shape.d.ts +93 -0
  525. package/dist/request-body-shape.d.ts.map +1 -0
  526. package/dist/request-body-shape.js +407 -0
  527. package/dist/request-body-shape.js.map +1 -0
  528. package/dist/requirement-claims.d.ts +89 -0
  529. package/dist/requirement-claims.d.ts.map +1 -0
  530. package/dist/requirement-claims.js +92 -0
  531. package/dist/requirement-claims.js.map +1 -0
  532. package/dist/retention-apply-runtime.d.ts +105 -0
  533. package/dist/retention-apply-runtime.d.ts.map +1 -0
  534. package/dist/retention-apply-runtime.js +269 -0
  535. package/dist/retention-apply-runtime.js.map +1 -0
  536. package/dist/reverify.d.ts +41 -0
  537. package/dist/reverify.d.ts.map +1 -0
  538. package/dist/reverify.js +69 -0
  539. package/dist/reverify.js.map +1 -0
  540. package/dist/round-records.d.ts +65 -0
  541. package/dist/round-records.d.ts.map +1 -0
  542. package/dist/round-records.js +61 -0
  543. package/dist/round-records.js.map +1 -0
  544. package/dist/round-runner.d.ts +924 -0
  545. package/dist/round-runner.d.ts.map +1 -0
  546. package/dist/round-runner.js +1693 -0
  547. package/dist/round-runner.js.map +1 -0
  548. package/dist/run-approval.d.ts +180 -0
  549. package/dist/run-approval.d.ts.map +1 -0
  550. package/dist/run-approval.js +199 -0
  551. package/dist/run-approval.js.map +1 -0
  552. package/dist/run-cmd.d.ts +359 -0
  553. package/dist/run-cmd.d.ts.map +1 -0
  554. package/dist/run-cmd.js +4418 -0
  555. package/dist/run-cmd.js.map +1 -0
  556. package/dist/run-delivery.d.ts +71 -0
  557. package/dist/run-delivery.d.ts.map +1 -0
  558. package/dist/run-delivery.js +104 -0
  559. package/dist/run-delivery.js.map +1 -0
  560. package/dist/run-ended.d.ts +75 -0
  561. package/dist/run-ended.d.ts.map +1 -0
  562. package/dist/run-ended.js +27 -0
  563. package/dist/run-ended.js.map +1 -0
  564. package/dist/run-ending-locator.d.ts +125 -0
  565. package/dist/run-ending-locator.d.ts.map +1 -0
  566. package/dist/run-ending-locator.js +133 -0
  567. package/dist/run-ending-locator.js.map +1 -0
  568. package/dist/run-launcher.d.ts +459 -0
  569. package/dist/run-launcher.d.ts.map +1 -0
  570. package/dist/run-launcher.js +652 -0
  571. package/dist/run-launcher.js.map +1 -0
  572. package/dist/run-lease.d.ts +208 -0
  573. package/dist/run-lease.d.ts.map +1 -0
  574. package/dist/run-lease.js +301 -0
  575. package/dist/run-lease.js.map +1 -0
  576. package/dist/run-refusal-marks.d.ts +189 -0
  577. package/dist/run-refusal-marks.d.ts.map +1 -0
  578. package/dist/run-refusal-marks.js +249 -0
  579. package/dist/run-refusal-marks.js.map +1 -0
  580. package/dist/run-start-marks.d.ts +153 -0
  581. package/dist/run-start-marks.d.ts.map +1 -0
  582. package/dist/run-start-marks.js +269 -0
  583. package/dist/run-start-marks.js.map +1 -0
  584. package/dist/scan-cmd.d.ts +14 -0
  585. package/dist/scan-cmd.d.ts.map +1 -0
  586. package/dist/scan-cmd.js +270 -0
  587. package/dist/scan-cmd.js.map +1 -0
  588. package/dist/scan-events.d.ts +50 -0
  589. package/dist/scan-events.d.ts.map +1 -0
  590. package/dist/scan-events.js +91 -0
  591. package/dist/scan-events.js.map +1 -0
  592. package/dist/scan.d.ts +191 -0
  593. package/dist/scan.d.ts.map +1 -0
  594. package/dist/scan.js +417 -0
  595. package/dist/scan.js.map +1 -0
  596. package/dist/scope-rule.d.ts +148 -0
  597. package/dist/scope-rule.d.ts.map +1 -0
  598. package/dist/scope-rule.js +121 -0
  599. package/dist/scope-rule.js.map +1 -0
  600. package/dist/self-repo-id.d.ts +18 -0
  601. package/dist/self-repo-id.d.ts.map +1 -0
  602. package/dist/self-repo-id.js +70 -0
  603. package/dist/self-repo-id.js.map +1 -0
  604. package/dist/serve-cmd.d.ts +115 -0
  605. package/dist/serve-cmd.d.ts.map +1 -0
  606. package/dist/serve-cmd.js +505 -0
  607. package/dist/serve-cmd.js.map +1 -0
  608. package/dist/serve.d.ts +167 -0
  609. package/dist/serve.d.ts.map +1 -0
  610. package/dist/serve.js +336 -0
  611. package/dist/serve.js.map +1 -0
  612. package/dist/server-client.d.ts +766 -0
  613. package/dist/server-client.d.ts.map +1 -0
  614. package/dist/server-client.js +475 -0
  615. package/dist/server-client.js.map +1 -0
  616. package/dist/session-adapter-runtime.d.ts +195 -0
  617. package/dist/session-adapter-runtime.d.ts.map +1 -0
  618. package/dist/session-adapter-runtime.js +373 -0
  619. package/dist/session-adapter-runtime.js.map +1 -0
  620. package/dist/session-checkpoint-runtime.d.ts +62 -0
  621. package/dist/session-checkpoint-runtime.d.ts.map +1 -0
  622. package/dist/session-checkpoint-runtime.js +268 -0
  623. package/dist/session-checkpoint-runtime.js.map +1 -0
  624. package/dist/session-control-transport.d.ts +106 -0
  625. package/dist/session-control-transport.d.ts.map +1 -0
  626. package/dist/session-control-transport.js +232 -0
  627. package/dist/session-control-transport.js.map +1 -0
  628. package/dist/session-observation-store.d.ts +98 -0
  629. package/dist/session-observation-store.d.ts.map +1 -0
  630. package/dist/session-observation-store.js +155 -0
  631. package/dist/session-observation-store.js.map +1 -0
  632. package/dist/session-observe-runtime.d.ts +123 -0
  633. package/dist/session-observe-runtime.d.ts.map +1 -0
  634. package/dist/session-observe-runtime.js +317 -0
  635. package/dist/session-observe-runtime.js.map +1 -0
  636. package/dist/session-store.d.ts +98 -0
  637. package/dist/session-store.d.ts.map +1 -0
  638. package/dist/session-store.js +116 -0
  639. package/dist/session-store.js.map +1 -0
  640. package/dist/sessions-cmd.d.ts +202 -0
  641. package/dist/sessions-cmd.d.ts.map +1 -0
  642. package/dist/sessions-cmd.js +609 -0
  643. package/dist/sessions-cmd.js.map +1 -0
  644. package/dist/settings-overlay.d.ts +53 -0
  645. package/dist/settings-overlay.d.ts.map +1 -0
  646. package/dist/settings-overlay.js +175 -0
  647. package/dist/settings-overlay.js.map +1 -0
  648. package/dist/setup-prompt.d.ts +34 -0
  649. package/dist/setup-prompt.d.ts.map +1 -0
  650. package/dist/setup-prompt.js +92 -0
  651. package/dist/setup-prompt.js.map +1 -0
  652. package/dist/setup.d.ts +103 -0
  653. package/dist/setup.d.ts.map +1 -0
  654. package/dist/setup.js +283 -0
  655. package/dist/setup.js.map +1 -0
  656. package/dist/shared-grants.d.ts +164 -0
  657. package/dist/shared-grants.d.ts.map +1 -0
  658. package/dist/shared-grants.js +242 -0
  659. package/dist/shared-grants.js.map +1 -0
  660. package/dist/signals.d.ts +55 -0
  661. package/dist/signals.d.ts.map +1 -0
  662. package/dist/signals.js +85 -0
  663. package/dist/signals.js.map +1 -0
  664. package/dist/source-cmd.d.ts +201 -0
  665. package/dist/source-cmd.d.ts.map +1 -0
  666. package/dist/source-cmd.js +684 -0
  667. package/dist/source-cmd.js.map +1 -0
  668. package/dist/source-verdict.d.ts +99 -0
  669. package/dist/source-verdict.d.ts.map +1 -0
  670. package/dist/source-verdict.js +182 -0
  671. package/dist/source-verdict.js.map +1 -0
  672. package/dist/spend-ledger.d.ts +350 -0
  673. package/dist/spend-ledger.d.ts.map +1 -0
  674. package/dist/spend-ledger.js +546 -0
  675. package/dist/spend-ledger.js.map +1 -0
  676. package/dist/stale-run-sweep.d.ts +79 -0
  677. package/dist/stale-run-sweep.d.ts.map +1 -0
  678. package/dist/stale-run-sweep.js +116 -0
  679. package/dist/stale-run-sweep.js.map +1 -0
  680. package/dist/start-attempts.d.ts +385 -0
  681. package/dist/start-attempts.d.ts.map +1 -0
  682. package/dist/start-attempts.js +613 -0
  683. package/dist/start-attempts.js.map +1 -0
  684. package/dist/status-cmd.d.ts +28 -0
  685. package/dist/status-cmd.d.ts.map +1 -0
  686. package/dist/status-cmd.js +116 -0
  687. package/dist/status-cmd.js.map +1 -0
  688. package/dist/stop-follow-up.d.ts +107 -0
  689. package/dist/stop-follow-up.d.ts.map +1 -0
  690. package/dist/stop-follow-up.js +172 -0
  691. package/dist/stop-follow-up.js.map +1 -0
  692. package/dist/surface-lease.d.ts +118 -0
  693. package/dist/surface-lease.d.ts.map +1 -0
  694. package/dist/surface-lease.js +485 -0
  695. package/dist/surface-lease.js.map +1 -0
  696. package/dist/sync.d.ts +54 -0
  697. package/dist/sync.d.ts.map +1 -0
  698. package/dist/sync.js +93 -0
  699. package/dist/sync.js.map +1 -0
  700. package/dist/syncing-ledger.d.ts +45 -0
  701. package/dist/syncing-ledger.d.ts.map +1 -0
  702. package/dist/syncing-ledger.js +53 -0
  703. package/dist/syncing-ledger.js.map +1 -0
  704. package/dist/temp-fixtures.d.ts +68 -0
  705. package/dist/temp-fixtures.d.ts.map +1 -0
  706. package/dist/temp-fixtures.js +38 -0
  707. package/dist/temp-fixtures.js.map +1 -0
  708. package/dist/token-window.d.ts +84 -0
  709. package/dist/token-window.d.ts.map +1 -0
  710. package/dist/token-window.js +143 -0
  711. package/dist/token-window.js.map +1 -0
  712. package/dist/tool-bridge.d.ts +177 -0
  713. package/dist/tool-bridge.d.ts.map +1 -0
  714. package/dist/tool-bridge.js +329 -0
  715. package/dist/tool-bridge.js.map +1 -0
  716. package/dist/tool-call-record.d.ts +197 -0
  717. package/dist/tool-call-record.d.ts.map +1 -0
  718. package/dist/tool-call-record.js +276 -0
  719. package/dist/tool-call-record.js.map +1 -0
  720. package/dist/tool-protocol.d.ts +135 -0
  721. package/dist/tool-protocol.d.ts.map +1 -0
  722. package/dist/tool-protocol.js +104 -0
  723. package/dist/tool-protocol.js.map +1 -0
  724. package/dist/tool-worker.d.ts +3 -0
  725. package/dist/tool-worker.d.ts.map +1 -0
  726. package/dist/tool-worker.js +478 -0
  727. package/dist/tool-worker.js.map +1 -0
  728. package/dist/toolchain-mirror.d.ts +86 -0
  729. package/dist/toolchain-mirror.d.ts.map +1 -0
  730. package/dist/toolchain-mirror.js +307 -0
  731. package/dist/toolchain-mirror.js.map +1 -0
  732. package/dist/trusted-git.d.ts +243 -0
  733. package/dist/trusted-git.d.ts.map +1 -0
  734. package/dist/trusted-git.js +920 -0
  735. package/dist/trusted-git.js.map +1 -0
  736. package/dist/ui.d.ts +76 -0
  737. package/dist/ui.d.ts.map +1 -0
  738. package/dist/ui.js +118 -0
  739. package/dist/ui.js.map +1 -0
  740. package/dist/untrusted-exec.d.ts +275 -0
  741. package/dist/untrusted-exec.d.ts.map +1 -0
  742. package/dist/untrusted-exec.js +479 -0
  743. package/dist/untrusted-exec.js.map +1 -0
  744. package/dist/untrusted-gate.d.ts +73 -0
  745. package/dist/untrusted-gate.d.ts.map +1 -0
  746. package/dist/untrusted-gate.js +226 -0
  747. package/dist/untrusted-gate.js.map +1 -0
  748. package/dist/uploader.d.ts +153 -0
  749. package/dist/uploader.d.ts.map +1 -0
  750. package/dist/uploader.js +204 -0
  751. package/dist/uploader.js.map +1 -0
  752. package/dist/verifier.d.ts +66 -0
  753. package/dist/verifier.d.ts.map +1 -0
  754. package/dist/verifier.js +170 -0
  755. package/dist/verifier.js.map +1 -0
  756. package/dist/verify-apply.d.ts +26 -0
  757. package/dist/verify-apply.d.ts.map +1 -0
  758. package/dist/verify-apply.js +36 -0
  759. package/dist/verify-apply.js.map +1 -0
  760. package/dist/verify-cmd.d.ts +44 -0
  761. package/dist/verify-cmd.d.ts.map +1 -0
  762. package/dist/verify-cmd.js +125 -0
  763. package/dist/verify-cmd.js.map +1 -0
  764. package/dist/verify-pass.d.ts +73 -0
  765. package/dist/verify-pass.d.ts.map +1 -0
  766. package/dist/verify-pass.js +103 -0
  767. package/dist/verify-pass.js.map +1 -0
  768. package/dist/welcome.d.ts +43 -0
  769. package/dist/welcome.d.ts.map +1 -0
  770. package/dist/welcome.js +116 -0
  771. package/dist/welcome.js.map +1 -0
  772. package/dist/workspace-provisioner.d.ts +65 -0
  773. package/dist/workspace-provisioner.d.ts.map +1 -0
  774. package/dist/workspace-provisioner.js +66 -0
  775. package/dist/workspace-provisioner.js.map +1 -0
  776. package/dist/workspace-quarantine.d.ts +64 -0
  777. package/dist/workspace-quarantine.d.ts.map +1 -0
  778. package/dist/workspace-quarantine.js +156 -0
  779. package/dist/workspace-quarantine.js.map +1 -0
  780. package/dist/workspace-residue-sweep.d.ts +113 -0
  781. package/dist/workspace-residue-sweep.d.ts.map +1 -0
  782. package/dist/workspace-residue-sweep.js +158 -0
  783. package/dist/workspace-residue-sweep.js.map +1 -0
  784. package/dist/workspace.d.ts +639 -0
  785. package/dist/workspace.d.ts.map +1 -0
  786. package/dist/workspace.js +2026 -0
  787. package/dist/workspace.js.map +1 -0
  788. package/package.json +52 -4
  789. package/win/CredProbe.cs +64 -0
  790. package/win/FakeClaude.cs +56 -0
  791. package/win/HandleProbe.cs +116 -0
  792. package/win/TokenProbe.cs +53 -0
  793. package/win/appcontainer.ps1 +500 -0
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CONTAINMENT_PREFLIGHT_STEP = void 0;
4
+ exports.makeUntrustedGateRunner = makeUntrustedGateRunner;
5
+ exports.makeContainmentPreflight = makeContainmentPreflight;
6
+ const toolchain_mirror_1 = require("./toolchain-mirror");
7
+ const node_path_1 = require("node:path");
8
+ const exec_domains_1 = require("./exec-domains");
9
+ const untrusted_exec_1 = require("./untrusted-exec");
10
+ const shared_grants_1 = require("./shared-grants");
11
+ /**
12
+ * A {@link CommandRunner} that runs each step contained.
13
+ *
14
+ * `projectDir` is both the worktree granted to the container and the cwd the
15
+ * step runs in, so a step can never be executed against a directory other than
16
+ * the one it was written for.
17
+ */
18
+ function makeUntrustedGateRunner(projectDir, deps = {}) {
19
+ const backend = deps.backend ?? new untrusted_exec_1.AppContainerBackend();
20
+ const now = deps.now ?? (() => Date.now());
21
+ const ensureToolchain = deps.toolchain ?? (() => (0, toolchain_mirror_1.ensureToolchainMirror)());
22
+ const shell = deps.shell ?? (0, node_path_1.join)((0, untrusted_exec_1.systemRoot)(), 'System32', 'cmd.exe');
23
+ return async (cmd, timeoutMs) => {
24
+ const started = now();
25
+ // The runtime the step will use, copied where the container can reach it.
26
+ // Without this there is no `node` inside the container at all, so a
27
+ // toolchain that cannot be mirrored is a step that cannot run — never a
28
+ // step that quietly runs on the host instead.
29
+ const tools = ensureToolchain();
30
+ if (!tools.ok) {
31
+ return {
32
+ ok: false,
33
+ // The step did not run. Not the project's fault, so not the item's bill.
34
+ unavailable: true,
35
+ timedOut: false,
36
+ ms: now() - started,
37
+ output: `this step did not run: no contained toolchain — ${tools.because}`,
38
+ };
39
+ }
40
+ /*
41
+ * The shared toolchain is granted under the shared-grant lock, before the
42
+ * launch and outside it — the critical section is one ACL write, never a
43
+ * gate step. An identity that already holds it does no work here at all.
44
+ */
45
+ const shared = await (0, shared_grants_1.ensureSharedAccess)(backend instanceof untrusted_exec_1.AppContainerBackend ? backend : null, (0, untrusted_exec_1.containerName)('gate', projectDir), (0, exec_domains_1.sharedGrantPaths)(tools.path));
46
+ if (!shared.ok) {
47
+ return {
48
+ ok: false,
49
+ // The step did not run, and not for the project's reasons.
50
+ unavailable: true,
51
+ timedOut: false,
52
+ ms: now() - started,
53
+ output: `this step did not run: the shared toolchain grant failed — ${shared.because}`,
54
+ };
55
+ }
56
+ const out = await backend.run({
57
+ kind: 'gate',
58
+ projectKey: projectDir,
59
+ executable: shell,
60
+ // The step is a shell line by contract, so it is handed to the shell as
61
+ // one argument rather than split — splitting it here would change what
62
+ // every existing project's gate means.
63
+ argv: ['/d', '/s', '/c', cmd],
64
+ // `cmd /s /c "<line>"` — one pair of quotes that cmd strips, leaving the
65
+ // line verbatim. Quoting each argument by C-runtime rules would escape
66
+ // the step's own quotes into something cmd cannot read.
67
+ rawCommandLine: `"${shell}" /d /s /c "${cmd}"`,
68
+ cwd: projectDir,
69
+ env: (0, exec_domains_1.buildUntrustedGateEnv)(projectDir, tools.path),
70
+ // Run-OWNED paths only. The shared toolchain was granted above, under the
71
+ // shared-grant lock, so it is not re-granted per launch — that per-launch
72
+ // grant is what accumulated one permanent ACE per identity.
73
+ grants: (0, exec_domains_1.untrustedGrants)('gate', projectDir),
74
+ protect: (0, exec_domains_1.protectedPaths)(projectDir),
75
+ // A test suite that needs the network is reaching outside the change it
76
+ // is meant to be checking.
77
+ network: 'none',
78
+ timeoutMs,
79
+ });
80
+ if (!out.ok) {
81
+ return {
82
+ ok: false,
83
+ // Same class as the missing toolchain above: containment could not be
84
+ // made, so nothing about the project was measured.
85
+ unavailable: true,
86
+ timedOut: false,
87
+ ms: now() - started,
88
+ output: `this step did not run: untrusted execution was unavailable ` +
89
+ `(${out.reason} at ${out.stage}) — ${out.because}`,
90
+ };
91
+ }
92
+ return {
93
+ ok: out.exitCode === 0 && !out.timedOut,
94
+ // The status itself, not only the verdict folded from it: a rejected
95
+ // candidate's evidence records "exited 2", never just "failed".
96
+ exitCode: out.exitCode,
97
+ timedOut: out.timedOut,
98
+ ms: now() - started,
99
+ // Interleaved the way the previous runner reported it, so existing
100
+ // diagnostics read the same.
101
+ output: `${out.stdout}${out.stderr}`,
102
+ };
103
+ };
104
+ }
105
+ /**
106
+ * The step a containment preflight runs.
107
+ *
108
+ * A `rem` is cmd.exe's comment: it starts, does nothing and exits 0. What is
109
+ * being measured is not the command — it is whether a container could be made
110
+ * to run one in at all.
111
+ */
112
+ exports.CONTAINMENT_PREFLIGHT_STEP = 'rem looply-containment-preflight';
113
+ /**
114
+ * ASK WHETHER A CONTAINER CAN ACTUALLY BE MADE, BEFORE PAYING FOR A MODEL TURN.
115
+ *
116
+ * `AppContainerBackend.probe()` answers a strictly earlier question. It returns
117
+ * as soon as a profile can be created or derived, and never reaches the grant,
118
+ * protect or launch stages — measured on one machine in one script: `probe`
119
+ * returned ok while a real `run` failed at `grant`, and again at `launch`.
120
+ * So a green probe does not mean a gate step can run.
121
+ *
122
+ * This runs the real thing through the real runner: same backend, same `gate`
123
+ * profile, same `unavailable` flag, same classification. There is no new
124
+ * vocabulary and no second code path to keep honest.
125
+ *
126
+ * ⚠️ THE GRANT SET IS DELIBERATELY SMALL, and this is not a shortcut. Granting
127
+ * the toolchain mirror propagates an inheritable ACE across 166 MB — measured at
128
+ * ~6.5 s against ~0.57 s for the project directory alone — and it proves nothing
129
+ * the small grant does not. Anyone "making the preflight faithful" by reusing
130
+ * `untrustedGrants` buys a 10x cost for no signal.
131
+ *
132
+ * ⚠️ IT COVERS THE `gate` PROFILE ONLY. The tool bridge uses `kind:'agent'`, a
133
+ * different profile from a different `CreateAppContainerProfile` call. A machine
134
+ * that can make neither is caught; one that can make the gate's and not the
135
+ * agent's is not. Closing that needs a second preflight through the bridge's own
136
+ * backend seam, and it is not this change.
137
+ */
138
+ function makeContainmentPreflight(projectDir, deps = {}) {
139
+ const backend = deps.backend ?? new untrusted_exec_1.AppContainerBackend();
140
+ const now = deps.now ?? (() => Date.now());
141
+ const ensureToolchain = deps.toolchain ?? (() => (0, toolchain_mirror_1.ensureToolchainMirror)());
142
+ const shell =
143
+ // ⚠️ DOUBLED. `'C:\Windows'` is the RELATIVE path `C:Windows` — `\W` is not
144
+ // an escape, so the backslash is dropped and `isAbsolute` is false. This
145
+ // repository has a suite named for that bug, and the first version of this
146
+ // line reintroduced it by copying the one above and losing the escape.
147
+ deps.shell ?? (0, node_path_1.join)((0, untrusted_exec_1.systemRoot)(), 'System32', 'cmd.exe');
148
+ return async () => {
149
+ const started = now();
150
+ // Asked first, exactly as the gate runner asks it: a machine with no
151
+ // mirrored runtime cannot run a step either, and must give the same answer.
152
+ const tools = ensureToolchain();
153
+ if (!tools.ok) {
154
+ return {
155
+ ok: false,
156
+ unavailable: true,
157
+ timedOut: false,
158
+ ms: now() - started,
159
+ output: `containment preflight: no contained toolchain — ${tools.because}`,
160
+ };
161
+ }
162
+ const out = await backend.run({
163
+ kind: 'gate',
164
+ projectKey: projectDir,
165
+ executable: shell,
166
+ argv: ['/d', '/s', '/c', exports.CONTAINMENT_PREFLIGHT_STEP],
167
+ rawCommandLine: `"${shell}" /d /s /c "${exports.CONTAINMENT_PREFLIGHT_STEP}"`,
168
+ cwd: projectDir,
169
+ env: (0, exec_domains_1.buildUntrustedGateEnv)(projectDir, tools.path),
170
+ /**
171
+ * THE PROJECT DIRECTORY AND THE PROTECT LIST ARE NOT OPTIONAL.
172
+ *
173
+ * The first version granted only the contained root and passed an empty
174
+ * protect list — a directory the daemon had `mkdirSync`'d microseconds
175
+ * earlier under its own `%TEMP%`, which it therefore always owns and can
176
+ * always ACL. So the grant failure this preflight exists to catch was one
177
+ * it could not reproduce, and the protect stage — which fails CLOSED on
178
+ * any path it cannot ACL, and which Phase 0 taught to include the resolved
179
+ * gitdir, `<super>/.git/modules/<name>` for a submodule — was invisible to
180
+ * it.
181
+ *
182
+ * ⚠️ THE TOOLCHAIN MIRROR STAYS OUT, and that is the documented gap
183
+ * rather than a claim of parity: its inheritable ACE propagates across
184
+ * 166 MB, ~6.5 s against ~0.57 s. So `doctor` and `run` CAN still disagree
185
+ * about a machine that fails only on the mirror.
186
+ */
187
+ grants: [
188
+ { path: projectDir, write: true },
189
+ { path: (0, exec_domains_1.containedRoot)('gate', projectDir), write: true },
190
+ ],
191
+ protect: (0, exec_domains_1.protectedPaths)(projectDir),
192
+ network: 'none',
193
+ timeoutMs: 30_000,
194
+ });
195
+ if (!out.ok) {
196
+ return {
197
+ ok: false,
198
+ unavailable: true,
199
+ timedOut: false,
200
+ ms: now() - started,
201
+ output: `containment preflight: a container could not be made ` +
202
+ `(${out.reason} at ${out.stage}) — ${out.because}`,
203
+ };
204
+ }
205
+ /**
206
+ * ⚠️ READ `exitCode` AND `timedOut`, exactly as the gate runner above does.
207
+ *
208
+ * The first version returned `{ok:true, timedOut:false}` unconditionally, so
209
+ * a container that launched and was then killed at the child ceiling was
210
+ * reported as a HEALTHY environment — and its timeout was not merely
211
+ * unreported but denied.
212
+ */
213
+ if (out.exitCode !== 0 || out.timedOut) {
214
+ return {
215
+ ok: false,
216
+ unavailable: true,
217
+ timedOut: out.timedOut,
218
+ ms: now() - started,
219
+ output: `containment preflight: a container was made but its process did not complete ` +
220
+ `(exit ${out.exitCode}${out.timedOut ? ', timed out' : ''})`,
221
+ };
222
+ }
223
+ return { ok: true, timedOut: false, ms: now() - started };
224
+ };
225
+ }
226
+ //# sourceMappingURL=untrusted-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"untrusted-gate.js","sourceRoot":"","sources":["../src/untrusted-gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,153 @@
1
+ import { type AnyEvent } from '@looply/core';
2
+ /**
3
+ * The event uploader — the machine half of DESIGN §12 case 23: server unreachable
4
+ * for an hour → events buffer locally, replay in order, no gaps.
5
+ *
6
+ * The ledger on disk is the truth; the server is a mirror that may lag. This
7
+ * class owns the lag: events are enqueued as the ledger appends them, and
8
+ * `flush()` ships them in `(runId, seq)` order. A transport failure is an
9
+ * *outcome*, never a throw — the run must keep working while the server is away,
10
+ * so the failed batch and everything after it stay buffered and the next flush
11
+ * resumes exactly where this one stopped.
12
+ *
13
+ * Resume is driven by the server's own acknowledgements: every ingest response
14
+ * carries `cursors`, the highest seq the server now holds per run. Anything at
15
+ * or below that head is dropped locally instead of re-sent. After a process
16
+ * restart the caller primes those cursors (or simply replays the ledger —
17
+ * ingest is idempotent on `(runId, seq)`, so overlap is duplicates, not damage).
18
+ *
19
+ * The buffer is capped (`DEFAULT_BUFFER_LIMIT`): case 23 says an hour offline,
20
+ * not a week, and memory is the one resource whose exhaustion ends the run the
21
+ * buffering was protecting.
22
+ */
23
+ /** Mirror of the server's `IngestResult` — the ack a successful POST returns. */
24
+ export interface IngestAck {
25
+ accepted: number;
26
+ duplicates: number;
27
+ rejected: number;
28
+ /** Highest seq the server now holds per run — the cursor this class trusts. */
29
+ cursors: Record<string, number>;
30
+ }
31
+ /** Injected transport: one POST to `/v1/projects/:id/events`. Throws on failure. */
32
+ export interface UploadTransport {
33
+ post(projectId: string, events: readonly AnyEvent[]): Promise<IngestAck>;
34
+ }
35
+ export interface FlushResult {
36
+ /** Events the server's ledger now holds — its own `accepted + duplicates`. */
37
+ delivered: number;
38
+ /**
39
+ * Events the server took but did not account for, cumulative.
40
+ *
41
+ * A 200 is not proof of storage. The server drops a malformed event, and
42
+ * silently drops one addressed to a different project than the URL — for a
43
+ * long time that was *every* event a run produced, and this class reported
44
+ * complete delivery of all of them. Anything a POST does not account for
45
+ * lands here so it can be said out loud instead of inferred from a phone that
46
+ * never moves.
47
+ */
48
+ unacked?: number;
49
+ /** Events dropped locally because the server's head already covers their seq. */
50
+ skipped: number;
51
+ /** Events still waiting after this flush — non-zero only on `error`. */
52
+ buffered: number;
53
+ /** Present when the transport failed; the unsent tail is retained, not lost. */
54
+ error?: string;
55
+ /** Present when the cap has thrown events away; cumulative, not per-flush. */
56
+ dropped?: number;
57
+ }
58
+ /**
59
+ * How many events may wait for a server that is not answering.
60
+ *
61
+ * A round emits on the order of tens of events, so this holds a long outage —
62
+ * many hours of running — before anything is thrown away. It exists because
63
+ * "buffer until the server returns" and "never end the run" cannot both be
64
+ * unconditional: an uploader with no ceiling turns a network outage into an
65
+ * out-of-memory kill, which loses the *whole* run rather than a prefix of its
66
+ * mirror. The ledger on disk is still complete either way.
67
+ */
68
+ export declare const DEFAULT_BUFFER_LIMIT = 5000;
69
+ export declare class EventUploader {
70
+ private readonly projectId;
71
+ private readonly transport;
72
+ /** Server rejects batches over 1000; stay comfortably under it. */
73
+ private readonly batchSize;
74
+ /** Ceiling on buffered events; the oldest go first once it is reached. */
75
+ private readonly capacity;
76
+ private buffer;
77
+ private readonly acked;
78
+ /**
79
+ * The greatest seq per run below which nothing is missing.
80
+ *
81
+ * Deliberately not `acked`. The server's ack reports the highest seq in the
82
+ * batch it just stored, which says nothing about the seqs *before* it — and
83
+ * those can be absent for reasons the server cannot see. The buffer sheds the
84
+ * oldest events when it overflows, so a long outage ships `[3, 4, 5]` and is
85
+ * told "you are up to 5" while 0, 1 and 2 were never sent at all. There is a
86
+ * green test asserting exactly that shape.
87
+ *
88
+ * Persisting `acked` would therefore write down a cursor covering events the
89
+ * server has never seen, and replay would skip them for ever. This head only
90
+ * advances one seq at a time, over a batch the server accounted for in full,
91
+ * and stops dead at the first gap.
92
+ */
93
+ private readonly durable;
94
+ private droppedCount;
95
+ private unackedCount;
96
+ constructor(projectId: string, transport: UploadTransport,
97
+ /** Server rejects batches over 1000; stay comfortably under it. */
98
+ batchSize?: number,
99
+ /** Ceiling on buffered events; the oldest go first once it is reached. */
100
+ capacity?: number);
101
+ /**
102
+ * Queue one event for the next flush. Cheap; call from the ledger append path.
103
+ *
104
+ * At capacity the *oldest* event goes, not the newest. The phone is watching
105
+ * for what is happening now — the round in flight, a question waiting on an
106
+ * answer — so the tail is what has to survive; and the head is the part a
107
+ * replay of the on-disk ledger can put back, since ingest is idempotent on
108
+ * `(runId, seq)`. Dropping is a reported loss, never a silent one.
109
+ */
110
+ enqueue(event: AnyEvent): void;
111
+ /** Events thrown away because the buffer was full, since this uploader started. */
112
+ dropped(): number;
113
+ /** Events a POST took but did not account for, since this uploader started. */
114
+ unacked(): number;
115
+ /**
116
+ * Seed the heads after a restart, so a replayed ledger skips what the server
117
+ * already holds.
118
+ *
119
+ * Both heads, from the same number: what came out of `cursor.json` is a
120
+ * durable gapless prefix, so it is simultaneously the last thing known held
121
+ * and a point with nothing missing behind it. Seeding only `acked` would let
122
+ * the next flush advance a durable head from -1 and re-send the whole run;
123
+ * seeding only `durable` would re-send everything the skip filter should drop.
124
+ */
125
+ prime(cursors: Record<string, number>): void;
126
+ /** Highest seq the server has acknowledged for a run, or -1 when unknown. */
127
+ ackedHead(runId: string): number;
128
+ /** Events waiting for the next flush. */
129
+ pending(): number;
130
+ /**
131
+ * Ship everything buffered, in `(runId, seq)` order, in batches.
132
+ *
133
+ * Order matters even though ingest dedupes: a batch that fails mid-flush must
134
+ * leave the server holding a *prefix* of each run, so the acknowledged head is
135
+ * always an honest resume point. Sending out of order would let a later seq
136
+ * land before an earlier one, and a crash in between would read as a gap.
137
+ */
138
+ flush(): Promise<FlushResult>;
139
+ private mergeCursor;
140
+ /**
141
+ * Walk a fully-accounted batch and extend each run's gapless head.
142
+ *
143
+ * One seq at a time, in order, stopping at the first number that is not the
144
+ * next one. A batch of `[3, 4, 5]` for a run whose head is -1 moves nothing:
145
+ * 0, 1 and 2 were never sent, and no ack can make it safe to skip them.
146
+ */
147
+ private advanceDurable;
148
+ /** Highest gapless seq the server is known to hold for a run, or -1. */
149
+ durableHead(runId: string): number;
150
+ /** What is safe to write to `cursor.json`. Never `acked` — see the field. */
151
+ durableCursors(): Record<string, number>;
152
+ }
153
+ //# sourceMappingURL=uploader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,OAAQ,CAAC;AAE1C,qBAAa,aAAa;IAuBtB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,0EAA0E;IAC1E,OAAO,CAAC,QAAQ,CAAC,QAAQ;IA3B3B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;IACrD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAK;gBAGN,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,eAAe;IAC3C,mEAAmE;IAClD,SAAS,SAAM;IAChC,0EAA0E;IACzD,QAAQ,SAAuB;IAGlD;;;;;;;;OAQG;IACH,OAAO,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAQ9B,mFAAmF;IACnF,OAAO,IAAI,MAAM;IAIjB,+EAA+E;IAC/E,OAAO,IAAI,MAAM;IAIjB;;;;;;;;;OASG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAO5C,6EAA6E;IAC7E,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIhC,yCAAyC;IACzC,OAAO,IAAI,MAAM;IAIjB;;;;;;;OAOG;IACG,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC;IAiEnC,OAAO,CAAC,WAAW;IAInB;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAStB,wEAAwE;IACxE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIlC,6EAA6E;IAC7E,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;CAGzC"}
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventUploader = exports.DEFAULT_BUFFER_LIMIT = void 0;
4
+ const core_1 = require("@looply/core");
5
+ /**
6
+ * How many events may wait for a server that is not answering.
7
+ *
8
+ * A round emits on the order of tens of events, so this holds a long outage —
9
+ * many hours of running — before anything is thrown away. It exists because
10
+ * "buffer until the server returns" and "never end the run" cannot both be
11
+ * unconditional: an uploader with no ceiling turns a network outage into an
12
+ * out-of-memory kill, which loses the *whole* run rather than a prefix of its
13
+ * mirror. The ledger on disk is still complete either way.
14
+ */
15
+ exports.DEFAULT_BUFFER_LIMIT = 5_000;
16
+ class EventUploader {
17
+ projectId;
18
+ transport;
19
+ batchSize;
20
+ capacity;
21
+ buffer = [];
22
+ acked = new Map();
23
+ /**
24
+ * The greatest seq per run below which nothing is missing.
25
+ *
26
+ * Deliberately not `acked`. The server's ack reports the highest seq in the
27
+ * batch it just stored, which says nothing about the seqs *before* it — and
28
+ * those can be absent for reasons the server cannot see. The buffer sheds the
29
+ * oldest events when it overflows, so a long outage ships `[3, 4, 5]` and is
30
+ * told "you are up to 5" while 0, 1 and 2 were never sent at all. There is a
31
+ * green test asserting exactly that shape.
32
+ *
33
+ * Persisting `acked` would therefore write down a cursor covering events the
34
+ * server has never seen, and replay would skip them for ever. This head only
35
+ * advances one seq at a time, over a batch the server accounted for in full,
36
+ * and stops dead at the first gap.
37
+ */
38
+ durable = new Map();
39
+ droppedCount = 0;
40
+ unackedCount = 0;
41
+ constructor(projectId, transport,
42
+ /** Server rejects batches over 1000; stay comfortably under it. */
43
+ batchSize = 500,
44
+ /** Ceiling on buffered events; the oldest go first once it is reached. */
45
+ capacity = exports.DEFAULT_BUFFER_LIMIT) {
46
+ this.projectId = projectId;
47
+ this.transport = transport;
48
+ this.batchSize = batchSize;
49
+ this.capacity = capacity;
50
+ }
51
+ /**
52
+ * Queue one event for the next flush. Cheap; call from the ledger append path.
53
+ *
54
+ * At capacity the *oldest* event goes, not the newest. The phone is watching
55
+ * for what is happening now — the round in flight, a question waiting on an
56
+ * answer — so the tail is what has to survive; and the head is the part a
57
+ * replay of the on-disk ledger can put back, since ingest is idempotent on
58
+ * `(runId, seq)`. Dropping is a reported loss, never a silent one.
59
+ */
60
+ enqueue(event) {
61
+ this.buffer.push(event);
62
+ while (this.buffer.length > this.capacity) {
63
+ this.buffer.shift();
64
+ this.droppedCount += 1;
65
+ }
66
+ }
67
+ /** Events thrown away because the buffer was full, since this uploader started. */
68
+ dropped() {
69
+ return this.droppedCount;
70
+ }
71
+ /** Events a POST took but did not account for, since this uploader started. */
72
+ unacked() {
73
+ return this.unackedCount;
74
+ }
75
+ /**
76
+ * Seed the heads after a restart, so a replayed ledger skips what the server
77
+ * already holds.
78
+ *
79
+ * Both heads, from the same number: what came out of `cursor.json` is a
80
+ * durable gapless prefix, so it is simultaneously the last thing known held
81
+ * and a point with nothing missing behind it. Seeding only `acked` would let
82
+ * the next flush advance a durable head from -1 and re-send the whole run;
83
+ * seeding only `durable` would re-send everything the skip filter should drop.
84
+ */
85
+ prime(cursors) {
86
+ for (const [runId, seq] of Object.entries(cursors)) {
87
+ this.mergeCursor(runId, seq);
88
+ if (seq > this.durableHead(runId))
89
+ this.durable.set(runId, seq);
90
+ }
91
+ }
92
+ /** Highest seq the server has acknowledged for a run, or -1 when unknown. */
93
+ ackedHead(runId) {
94
+ return this.acked.get(runId) ?? -1;
95
+ }
96
+ /** Events waiting for the next flush. */
97
+ pending() {
98
+ return this.buffer.length;
99
+ }
100
+ /**
101
+ * Ship everything buffered, in `(runId, seq)` order, in batches.
102
+ *
103
+ * Order matters even though ingest dedupes: a batch that fails mid-flush must
104
+ * leave the server holding a *prefix* of each run, so the acknowledged head is
105
+ * always an honest resume point. Sending out of order would let a later seq
106
+ * land before an earlier one, and a crash in between would read as a gap.
107
+ */
108
+ async flush() {
109
+ const ordered = (0, core_1.sortEvents)(this.buffer);
110
+ let skipped = 0;
111
+ const fresh = [];
112
+ for (const e of ordered) {
113
+ if (e.seq <= this.ackedHead(e.runId))
114
+ skipped += 1;
115
+ else
116
+ fresh.push(e);
117
+ }
118
+ // Two counters, deliberately. `sent` walks the batches and is the only
119
+ // thing the loop may advance on; `delivered` is how many of those the
120
+ // server accounted for. They were one variable, which was fine only while
121
+ // every batch counted as fully delivered — the moment a batch could be
122
+ // partially accounted for, a server that kept nothing stopped advancing the
123
+ // cursor and this loop re-sent the same batch forever.
124
+ let sent = 0;
125
+ let delivered = 0;
126
+ while (sent < fresh.length) {
127
+ const batch = fresh.slice(sent, sent + this.batchSize);
128
+ let ack;
129
+ try {
130
+ ack = await this.transport.post(this.projectId, batch);
131
+ }
132
+ catch (e) {
133
+ // Keep the unsent tail — including this batch — for the next flush.
134
+ // Losing it here is exactly the gap case 23 exists to prevent.
135
+ this.buffer = fresh.slice(sent);
136
+ return {
137
+ delivered,
138
+ skipped,
139
+ buffered: this.buffer.length,
140
+ error: e instanceof Error ? e.message : String(e),
141
+ ...(this.droppedCount > 0 ? { dropped: this.droppedCount } : {}),
142
+ ...(this.unackedCount > 0 ? { unacked: this.unackedCount } : {}),
143
+ };
144
+ }
145
+ for (const [runId, seq] of Object.entries(ack.cursors))
146
+ this.mergeCursor(runId, seq);
147
+ // `accepted + duplicates` is exactly "events the server's ledger now
148
+ // holds": one it stored this time, one it already had. Everything else —
149
+ // malformed, addressed elsewhere, or dropped for a reason the ack does
150
+ // not name — is a loss, and counting it as delivered is how a run could
151
+ // upload its entire life to a server that kept none of it and still
152
+ // report success. `rejected` deliberately does NOT count as delivered:
153
+ // the server telling us it threw something away is not storage.
154
+ const accounted = Math.min(ack.accepted + ack.duplicates, batch.length);
155
+ this.unackedCount += batch.length - accounted;
156
+ delivered += accounted;
157
+ sent += batch.length;
158
+ // Only a batch the server accounted for in full says anything about which
159
+ // individual events landed. A partial one names a count, not a set, so
160
+ // there is no seq it makes safe to skip.
161
+ if (accounted === batch.length)
162
+ this.advanceDurable(batch);
163
+ }
164
+ this.buffer = [];
165
+ return {
166
+ delivered,
167
+ skipped,
168
+ buffered: 0,
169
+ ...(this.droppedCount > 0 ? { dropped: this.droppedCount } : {}),
170
+ ...(this.unackedCount > 0 ? { unacked: this.unackedCount } : {}),
171
+ };
172
+ }
173
+ mergeCursor(runId, seq) {
174
+ if (seq > this.ackedHead(runId))
175
+ this.acked.set(runId, seq);
176
+ }
177
+ /**
178
+ * Walk a fully-accounted batch and extend each run's gapless head.
179
+ *
180
+ * One seq at a time, in order, stopping at the first number that is not the
181
+ * next one. A batch of `[3, 4, 5]` for a run whose head is -1 moves nothing:
182
+ * 0, 1 and 2 were never sent, and no ack can make it safe to skip them.
183
+ */
184
+ advanceDurable(batch) {
185
+ for (const e of batch) {
186
+ const head = this.durableHead(e.runId);
187
+ if (e.seq <= head)
188
+ continue;
189
+ if (e.seq !== head + 1)
190
+ continue;
191
+ this.durable.set(e.runId, e.seq);
192
+ }
193
+ }
194
+ /** Highest gapless seq the server is known to hold for a run, or -1. */
195
+ durableHead(runId) {
196
+ return this.durable.get(runId) ?? -1;
197
+ }
198
+ /** What is safe to write to `cursor.json`. Never `acked` — see the field. */
199
+ durableCursors() {
200
+ return Object.fromEntries(this.durable);
201
+ }
202
+ }
203
+ exports.EventUploader = EventUploader;
204
+ //# sourceMappingURL=uploader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploader.js","sourceRoot":"","sources":["../src/uploader.ts"],"names":[],"mappings":"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"}