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,105 @@
1
+ import { type ApplyIntent, type ApplyRecord, type ApplyRecordPhase, type Observed, type RemovalDecision, type RetentionPolicy, type Tombstone } from '@looply/core';
2
+ /**
3
+ * THE FILESYSTEM HALF OF APPLYING A RETENTION PLAN.
4
+ *
5
+ * ─────────────────────────────────────────────────────────────────────────────
6
+ * `retention-apply.ts` in core decides; this observes, serialises, journals and
7
+ * removes. The split is the same one `candidate-replay` uses and for the same
8
+ * reason: every refusal in the decision can be tested without a real file, and
9
+ * every mechanic here can be tested against real ones without re-deciding
10
+ * anything.
11
+ *
12
+ * 🔴 NOTHING HERE DECIDES. This file must never contain a reason to remove
13
+ * something. It reads what is there, hands it to the fold, and does what the
14
+ * fold says. A condition written here would be one nothing in core's suite can
15
+ * see, which is how the second copy of a rule ends up disagreeing with the first.
16
+ */
17
+ /** What the filesystem cannot tell us: provenance, pins and references. */
18
+ export interface ArtifactFacts {
19
+ readonly owned?: boolean;
20
+ readonly pinned?: boolean;
21
+ readonly referenced?: boolean;
22
+ readonly class?: Observed['class'];
23
+ }
24
+ export interface ApplyRuntimeDeps {
25
+ readonly nowMs: () => number;
26
+ readonly policy: RetentionPolicy;
27
+ readonly maxPlanAgeMs?: number;
28
+ /** Ownership, pins and references for one artifact. Absent fields refuse. */
29
+ readonly facts: (id: string) => ArtifactFacts;
30
+ /** Append-only, two records per deletion. Created if absent. */
31
+ readonly journalPath: string;
32
+ /** Exclusive while an apply runs. See `withLock`. */
33
+ readonly lockPath: string;
34
+ readonly log?: (line: string) => void;
35
+ }
36
+ export interface ApplyOutcome {
37
+ readonly decisions: readonly RemovalDecision[];
38
+ readonly removed: readonly Tombstone[];
39
+ readonly refused: readonly {
40
+ id: string;
41
+ because: string;
42
+ }[];
43
+ readonly alreadyGone: readonly string[];
44
+ /** Entries a previous interrupted run left in flight, re-observed this time. */
45
+ readonly resumed: readonly string[];
46
+ /**
47
+ * Entries this intent had already finished, carried over rather than redone.
48
+ *
49
+ * 🔴 REPORTED, NOT SWALLOWED. A second run of the same plan decides nothing
50
+ * and removes nothing — which is the point — but a caller told only "removed
51
+ * 0, refused 0" would read a standing refusal as a clean result. The decision
52
+ * still stands; it was simply made earlier.
53
+ */
54
+ readonly settled: readonly {
55
+ id: string;
56
+ phase: ApplyRecordPhase;
57
+ }[];
58
+ }
59
+ /**
60
+ * What is actually at `path`, read without following anything.
61
+ *
62
+ * ⚠️ `lstat`, NEVER `stat`. `stat` follows a link and reports the TARGET, so a
63
+ * junction would be measured, aged and classified as whatever it points at —
64
+ * and then deleted as if it were that. `lstat` reports the link itself, which
65
+ * is the thing this is deciding about.
66
+ *
67
+ * Every failure produces a refusable observation rather than a throw: an
68
+ * unreadable artifact must reach the fold as unreadable, because the fold is
69
+ * where "unreadable is not permission" is written down.
70
+ */
71
+ export declare function observe(id: string, path: string, facts: ArtifactFacts): Observed;
72
+ export declare class LockHeld extends Error {
73
+ readonly by: string;
74
+ constructor(by: string);
75
+ }
76
+ /**
77
+ * Exclusive for the duration, or it does not run.
78
+ *
79
+ * `wx` is create-if-absent, and it is the whole mechanism: two processes racing
80
+ * it cannot both win, because the filesystem arbitrates. The holder writes who
81
+ * it is so the refusal can say so rather than "locked".
82
+ *
83
+ * ⚠️ A HELD LOCK IS A REFUSAL, NOT A WAIT. The charter requires serialising
84
+ * against writers and retention consumers; a timeout that gave up and proceeded
85
+ * would be exactly the thing it is serialising against.
86
+ */
87
+ export declare function withLock<T>(lockPath: string, holder: string, body: () => T): T;
88
+ export declare function readJournal(path: string): ApplyRecord[];
89
+ /**
90
+ * Carry out an intent: observe, decide, journal, remove.
91
+ *
92
+ * The order per deletion is fixed and is the crash-survivable one:
93
+ *
94
+ * 1. observe what is there now
95
+ * 2. ask the fold
96
+ * 3. write `intended` BEFORE touching anything
97
+ * 4. remove
98
+ * 5. write `removed` with the tombstone
99
+ *
100
+ * A crash between 3 and 5 leaves an `intended` with no outcome, which is
101
+ * exactly the state `resumeApply` re-observes. It cannot be mistaken for a
102
+ * completed removal, and it cannot be mistaken for one that never started.
103
+ */
104
+ export declare function applyRetention(intent: ApplyIntent, deps: ApplyRuntimeDeps): ApplyOutcome;
105
+ //# sourceMappingURL=retention-apply-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention-apply-runtime.d.ts","sourceRoot":"","sources":["../src/retention-apply-runtime.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB;;;;;;;;;;;;;;GAcG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,aAAa,CAAC;IAC9C,gEAAgE;IAChE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7D,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC;;;;;;;OAOG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,gBAAgB,CAAA;KAAE,EAAE,CAAC;CACtE;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,QAAQ,CAmChF;AAgDD,qBAAa,QAAS,SAAQ,KAAK;aACL,EAAE,EAAE,MAAM;gBAAV,EAAE,EAAE,MAAM;CAGvC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CA4B9E;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAevD;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB,GAAG,YAAY,CA8ExF"}
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LockHeld = void 0;
4
+ exports.observe = observe;
5
+ exports.withLock = withLock;
6
+ exports.readJournal = readJournal;
7
+ exports.applyRetention = applyRetention;
8
+ const node_fs_1 = require("node:fs");
9
+ const node_path_1 = require("node:path");
10
+ const core_1 = require("@looply/core");
11
+ /* ──────────────────────────────────────────────────────────── observing ── */
12
+ /**
13
+ * What is actually at `path`, read without following anything.
14
+ *
15
+ * ⚠️ `lstat`, NEVER `stat`. `stat` follows a link and reports the TARGET, so a
16
+ * junction would be measured, aged and classified as whatever it points at —
17
+ * and then deleted as if it were that. `lstat` reports the link itself, which
18
+ * is the thing this is deciding about.
19
+ *
20
+ * Every failure produces a refusable observation rather than a throw: an
21
+ * unreadable artifact must reach the fold as unreadable, because the fold is
22
+ * where "unreadable is not permission" is written down.
23
+ */
24
+ function observe(id, path, facts) {
25
+ const base = { id, ...facts };
26
+ let st;
27
+ try {
28
+ st = (0, node_fs_1.lstatSync)(path);
29
+ }
30
+ catch (e) {
31
+ const code = e.code;
32
+ if (code === 'ENOENT') {
33
+ return { ...base, present: false, bytes: null, createdAtMs: null, realPath: null, isLink: false, containsLink: false };
34
+ }
35
+ // There but unreadable — the fold refuses this, and must be given the
36
+ // chance to. Reporting it absent would be a removal decided by an error.
37
+ return { ...base, present: true, bytes: null, createdAtMs: null, realPath: null, isLink: false };
38
+ }
39
+ const isLink = st.isSymbolicLink();
40
+ let realPath = null;
41
+ try {
42
+ realPath = node_fs_1.realpathSync.native(path);
43
+ }
44
+ catch {
45
+ /* null refuses */
46
+ }
47
+ const walked = walk(path, st.isDirectory());
48
+ return {
49
+ ...base,
50
+ present: true,
51
+ bytes: walked.bytes,
52
+ createdAtMs: walked.createdAtMs,
53
+ realPath,
54
+ isLink,
55
+ ...(walked.containsLink === undefined ? {} : { containsLink: walked.containsLink }),
56
+ };
57
+ }
58
+ /**
59
+ * Size, age and whether anything inside is a link.
60
+ *
61
+ * 🔴 THE LINK SEARCH IS THE POINT, not a side effect of measuring. A recursive
62
+ * delete walks a junction out of the tree, so an artifact directory holding one
63
+ * is an artifact that can delete somebody else's files. The walk uses `lstat`
64
+ * at every level and never descends THROUGH a link — it records it and stops.
65
+ *
66
+ * Any error at any level leaves `bytes`/`createdAtMs` null and `containsLink`
67
+ * undefined, all three of which the fold refuses. A partial walk is not a
68
+ * measurement.
69
+ */
70
+ function walk(path, isDir) {
71
+ let bytes = 0;
72
+ let createdAtMs = null;
73
+ let containsLink = false;
74
+ const stack = [path];
75
+ let first = true;
76
+ try {
77
+ while (stack.length > 0) {
78
+ const at = stack.pop();
79
+ const st = (0, node_fs_1.lstatSync)(at);
80
+ if (st.isSymbolicLink()) {
81
+ // The top-level link is reported by `observe` through `isLink`; a nested
82
+ // one is what this flag exists for. Either way: do not descend.
83
+ if (!first)
84
+ containsLink = true;
85
+ first = false;
86
+ continue;
87
+ }
88
+ first = false;
89
+ createdAtMs = createdAtMs === null ? st.mtimeMs : Math.min(createdAtMs, st.mtimeMs);
90
+ if (st.isDirectory()) {
91
+ for (const child of (0, node_fs_1.readdirSync)(at))
92
+ stack.push((0, node_path_1.join)(at, child));
93
+ }
94
+ else {
95
+ bytes += st.size;
96
+ }
97
+ }
98
+ }
99
+ catch {
100
+ return { bytes: null, createdAtMs: null, containsLink: undefined };
101
+ }
102
+ if (!isDir && createdAtMs === null)
103
+ return { bytes: null, createdAtMs: null, containsLink: undefined };
104
+ return { bytes, createdAtMs, containsLink };
105
+ }
106
+ /* ─────────────────────────────────────────────────────────── the lock ── */
107
+ class LockHeld extends Error {
108
+ by;
109
+ constructor(by) {
110
+ super(`another apply or retention consumer holds the lock: ${by}`);
111
+ this.by = by;
112
+ }
113
+ }
114
+ exports.LockHeld = LockHeld;
115
+ /**
116
+ * Exclusive for the duration, or it does not run.
117
+ *
118
+ * `wx` is create-if-absent, and it is the whole mechanism: two processes racing
119
+ * it cannot both win, because the filesystem arbitrates. The holder writes who
120
+ * it is so the refusal can say so rather than "locked".
121
+ *
122
+ * ⚠️ A HELD LOCK IS A REFUSAL, NOT A WAIT. The charter requires serialising
123
+ * against writers and retention consumers; a timeout that gave up and proceeded
124
+ * would be exactly the thing it is serialising against.
125
+ */
126
+ function withLock(lockPath, holder, body) {
127
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(lockPath), { recursive: true });
128
+ let fd;
129
+ try {
130
+ fd = (0, node_fs_1.openSync)(lockPath, 'wx');
131
+ }
132
+ catch (e) {
133
+ if (e.code === 'EEXIST') {
134
+ let by = 'unknown';
135
+ try {
136
+ by = (0, node_fs_1.readFileSync)(lockPath, 'utf8').trim() || 'unknown';
137
+ }
138
+ catch {
139
+ /* the message degrades; the refusal does not */
140
+ }
141
+ throw new LockHeld(by);
142
+ }
143
+ throw e;
144
+ }
145
+ try {
146
+ (0, node_fs_1.writeSync)(fd, holder);
147
+ (0, node_fs_1.closeSync)(fd);
148
+ return body();
149
+ }
150
+ finally {
151
+ try {
152
+ (0, node_fs_1.unlinkSync)(lockPath);
153
+ }
154
+ catch {
155
+ /* a lock that cannot be released is reported by the next run, not hidden here */
156
+ }
157
+ }
158
+ }
159
+ /* ──────────────────────────────────────────────────────────── journal ── */
160
+ function readJournal(path) {
161
+ if (!(0, node_fs_1.existsSync)(path))
162
+ return [];
163
+ const out = [];
164
+ for (const line of (0, node_fs_1.readFileSync)(path, 'utf8').split('\n')) {
165
+ if (line.trim() === '')
166
+ continue;
167
+ try {
168
+ out.push(JSON.parse(line));
169
+ }
170
+ catch {
171
+ // A torn last line is what a crash mid-append looks like. Skipping it is
172
+ // correct: an unparseable record asserts nothing, and `resumeApply` reads
173
+ // an absent record as "never started", which re-decides rather than
174
+ // assumes.
175
+ }
176
+ }
177
+ return out;
178
+ }
179
+ function append(path, record) {
180
+ (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(path), { recursive: true });
181
+ (0, node_fs_1.appendFileSync)(path, JSON.stringify(record) + '\n', 'utf8');
182
+ }
183
+ /* ───────────────────────────────────────────────────────────── applying ── */
184
+ /**
185
+ * Carry out an intent: observe, decide, journal, remove.
186
+ *
187
+ * The order per deletion is fixed and is the crash-survivable one:
188
+ *
189
+ * 1. observe what is there now
190
+ * 2. ask the fold
191
+ * 3. write `intended` BEFORE touching anything
192
+ * 4. remove
193
+ * 5. write `removed` with the tombstone
194
+ *
195
+ * A crash between 3 and 5 leaves an `intended` with no outcome, which is
196
+ * exactly the state `resumeApply` re-observes. It cannot be mistaken for a
197
+ * completed removal, and it cannot be mistaken for one that never started.
198
+ */
199
+ function applyRetention(intent, deps) {
200
+ const root = (0, node_path_1.resolve)(intent.root);
201
+ const log = deps.log ?? (() => { });
202
+ return withLock(deps.lockPath, `${process.pid} applying ${intent.intentId}`, () => {
203
+ const actions = (0, core_1.resumeApply)(intent, readJournal(deps.journalPath));
204
+ const byId = new Map(intent.deletions.map((d) => [d.id, d]));
205
+ const decisions = [];
206
+ const removed = [];
207
+ const refused = [];
208
+ const alreadyGone = [];
209
+ const resumed = [];
210
+ const settled = [];
211
+ for (const action of actions) {
212
+ const planned = byId.get(action.id);
213
+ if (planned === undefined)
214
+ continue;
215
+ if (action.kind === 'settled') {
216
+ settled.push({ id: action.id, phase: action.phase });
217
+ log(`${action.id}: already ${action.phase}`);
218
+ continue;
219
+ }
220
+ if (action.kind === 're-observe') {
221
+ resumed.push(action.id);
222
+ log(`${action.id}: ${action.because} — looking again`);
223
+ }
224
+ const observed = observe(action.id, planned.path, deps.facts(action.id));
225
+ const verdict = (0, core_1.decideRemoval)(planned, observed, { ...intent, root }, {
226
+ nowMs: deps.nowMs(),
227
+ policy: deps.policy,
228
+ ...(deps.maxPlanAgeMs === undefined ? {} : { maxPlanAgeMs: deps.maxPlanAgeMs }),
229
+ });
230
+ decisions.push({ id: action.id, path: planned.path, verdict });
231
+ if (verdict.kind === 'refuse') {
232
+ append(deps.journalPath, { intentId: intent.intentId, id: action.id, phase: 'refused', atMs: deps.nowMs(), because: verdict.because });
233
+ refused.push({ id: action.id, because: verdict.because });
234
+ log(`${action.id}: refused — ${verdict.because}`);
235
+ continue;
236
+ }
237
+ if (verdict.kind === 'already-gone') {
238
+ const stone = (0, core_1.tombstoneFor)(planned, verdict.because, deps.nowMs());
239
+ append(deps.journalPath, { intentId: intent.intentId, id: action.id, phase: 'removed', atMs: deps.nowMs(), tombstone: stone, because: verdict.because });
240
+ alreadyGone.push(action.id);
241
+ log(`${action.id}: already gone`);
242
+ continue;
243
+ }
244
+ // 🔴 THE INTENT IS ON DISK BEFORE THE REMOVAL, NOT AFTER.
245
+ append(deps.journalPath, { intentId: intent.intentId, id: action.id, phase: 'intended', atMs: deps.nowMs(), because: verdict.because });
246
+ /**
247
+ * ⚠️ ONE LAST BOUNDARY CHECK, IMMEDIATELY BEFORE THE CALL THAT DELETES.
248
+ * The fold checked it, and this checks it again against the resolved path
249
+ * it is about to hand to `rmSync`. It is the cheapest possible guard on
250
+ * the only line in this package that can destroy something, and the cost
251
+ * of the duplication is one comparison.
252
+ */
253
+ const target = observed.realPath ?? planned.path;
254
+ if (!(0, core_1.insideRoot)(root, target)) {
255
+ const because = `refusing at the last step: ${target} is outside ${root}`;
256
+ append(deps.journalPath, { intentId: intent.intentId, id: action.id, phase: 'refused', atMs: deps.nowMs(), because });
257
+ refused.push({ id: action.id, because });
258
+ continue;
259
+ }
260
+ (0, node_fs_1.rmSync)(planned.path, { recursive: true, force: false });
261
+ const stone = (0, core_1.tombstoneFor)(planned, verdict.because, deps.nowMs());
262
+ append(deps.journalPath, { intentId: intent.intentId, id: action.id, phase: 'removed', atMs: deps.nowMs(), tombstone: stone, because: verdict.because });
263
+ removed.push(stone);
264
+ log(`${action.id}: removed — ${verdict.because}`);
265
+ }
266
+ return { decisions, removed, refused, alreadyGone, resumed, settled };
267
+ });
268
+ }
269
+ //# sourceMappingURL=retention-apply-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retention-apply-runtime.js","sourceRoot":"","sources":["../src/retention-apply-runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ import type { Evidence } from '@looply/core';
2
+ import type { EvidenceLookup } from './evidence-cache';
3
+ /**
4
+ * Re-verification triggers (DESIGN §7, §12 case 19).
5
+ *
6
+ * Cached evidence is a claim about one tree. DESIGN names exactly two things
7
+ * that age it: HEAD moving past more than N commits that touch the paths the
8
+ * evidence points at, and a discard. This module owns the first trigger as a
9
+ * pure decision over the cache's lookup result; the discard trigger lives in
10
+ * the round runner, which invalidates the cache entry so the next lookup here
11
+ * is a `miss`. Both funnel into the same answer: hand the implementer the
12
+ * cached file:line, or send the item back through verify first.
13
+ *
14
+ * The decision takes counting as an injected function (the real backend is
15
+ * `GitDriver.countCommitsTouching`), so every branch is testable without a
16
+ * repository.
17
+ */
18
+ /**
19
+ * How many commits touching the evidence paths HEAD may move past before the
20
+ * evidence must be re-checked. DESIGN fixes the trigger but is silent on N; a
21
+ * constant rather than config, same reasoning as the zero-rejection alert
22
+ * threshold — a tunable staleness bound is how stale evidence gets tolerated.
23
+ * §12 case 19's forty-commit example must fire, so N stays well under 40 (the
24
+ * spec asserts this).
25
+ */
26
+ export declare const REVERIFY_AFTER_COMMITS = 20;
27
+ /** Count of commits in `fromSha..toSha` that touch any of `paths`. */
28
+ export type CountCommitsTouching = (fromSha: string, toSha: string, paths: readonly string[]) => Promise<number>;
29
+ export type ReverifyDecision =
30
+ /** The cached evidence is still trustworthy — put it in the implementation prompt. */
31
+ {
32
+ kind: 'reuse';
33
+ evidence: Evidence[];
34
+ }
35
+ /** The item must go back through verify before it is picked. */
36
+ | {
37
+ kind: 'reverify';
38
+ reason: string;
39
+ };
40
+ export declare function decideReverify(lookup: EvidenceLookup, head: string, countCommitsTouching: CountCommitsTouching, threshold?: number): Promise<ReverifyDecision>;
41
+ //# sourceMappingURL=reverify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverify.d.ts","sourceRoot":"","sources":["../src/reverify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,sEAAsE;AACtE,MAAM,MAAM,oBAAoB,GAAG,CACjC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,SAAS,MAAM,EAAE,KACrB,OAAO,CAAC,MAAM,CAAC,CAAC;AAErB,MAAM,MAAM,gBAAgB;AAC1B,sFAAsF;AACpF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;CAAE;AACzC,gEAAgE;GAC9D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,wBAAsB,cAAc,CAClC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,EACZ,oBAAoB,EAAE,oBAAoB,EAC1C,SAAS,GAAE,MAA+B,GACzC,OAAO,CAAC,gBAAgB,CAAC,CAyC3B"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REVERIFY_AFTER_COMMITS = void 0;
4
+ exports.decideReverify = decideReverify;
5
+ /**
6
+ * Re-verification triggers (DESIGN §7, §12 case 19).
7
+ *
8
+ * Cached evidence is a claim about one tree. DESIGN names exactly two things
9
+ * that age it: HEAD moving past more than N commits that touch the paths the
10
+ * evidence points at, and a discard. This module owns the first trigger as a
11
+ * pure decision over the cache's lookup result; the discard trigger lives in
12
+ * the round runner, which invalidates the cache entry so the next lookup here
13
+ * is a `miss`. Both funnel into the same answer: hand the implementer the
14
+ * cached file:line, or send the item back through verify first.
15
+ *
16
+ * The decision takes counting as an injected function (the real backend is
17
+ * `GitDriver.countCommitsTouching`), so every branch is testable without a
18
+ * repository.
19
+ */
20
+ /**
21
+ * How many commits touching the evidence paths HEAD may move past before the
22
+ * evidence must be re-checked. DESIGN fixes the trigger but is silent on N; a
23
+ * constant rather than config, same reasoning as the zero-rejection alert
24
+ * threshold — a tunable staleness bound is how stale evidence gets tolerated.
25
+ * §12 case 19's forty-commit example must fire, so N stays well under 40 (the
26
+ * spec asserts this).
27
+ */
28
+ exports.REVERIFY_AFTER_COMMITS = 20;
29
+ async function decideReverify(lookup, head, countCommitsTouching, threshold = exports.REVERIFY_AFTER_COMMITS) {
30
+ if (lookup.kind === 'hit') {
31
+ // Recorded at exactly this HEAD — nothing can have touched anything since.
32
+ return { kind: 'reuse', evidence: lookup.evidence };
33
+ }
34
+ if (lookup.kind === 'miss') {
35
+ return {
36
+ kind: 'reverify',
37
+ reason: 'no cached evidence — the item has not been verified (or a discard invalidated it)',
38
+ };
39
+ }
40
+ const paths = [...new Set(lookup.evidence.map((e) => e.path))];
41
+ if (paths.length === 0) {
42
+ // No paths means no commit can touch them, so the moved-HEAD trigger cannot
43
+ // fire by definition — an evidence-free confirmation ages only through the
44
+ // discard trigger. (This also keeps an empty pathspec away from rev-list,
45
+ // where it would count every commit — the opposite of the question.)
46
+ return { kind: 'reuse', evidence: lookup.evidence };
47
+ }
48
+ let touched;
49
+ try {
50
+ touched = await countCommitsTouching(lookup.cachedHead, head, paths);
51
+ }
52
+ catch (e) {
53
+ // The cached HEAD may no longer resolve — rebased away, gc'd, or a
54
+ // different clone. Freshness cannot be established, so fail toward
55
+ // re-checking, never toward handing over line numbers of unknown age.
56
+ return {
57
+ kind: 'reverify',
58
+ reason: `cannot count commits since ${lookup.cachedHead}: ${e.message}`,
59
+ };
60
+ }
61
+ if (touched > threshold) {
62
+ return {
63
+ kind: 'reverify',
64
+ reason: `${touched} commits since ${lookup.cachedHead} touched the evidence paths (threshold ${threshold})`,
65
+ };
66
+ }
67
+ return { kind: 'reuse', evidence: lookup.evidence };
68
+ }
69
+ //# sourceMappingURL=reverify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reverify.js","sourceRoot":"","sources":["../src/reverify.ts"],"names":[],"mappings":";;;AA0CA,wCA8CC;AArFD;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;GAOG;AACU,QAAA,sBAAsB,GAAG,EAAE,CAAC;AAelC,KAAK,UAAU,cAAc,CAClC,MAAsB,EACtB,IAAY,EACZ,oBAA0C,EAC1C,YAAoB,8BAAsB;IAE1C,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC1B,2EAA2E;QAC3E,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,mFAAmF;SAC5F,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,4EAA4E;QAC5E,2EAA2E;QAC3E,0EAA0E;QAC1E,qEAAqE;QACrE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,oBAAoB,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACvE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,mEAAmE;QACnE,mEAAmE;QACnE,sEAAsE;QACtE,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,8BAA8B,MAAM,CAAC,UAAU,KAAM,CAAW,CAAC,OAAO,EAAE;SACnF,CAAC;IACJ,CAAC;IAED,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;QACxB,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,MAAM,EAAE,GAAG,OAAO,kBAAkB,MAAM,CAAC,UAAU,0CAA0C,SAAS,GAAG;SAC5G,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;AACtD,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { type GateStepResult, type GateVerdict, type RoundOutcome } from '@looply/core';
2
+ import type { LedgerFs } from './ledger-store';
3
+ /**
4
+ * WHAT A ROUND ACTUALLY DID, read back out of the ledger.
5
+ *
6
+ * The ledger has always been write-only from this side: `LedgerStore` appends
7
+ * and projects a status, and nothing asked it what happened in a particular
8
+ * round. Phase 6C needs to, because the only honest machine-held answer to
9
+ * "was this goal delivered" is the round record itself — which item, which
10
+ * outcome, which commit, and which gate steps passed.
11
+ *
12
+ * READ-ONLY, and deliberately not a method on `LedgerStore`. That class is the
13
+ * only writer of `events.jsonl` in the repository and its own comment says so;
14
+ * adding a reader to it invites a future reader that also writes. This takes a
15
+ * filesystem and a path and returns data.
16
+ *
17
+ * Damage-tolerant for the same reason every other reader here is: a process
18
+ * killed mid-append leaves a partial final line, and discarding a whole history
19
+ * because its last line is short would be absurd.
20
+ *
21
+ * SAFE TO READ WHILE A RUN IS APPENDING. `events.jsonl` is append-only with a
22
+ * single writer, and rotation or compaction would already have broken
23
+ * `makeLedgerReplay`'s byte-count guard — so a read sees a prefix of the truth,
24
+ * never a rewritten one. A prefix can only make this answer "not yet", which is
25
+ * the safe direction.
26
+ */
27
+ /** One round, joined from the two events that describe it. */
28
+ export interface RoundRecord {
29
+ runId: string;
30
+ round: number;
31
+ itemId: string;
32
+ outcome: RoundOutcome;
33
+ /** The commit, when the round committed. Absent on a discarded or abandoned round. */
34
+ sha?: string;
35
+ /**
36
+ * The gate that permitted it, when one was recorded.
37
+ *
38
+ * Absent is NOT a pass. A round whose gate never reached the ledger proves
39
+ * nothing about what ran, and the caller treats it as unproven.
40
+ */
41
+ gate?: {
42
+ verdict: GateVerdict;
43
+ steps: GateStepResult[];
44
+ };
45
+ }
46
+ export type RoundRecordsOutcome = {
47
+ ok: true;
48
+ rounds: RoundRecord[];
49
+ }
50
+ /**
51
+ * The ledger could not be read. NOT the same as "it holds no rounds".
52
+ *
53
+ * Both once returned an empty list, on the reasoning that either way nothing
54
+ * could be proven. That was true while a failed proof was retryable; it stopped
55
+ * being true when a KEY 2 refusal became TERMINAL, because a file that was
56
+ * momentarily busy would then be laundered into "no round delivered any of
57
+ * this plan" — a sentence about the work, told to a person, on the strength
58
+ * of a read that never happened.
59
+ */
60
+ | {
61
+ ok: false;
62
+ because: string;
63
+ };
64
+ export declare function readRoundRecords(stateDir: string, fs: Pick<LedgerFs, 'readFile'>): Promise<RoundRecordsOutcome>;
65
+ //# sourceMappingURL=round-records.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-records.d.ts","sourceRoot":"","sources":["../src/round-records.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AACpG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,8DAA8D;AAC9D,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;IACtB,sFAAsF;IACtF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,IAAI,CAAC,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,cAAc,EAAE,CAAA;KAAE,CAAC;CAC1D;AAYD,MAAM,MAAM,mBAAmB,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE;AACrC;;;;;;;;;GASG;GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,GAC7B,OAAO,CAAC,mBAAmB,CAAC,CA+C9B"}
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readRoundRecords = readRoundRecords;
4
+ const core_1 = require("@looply/core");
5
+ /**
6
+ * `(runId, round)` — rounds are numbered per run, so neither half is a key alone.
7
+ *
8
+ * `#` because a run id is `run_` plus base32 and a round is a number, so neither
9
+ * can contain it and no two distinct pairs can collide on the joined string.
10
+ */
11
+ function roundKey(runId, round) {
12
+ return `${runId}#${round}`;
13
+ }
14
+ async function readRoundRecords(stateDir, fs) {
15
+ let text;
16
+ try {
17
+ text = await fs.readFile(`${stateDir}/events.jsonl`);
18
+ }
19
+ catch (e) {
20
+ return { ok: false, because: `the run ledger could not be read (${e.message})` };
21
+ }
22
+ // Genuinely absent, or genuinely empty. Nothing has happened here yet, which
23
+ // IS an answer: no round delivered anything.
24
+ if (text === null || text.length === 0)
25
+ return { ok: true, rounds: [] };
26
+ const { events } = (0, core_1.parseLines)(text);
27
+ const gates = new Map();
28
+ const ended = new Map();
29
+ for (const e of events) {
30
+ if (e.kind === 'gate.result') {
31
+ const d = e.data;
32
+ gates.set(roundKey(e.runId, d.round), { verdict: d.verdict, steps: d.steps });
33
+ continue;
34
+ }
35
+ if (e.kind === 'round.ended') {
36
+ const d = e.data;
37
+ const record = {
38
+ runId: e.runId,
39
+ round: d.round,
40
+ itemId: d.itemId,
41
+ outcome: d.outcome,
42
+ };
43
+ if (d.sha !== undefined)
44
+ record.sha = d.sha;
45
+ // Last write wins on a duplicate `(runId, round)`, which the ledger's own
46
+ // contract says cannot happen — but a duplicated DELIVERY can, and taking
47
+ // the later copy of an identical event is the same answer either way.
48
+ ended.set(roundKey(e.runId, d.round), record);
49
+ }
50
+ }
51
+ // Joined after the walk rather than during it, because `gate.result` and
52
+ // `round.ended` are appended in that order for a committing round but the
53
+ // reader must not depend on having seen one before the other.
54
+ const out = [];
55
+ for (const [key, record] of ended) {
56
+ const gate = gates.get(key);
57
+ out.push(gate === undefined ? record : { ...record, gate });
58
+ }
59
+ return { ok: true, rounds: out };
60
+ }
61
+ //# sourceMappingURL=round-records.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"round-records.js","sourceRoot":"","sources":["../src/round-records.ts"],"names":[],"mappings":";;AAqEA,4CAkDC;AAvHD,uCAAoG;AA6CpG;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,KAAa,EAAE,KAAa;IAC5C,OAAO,GAAG,KAAK,IAAI,KAAK,EAAE,CAAC;AAC7B,CAAC;AAgBM,KAAK,UAAU,gBAAgB,CACpC,QAAgB,EAChB,EAA8B;IAE9B,IAAI,IAAmB,CAAC;IACxB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,GAAG,QAAQ,eAAe,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,qCAAsC,CAAW,CAAC,OAAO,GAAG,EAAE,CAAC;IAC9F,CAAC;IACD,6EAA6E;IAC7E,6CAA6C;IAC7C,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAExE,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,iBAAU,EAAC,IAAI,CAAC,CAAC;IAEpC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA6D,CAAC;IACnF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAuB,CAAC;IAE7C,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACjB,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YAC9E,SAAS;QACX,CAAC;QACD,IAAI,CAAC,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACjB,MAAM,MAAM,GAAgB;gBAC1B,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC;YACF,IAAI,CAAC,CAAC,GAAG,KAAK,SAAS;gBAAE,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;YAC5C,0EAA0E;YAC1E,0EAA0E;YAC1E,sEAAsE;YACtE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,yEAAyE;IACzE,0EAA0E;IAC1E,8DAA8D;IAC9D,MAAM,GAAG,GAAkB,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;AACnC,CAAC"}